Python : How to add vertical scroll in RecycleView

前端 未结 2 1704
执笔经年
执笔经年 2020-12-06 22:34

I am using Python-2.7 and kivy.
I run test.py then show a menu Test.When i click on it then show list o

相关标签:
2条回答
  • 2020-12-06 22:47

    The trick is to change the viewclass to fit your needs. You had used Button but it looked to me like that was just to try to sync up your two RecycleViews so I used Labels instead. However, since the TwoLabelListItem that I created is just a BoxLayout you can easily manipulate it to exactly fit your needs.

    Once you create the appropriate layout for the viewclass you then just need to make sure that your the data passed to it is correctly applied. Here I apply the data to the two different labels. I also grab the data as your notes indicated you wanted to be able to have something popup for the different line items.

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        self.ids.label1.text = data['text1']
        self.ids.label2.text = data['text2']
        self.data = data
    

    So keeping the data will let you reference it when an element is selected.

        def apply_selection(self, rv, index, is_selected):
            ''' Respond to the selection of items in the view. '''
            self.selected = is_selected
            if self.selected:
                print(self.data)
    

    Adding a scroll bar to the RecycleView is then simply a matter of telling it in kv that you want to use it. If you want to have the user be able to either move the content or the bars just add content to the list. ['bars', 'content']

    RecycleView:        
        scroll_type: ['bars']
        bar_width: 25
        ...
    

    testApp.py

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.properties import BooleanProperty, ListProperty, ObjectProperty, NumericProperty, DictProperty
    
    from kivy.uix.recycleview.views import RecycleDataViewBehavior
    from kivy.uix.button import Button
    from kivy.uix.recyclegridlayout import RecycleGridLayout
    from kivy.uix.behaviors import FocusBehavior
    from kivy.uix.recycleview.layout import LayoutSelectionBehavior
    from kivy.uix.popup import Popup
    from kivy.core.window import Window
    from kivy.clock import Clock
    
    Window.size = (600, 325)
    
    
    class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                      RecycleGridLayout):
        ''' Adds selection and focus behaviour to the view. '''
    
        selected_row = NumericProperty(0)
    
        def get_nodes(self):
            nodes = self.get_selectable_nodes()
            if self.nodes_order_reversed:
                nodes = nodes[::-1]
            if not nodes:
                return None, None
    
            selected = self.selected_nodes
            if not selected:    # nothing selected, select the first
                self.select_node(nodes[0])
                self.selected_row = 0
                return None, None
    
            if len(nodes) == 1:     # the only selectable node is selected already
                return None, None
    
            last = nodes.index(selected[-1])
            self.clear_selection()
            return last, nodes
    
        def select_next(self):
            ''' Select next row '''
            last, nodes = self.get_nodes()
            if not nodes:
                return
    
            if last == len(nodes) - 1:
                self.select_node(nodes[0])
                self.selected_row = nodes[0]
            else:
                self.select_node(nodes[last + 1])
                self.selected_row = nodes[last + 1]
    
        def select_previous(self):
            ''' Select previous row '''
            last, nodes = self.get_nodes()
            if not nodes:
                return
    
            if not last:
                self.select_node(nodes[-1])
                self.selected_row = nodes[-1]
            else:
                self.select_node(nodes[last - 1])
                self.selected_row = nodes[last - 1]
    
        def select_current(self):
            ''' Select current row '''
            last, nodes = self.get_nodes()
            if not nodes:
                return
    
            self.select_node(nodes[self.selected_row])
    
    
    class TwoLabelListItem(RecycleDataViewBehavior, BoxLayout):
        ''' Add selection support to the Label '''
        index = None
        selected = BooleanProperty(False)
        selectable = BooleanProperty(True)
    
        def refresh_view_attrs(self, rv, index, data):
            ''' Catch and handle the view changes '''
            self.index = index
            self.ids.label1.text = data['text1']
            self.ids.label2.text = data['text2']
            self.data = data
    
        def on_touch_down(self, touch):
            ''' Add selection on touch down '''
            if super(TwoLabelListItem, self).on_touch_down(touch):
                return True
            if self.collide_point(*touch.pos) and self.selectable:
                return self.parent.select_with_touch(self.index, touch)
    
        def apply_selection(self, rv, index, is_selected):
            ''' Respond to the selection of items in the view. '''
            self.selected = is_selected
            if self.selected:
                print(self.data)
    
    
    class RV(BoxLayout):
        data_items = ListProperty([])
        row_data = DictProperty({})
        data = ListProperty([])
        col_row_controller = ObjectProperty(None)
    
        def __init__(self, **kwargs):
            super(RV, self).__init__(**kwargs)
            self.get_states()
            Clock.schedule_once(self.set_default_first_row, .0005)
            self._request_keyboard()
    
        def _request_keyboard(self):
            self._keyboard = Window.request_keyboard(
                self._keyboard_closed, self, 'text'
            )
            if self._keyboard.widget:
                # If it exists, this widget is a VKeyboard object which you can use
                # to change the keyboard layout.
                pass
            self._keyboard.bind(on_key_down=self._on_keyboard_down)
    
        def _keyboard_closed(self):
            self._keyboard.unbind(on_key_down=self._on_keyboard_down)
            self._keyboard = None
    
        def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
            if keycode[1] == 'down':    # keycode[274, 'down'] pressed
                # Respond to keyboard down arrow pressed
                self.display_keystrokes(keyboard, keycode, text, modifiers)
                self.col_row_controller.select_next()
    
            elif keycode[1] == 'up':    # keycode[273, 'up] pressed
                # Respond to keyboard up arrow pressed
                self.display_keystrokes(keyboard, keycode, text, modifiers)
                self.col_row_controller.select_previous()
    
            # Keycode is composed of an integer + a string
            # If we hit escape, release the keyboard
            if keycode[1] == 'escape':
                keyboard.release()
    
            # Return True to accept the key. Otherwise, it will be used by
            # the system.
            return True
    
        def display_keystrokes(self, keyboard, keycode, text, modifiers):
            print("\nThe key", keycode, "have been pressed")
            print(" - text is %r" % text)
            print(" - modifiers are %r" % modifiers)
    
        def on_keyboard_select(self):
            ''' Respond to keyboard event to call Popup '''
    
            # setup row data for Popup
            self.row_data = self.data[self.col_row_controller.selected_row]
    
            # call Popup
            self.popup_callback()
    
        def on_mouse_select(self, instance):
            ''' Respond to mouse event to call Popup '''
    
            if (self.col_row_controller.selected_row != instance.index):
                # Mouse clicked on row is not equal to current selected row
                self.col_row_controller.selected_row = instance.index
    
                # Hightlight mouse clicked/selected row
                self.col_row_controller.select_current()
    
            # setup row data for Popup
            self.row_data = self.data[instance.index]
    
            # call Popup
            self.popup_callback()
    
        def popup_callback(self):
    
            # enable keyboard request
            self._request_keyboard()
    
        def set_default_first_row(self, dt):
            ''' Set default first row as selected '''
            self.col_row_controller.select_next()
    
        def update(self):
            self.data = [{'text1': str(x[0]), 'text2': x[1], 'Id': str(x[0]), 'Name': x[1], 'key': 'Id', 'selectable': True}
                              for x in self.data_items]
    
        def get_states(self):
            rows = [(x, 'abc') for x in range(25)]
    
            i = 0
            for row in rows:
                self.data_items.append([row[0], row[1], i])
                i += 1
            print(self.data_items)
            self.update()
    
    
    class MainMenu(BoxLayout):
        states_cities_or_areas = ObjectProperty(None)
        rv = ObjectProperty(None)
    
        def display_states(self):
            self.remove_widgets()
            self.rv = RV()
            self.states_cities_or_areas.add_widget(self.rv)
    
        def remove_widgets(self):
            self.states_cities_or_areas.clear_widgets()
    
    
    class TestApp(App):
        title = "test"
    
        def build(self):
            return MainMenu()
    
    
    if __name__ == '__main__':
        TestApp().run()
    

    test.kv

    #:kivy 1.10.0
    
    <TwoLabelListItem>:
        # Draw a background to indicate selection
        canvas.before:
            Color:
                rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
            Rectangle:
                pos: self.pos
                size: self.size
        Label:
            id: label1
        Label:
            id: label2
    
    
    <RV>:
        col_row_controller: col_row_controller
        RecycleView:
            scroll_type: ['bars']
            bar_width: 25
            size_hint_x: .1
            data: root.data
            viewclass: 'TwoLabelListItem'
            SelectableRecycleGridLayout:
                padding: 0,0,25,0
                id: col_row_controller
                key_selection: 'selectable'
                cols: 1
                default_size: None, dp(26)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
                multiselect: False
                touch_multiselect: True
    
    
    <MenuButton@Button>:
        text_size: self.size
        valign: "middle"
        padding_x: 5
        size : (80,30)
        size_hint : (None, None)
        background_color: 90 , 90, 90, 90
        background_normal: ''
        color: 0, 0.517, 0.705, 1
        border: (0, 10, 0, 0)
    
    
    <MainMenu>:
        states_cities_or_areas: states_cities_or_areas
    
        BoxLayout:
            orientation: 'vertical'
            #spacing : 10
    
            BoxLayout:
                canvas.before:
                    Rectangle:
                        pos: self.pos
                        size: self.size
    
                size_hint_y: 1
    
                MenuButton:
                    id: btn
                    text: 'Test'
                    size : (60,30)
                    on_release: root.display_states()
    
    
            BoxLayout:
                canvas.before:
                    Rectangle:
                        pos: self.pos
                        size: self.size
    
                    Color:
                        rgb: (1,1,1)
    
                Label:
                    size_hint_x: 45
    
            BoxLayout:
                id: states_cities_or_areas
                size_hint_y: 10
    
            Label:
                size_hint_y: 1
    
    0 讨论(0)
  • 2020-12-06 22:52

    Question

    How to set text right align in only customerId column and other column should be left align?

    Solution

    Snippet

    def apply_selection(self, rv, index, is_selected):
        ''' Respond to the selection of items in the view. '''
        self.selected = is_selected
        self.text_size = self.size
        if index == rv.data[index]['range'][0]:
            self.halign = 'right'
        else:
            self.halign = 'left'
    

    Output

    Label - Text grow vertically and wraps at a certain width

    A Label that can grow vertically but wraps the text at a certain width:

    Label:
        size_hint_y: None
        text_size: self.width, None
        height: self.texture_size[1]
    

    To scroll a GridLayout on it’s X-axis/horizontally and Y-axis/vertically, set size_hint property to (None, None).

    ScrollView - ScrollEffect, scroll_type, bar_width, etc.

    By default, the ScrollView allows scrolling along both the X and Y axes. You can explicitly disable scrolling on an axis by setting the do_scroll_x or do_scroll_y properties to False.

    To scroll a GridLayout on it’s Y-axis/vertically, set the child’s width to that of the ScrollView (size_hint_x=1), and set the size_hint_y property to None:

    When scrolling would exceed the bounds of the ScrollView, it uses a ScrollEffect to handle the overscroll.

    scroll_type

    Sets the type of scrolling to use for the content of the scrollview. Available options are: [‘content’], [‘bars’], [‘bars’, ‘content’]

    [‘bars’] Content is scrolled by dragging or swiping the scoll bars.

    Grid Layout

    cols_minimum

    Dict of minimum width for each column. The dictionary keys are the column numbers, e.g. 0, 1, 2…

    cols_minimum is a DictProperty and defaults to {}.

    Snippets

    <RV>:
        row_controller: row_controller
    
        bar_width: 10
        bar_color: 1, 0, 0, 1   # red
        bar_inactive_color: 0, 0, 1, 1   # blue
        effect_cls: "ScrollEffect"
        scroll_type: ['bars']
    
        data: root.rv_data
        viewclass: 'SelectableButton'
    
        SelectableRecycleGridLayout:
            id: row_controller
            key_selection: 'selectable'
            cols: root.total_col_headings
            cols_minimum: root.cols_minimum
            default_size: None, dp(26)
            default_size_hint: 1, None
            size_hint: None, None
            height: self.minimum_height
            width: self.minimum_width
            orientation: 'vertical'
            multiselect: True
            touch_multiselect: True
    

    The following example demonstrates:

    1. Scrolling of the table header on the X-axis.
    2. Support scrolling on the X-axis and Y-axis.
    3. Support scrolling on the Y-axis in the Popup window.
    4. Works for any columns in database table.
    5. Varying column width using GridLayout cols_minimum.
    6. Combined two RecycleView into one as there is no need to have a recycleview just for the ID.
    7. Selectable buttons.

    SQLite Sample Database

    chinook SQLite sample database

    Example

    main.py

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.properties import BooleanProperty, ListProperty, ObjectProperty, NumericProperty, DictProperty
    
    from kivy.uix.recycleview.views import RecycleDataViewBehavior
    from kivy.uix.button import Button
    from kivy.uix.recyclegridlayout import RecycleGridLayout
    from kivy.uix.behaviors import FocusBehavior
    from kivy.uix.recycleview.layout import LayoutSelectionBehavior
    from kivy.uix.popup import Popup
    from kivy.core.window import Window
    from kivy.clock import Clock
    from kivy.uix.scrollview import ScrollView
    from kivy.uix.label import Label
    from kivy.uix.textinput import TextInput
    from kivy.uix.recycleview import RecycleView
    import sqlite3 as lite
    import re
    
    Window.size = (600, 325)
    
    
    class PopupLabelCell(Label):
        pass
    
    
    class EditStatePopup(Popup):
    
        def __init__(self, obj, **kwargs):
            super(EditStatePopup, self).__init__(**kwargs)
            self.populate_content(obj)
    
        def populate_content(self, obj):
            for x in range(len(obj.table_header.col_headings)):
                self.container.add_widget(PopupLabelCell(text=obj.table_header.col_headings[x]))
                textinput = TextInput(text=str(obj.row_data[x]))
                if x == 0:
                    textinput.readonly = True
                self.container.add_widget(textinput)
    
    
    class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                      RecycleGridLayout):
        ''' Adds selection and focus behaviour to the view. '''
    
        selected_row = NumericProperty(0)
        obj = ObjectProperty(None)
    
        def get_nodes(self):
            nodes = self.get_selectable_nodes()
            if self.nodes_order_reversed:
                nodes = nodes[::-1]
            if not nodes:
                return None, None
    
            selected = self.selected_nodes
            if not selected:    # nothing selected, select the first
                self.selected_row = 0
                self.select_row(nodes)
                return None, None
    
            if len(nodes) == 1:     # the only selectable node is selected already
                return None, None
    
            last = nodes.index(selected[-1])
            self.clear_selection()
            return last, nodes
    
        def select_next(self, obj):
            ''' Select next row '''
            self.obj = obj
            last, nodes = self.get_nodes()
            if not nodes:
                return
    
            if last == len(nodes) - 1:
                self.selected_row = nodes[0]
            else:
                self.selected_row = nodes[last + 1]
    
            self.selected_row += self.obj.total_col_headings
            self.select_row(nodes)
    
        def select_previous(self, obj):
            ''' Select previous row '''
            self.obj = obj
            last, nodes = self.get_nodes()
            if not nodes:
                return
    
            if not last:
                self.selected_row = nodes[-1]
            else:
                self.selected_row = nodes[last - 1]
    
            self.selected_row -= self.obj.total_col_headings
            self.select_row(nodes)
    
        def select_current(self, obj):
            ''' Select current row '''
            self.obj = obj
            last, nodes = self.get_nodes()
            if not nodes:
                return
    
            self.select_row(nodes)
    
        def select_row(self, nodes):
            col = self.obj.rv_data[self.selected_row]['range']
            for x in range(col[0], col[1] + 1):
                self.select_node(nodes[x])
    
    
    class SelectableButton(RecycleDataViewBehavior, Button):
        ''' Add selection support to the Button '''
        index = None
        selected = BooleanProperty(False)
        selectable = BooleanProperty(True)
    
        def refresh_view_attrs(self, rv, index, data):
            ''' Catch and handle the view changes '''
    
            self.index = index
            return super(SelectableButton, self).refresh_view_attrs(rv, index, data)
    
        def on_touch_down(self, touch):
            ''' Add selection on touch down '''
            if super(SelectableButton, self).on_touch_down(touch):
                return True
            if self.collide_point(*touch.pos) and self.selectable:
                print("on_touch_down: self=", self)
                return self.parent.select_with_touch(self.index, touch)
    
        def apply_selection(self, rv, index, is_selected):
            ''' Respond to the selection of items in the view. '''
            self.selected = is_selected
            self.text_size = self.size
            if index == rv.data[index]['range'][0]:
                self.halign = 'right'
            else:
                self.halign = 'left'
    
    
    class HeaderCell(Label):
        pass
    
    
    class TableHeader(ScrollView):
        """Fixed table header that scrolls x with the data table"""
        header = ObjectProperty(None)
        col_headings = ListProperty([])
        cols_minimum = DictProperty({})
    
        def __init__(self, **kwargs):
            super(TableHeader, self).__init__(**kwargs)
            self.db = lite.connect('chinook.db')
            self.db_cursor = self.db.cursor()
            self.get_table_column_headings()
    
        def get_table_column_headings(self):
            self.db_cursor.execute("PRAGMA table_info(customers)")
            col_headings = self.db_cursor.fetchall()
    
            for col_heading in col_headings:
                data_type = col_heading[2]
                if data_type == "INTEGER":
                    self.cols_minimum[col_heading[0]] = 100
                else:
                    self.cols_minimum[col_heading[0]] = int(re.findall(r'\d+', data_type).pop(0)) * 5
                self.col_headings.append(col_heading[1])
                self.header.add_widget(HeaderCell(text=col_heading[1], width=self.cols_minimum[col_heading[0]]))
    
    
    class RV(RecycleView):
        row_data = ()
        rv_data = ListProperty([])
        row_controller = ObjectProperty(None)
        total_col_headings = NumericProperty(0)
        cols_minimum = DictProperty({})
        table_header = ObjectProperty(None)
    
        def __init__(self, table_header, **kwargs):
            super(RV, self).__init__(**kwargs)
            self.table_header = table_header
            self.total_col_headings = len(table_header.col_headings)
            self.cols_minimum = table_header.cols_minimum
            self.database_connection()
            self.get_states()
            Clock.schedule_once(self.set_default_first_row, .0005)
            self._request_keyboard()
    
        def database_connection(self):
            self.db = lite.connect('chinook.db')
            self.db_cursor = self.db.cursor()
    
        def _request_keyboard(self):
            self._keyboard = Window.request_keyboard(
                self._keyboard_closed, self, 'text'
            )
            if self._keyboard.widget:
                # If it exists, this widget is a VKeyboard object which you can use
                # to change the keyboard layout.
                pass
            self._keyboard.bind(on_key_down=self._on_keyboard_down)
    
        def _keyboard_closed(self):
            self._keyboard.unbind(on_key_down=self._on_keyboard_down)
            self._keyboard = None
    
        def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
            if keycode[1] == 'down':    # keycode[274, 'down'] pressed
                # Respond to keyboard down arrow pressed
                self.display_keystrokes(keyboard, keycode, text, modifiers)
                self.row_controller.select_next(self)
    
            elif keycode[1] == 'up':    # keycode[273, 'up] pressed
                # Respond to keyboard up arrow pressed
                self.display_keystrokes(keyboard, keycode, text, modifiers)
                self.row_controller.select_previous(self)
    
            elif len(modifiers) > 0 and modifiers[0] == 'ctrl' and text == 'e':     # ctrl + e pressed
                # Respond to keyboard ctrl + e pressed, and call Popup
                self.display_keystrokes(keyboard, keycode, text, modifiers)
                self.on_keyboard_select()
    
            # Keycode is composed of an integer + a string
            # If we hit escape, release the keyboard
            if keycode[1] == 'escape':
                keyboard.release()
    
            # Return True to accept the key. Otherwise, it will be used by
            # the system.
            return True
    
        def display_keystrokes(self, keyboard, keycode, text, modifiers):
            print("\nThe key", keycode, "have been pressed")
            print(" - text is %r" % text)
            print(" - modifiers are %r" % modifiers)
    
        def on_keyboard_select(self):
            ''' Respond to keyboard event to call Popup '''
    
            # setup row data for Popup
            self.setup_row_data(self.rv_data[self.row_controller.selected_row]['Index'])
    
            # call Popup
            self.popup_callback()
    
        def on_mouse_select(self, instance):
            ''' Respond to mouse event to call Popup '''
    
            if self.row_controller.selected_row != instance.index:
                # Mouse clicked on row is not equal to current selected row
                self.row_controller.selected_row = instance.index
    
                # Hightlight mouse clicked/selected row
                self.row_controller.select_current(self)
    
            # setup row data for Popup
            self.setup_row_data(self.rv_data[instance.index]['Index'])
    
            # call Popup
            self.popup_callback()
    
            # enable keyboard request
            self._request_keyboard()
    
        def setup_row_data(self, value):
            self.db_cursor.execute("SELECT * FROM customers WHERE CustomerId=?", value)
            self.row_data = self.db_cursor.fetchone()
    
        def popup_callback(self):
            ''' Instantiate and Open Popup '''
            popup = EditStatePopup(self)
            popup.open()
    
        def set_default_first_row(self, dt):
            ''' Set default first row as selected '''
            self.row_controller.select_next(self)
    
        def get_states(self):
            self.db_cursor.execute("SELECT * FROM customers ORDER BY CustomerId ASC")
            rows = self.db_cursor.fetchall()
    
            data = []
            low = 0
            high = self.total_col_headings - 1
            for row in rows:
                for i in range(len(row)):
                    data.append([row[i], row[0], [low, high]])
                low += self.total_col_headings
                high += self.total_col_headings
    
            self.rv_data = [{'text': str(x[0]), 'Index': str(x[1]), 'range': x[2], 'selectable': True} for x in data]
    
    
    class Table(BoxLayout):
        rv = ObjectProperty(None)
    
        def __init__(self, **kwargs):
            super(Table, self).__init__(**kwargs)
            self.orientation = "vertical"
            self.header = TableHeader()
            self.rv = RV(self.header)
    
            self.rv.fbind('scroll_x', self.scroll_with_header)
    
            self.add_widget(self.header)
            self.add_widget(self.rv)
    
        def scroll_with_header(self, obj, value):
            self.header.scroll_x = value
    
    
    class MainMenu(BoxLayout):
        states_cities_or_areas = ObjectProperty(None)
        table = ObjectProperty(None)
    
        def display_states(self):
            self.remove_widgets()
            self.table = Table()
            self.states_cities_or_areas.add_widget(self.table)
    
        def remove_widgets(self):
            self.states_cities_or_areas.clear_widgets()
    
    
    class TestApp(App):
        title = "test"
    
        def build(self):
            return MainMenu()
    
    
    if __name__ == '__main__':
        TestApp().run()
    

    test.kv

    #:kivy 1.10.0
    
    <PopupLabelCell>
        size_hint: (None, None)
        height: 30
        text_size: self.size
        halign: "left"
        valign: "middle"
    
    <EditStatePopup>:
        container: container
        size_hint: None, None
        size: 400, 275
        title_size: 20
        # title_font: "Verdana"
        auto_dismiss: False
    
        BoxLayout:
            orientation: "vertical"
            ScrollView:
                bar_width: 10
                bar_color: 1, 0, 0, 1   # red
                bar_inactive_color: 0, 0, 1, 1   # blue
                effect_cls: "ScrollEffect"
                scroll_type: ['bars']
                size_hint: (1, None)
    
                GridLayout:
                    id: container
                    cols: 2
                    row_default_height: 30
                    cols_minimum: {0: 100, 1: 300}
                    # spacing: 10, 10
                    # padding: 20, 20
                    size_hint: (None, None)
                    height: self.minimum_height
    
            BoxLayout:
                Button:
                    size_hint: 1, 0.2
                    text: "Save Changes"
                    on_release:
                        root.dismiss()
                Button:
                    size_hint: 1, 0.2
                    text: "Cancel Changes"
                    on_release: root.dismiss()
    
    <SelectableButton>:
        canvas.before:
            Color:
                rgba: (0, 0.517, 0.705, 1) if self.selected else (0, 0.517, 0.705, 1)
            Rectangle:
                pos: self.pos
                size: self.size
        background_color: [1, 0, 0, 1]  if self.selected else [1, 1, 1, 1]  # dark red else dark grey
        on_press: app.root.table.rv.on_mouse_select(self)
    
    <HeaderCell>
        size_hint: (None, None)
        height: 25
        text_size: self.size
        halign: "left"
        valign: "middle"
        background_disabled_normal: ''
        disabled_color: (1, 1, 1, 1)
    
        canvas.before:
            Color:
                rgba: 1, 0.502, 0, 1
            Rectangle:
                pos: self.pos
                size: self.size
    
    <TableHeader>:
        header: header
        bar_width: 0
        do_scroll: False
        size_hint: (1, None)
        height: 25
        effect_cls: "ScrollEffect"
    
        GridLayout:
            id: header
            rows: 1
            cols_minimum: root.cols_minimum
            size_hint: (None, None)
            width: self.minimum_width
            height: self.minimum_height
    
    <RV>:
        row_controller: row_controller
    
        bar_width: 10
        bar_color: 1, 0, 0, 1   # red
        bar_inactive_color: 0, 0, 1, 1   # blue
        effect_cls: "ScrollEffect"
        scroll_type: ['bars']
    
        data: root.rv_data
        viewclass: 'SelectableButton'
    
        SelectableRecycleGridLayout:
            id: row_controller
            key_selection: 'selectable'
            cols: root.total_col_headings
            cols_minimum: root.cols_minimum
            default_size: None, dp(26)
            default_size_hint: 1, None
            size_hint: None, None
            height: self.minimum_height
            width: self.minimum_width
            orientation: 'vertical'
            multiselect: True
            touch_multiselect: True
    
    
    <MenuButton@Button>:
        text_size: self.size
        valign: "middle"
        padding_x: 5
        size : (80,30)
        size_hint : (None, None)
        background_color: 90 , 90, 90, 90
        background_normal: ''
        color: 0, 0.517, 0.705, 1
        border: (0, 10, 0, 0)
    
    
    <MainMenu>:
        states_cities_or_areas: states_cities_or_areas
    
        BoxLayout:
            orientation: 'vertical'
    
            BoxLayout:
                canvas.before:
                    Rectangle:
                        pos: self.pos
                        size: self.size
    
                size_hint_y: 1
    
                MenuButton:
                    id: btn
                    text: 'Test'
                    size : (60,30)
                    on_release: root.display_states()
    
    
            BoxLayout:
                canvas.before:
                    Rectangle:
                        pos: self.pos
                        size: self.size
    
                    Color:
                        rgb: (1,1,1)
    
                Label:
                    size_hint_x: 45
    
            BoxLayout:
                id: states_cities_or_areas
                size_hint_y: 10
    
            Label:
                size_hint_y: 1
    

    Output

    0 讨论(0)
提交回复
热议问题