0

Sorry for this question, but my reputation don't allow a comment to ikolim' s great answer to this question: Python : How to add vertical scroll in RecycleView

In this code is an issue with displaying one row only. I tried, but can't fix it.

to show what I mean:

change code in class RV(RecycleView)

    def get_states(self):
        # self.db_cursor.execute("SELECT * FROM customers ORDER BY CustomerId ASC")
        self.db_cursor.execute("SELECT * FROM Customers WHERE Customers.CustomerId = 1")
        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]
        print('rv_data', self.rv_data)

The RecycleView displays header nodes as expected, but only one node of data. Mouse click on the data node shows row data as wanted.

As I mentioned before before, i tried to spot where code has to be changed for the expeced result.

I hope my description is a little bit clearer now.

Thanks for inquering!

cbrunner
  • 3
  • 4

1 Answers1

0

alas the simple answer is: it is a kivy RecycleGridLayout issue! https://github.com/kivy/kivy/issues/7255

a poor workaround to display a single row's data, is to add dummy data for another row.

the base of code in main.py is a slightly adapted version of PalimPalim's answer to this question: Kivy - python - multiple widgets in recycleview row

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.properties import NumericProperty, ListProperty
    from kivy.uix.recycleview import RecycleView
    from kivy.uix.recycleview.views import RecycleDataViewBehavior
    from kivy.uix.label import Label
    from kivy.properties import BooleanProperty
    from kivy.uix.behaviors import FocusBehavior
    
    from customRecyclegridlayout import CustomRecycleGridLayout
    from Examples.RecycleGridLayout_Palim.customlayout import CustomLayoutSelectionBehavior
    
    Builder.load_string('''
    <SelectableLabel>:
        # 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
    <RV>:
        viewclass: 'SelectableLabel'
        data: root.data
        SelectableRecycleGridLayout:
            id: recycle_grid
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'lr-tb'
            multiselect: True
            touch_multiselect: True
            cols: root.rv_columns
    ''')
    
    
    class SelectableRecycleGridLayout(FocusBehavior, CustomLayoutSelectionBehavior, CustomRecycleGridLayout):
        ''' Adds selection and focus behaviour to the view. '''
    
    
    class SelectableLabel(RecycleDataViewBehavior, Label):
    
        ''' 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
            return super(SelectableLabel, self).refresh_view_attrs(
                rv, index, data)
    
        def on_touch_down(self, touch):
            ''' Add selection on touch down '''
            if super(SelectableLabel, 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 is_selected:
                print("selection changed to {0}".format(rv.data[index]))
            else:
                print("selection removed for {0}".format(rv.data[index]))
    
    
    class RV(RecycleView):
        rv_columns = NumericProperty(3)  # set number of columns in RecycleView
        items = ListProperty()
        data = ListProperty([])
    
        def __init__(self, **kwargs):
            super(RV, self).__init__(**kwargs)
            items_entity_0 = []
            items_entity_1 = [0, "apple", "fox"]
            items_entity_2 = [0, "apple", "fox", 1, "bone", "dog"]
            items_entity_3 = [0, "apple", "fox", 1, "bone", "dog", 2, 'milk', "cat"]
    
            self.data = self._get_formatted_data(self._check_itemsList(items_entity_1))
            self.app_info = App.get_running_app()
    
        def _check_itemsList(self, item_list):
            i_list = item_list
            if self.rv_columns == len(i_list):
                print('single row detected!')
                for element in range(self.rv_columns):
                    i_list.append('dummy')
    
            return i_list
    
        @staticmethod
        def _get_formatted_data(item_list):
            data = [{'text': str(x)} for x in item_list]
            return data
    
    
    class TestApp(App):
        def build(self):
            return RV()
    
    
    if __name__ == '__main__':
        TestApp().run()
cbrunner
  • 3
  • 4
  • 1
    Can you summarize where that leaves you? Is this just a known bug? Or is there a workaround? If the latter, can you provide an explanation of the workaround here, so your answer isn't reliant primarily on the link? – Jeremy Caney Nov 03 '21 at 20:23