Kivy, RecycleView с выбираемыми метками и несколькими столбцами - PullRequest
0 голосов
/ 23 мая 2019

С последних нескольких недель я очень много работал над созданием графического интерфейса для Raspberry Pi3.Теперь эта проблема, над которой я застрял, заключается в том, что у меня есть таблица с четырьмя столбцами, для которых количество строк зависит от данных из БД.И я использую структуру RecycleView.

Ниже приведен фактический снимок экрана (у меня, кажется, нет привилегии вставлять изображения в данный момент) проекта, над которым я работаю.Упомянутая таблица хорошо показывает 3 строки, извлеченные из базы данных.Пока все хорошо.

Screenshot 1

Но теперь мне нужно сделать эти строки выбираемыми, и я действительно борюсь с этим.Я реализовал это с SelectableRecycleBoxLayout и SelectableRecycleGridLayout, но мои данные больше не отображаются в столбцах, и это вывод, который я получаю.

Screenshot 2

Ниже приведены основные сегменты кода, с помощью которых я получил результаты, как показано в Screnshot 1. Пожалуйста, дайте указания, как правильно реализовать выбираемый вид.Спасибо.

main.py

class RecycleViewRow(BoxLayout):

    slno    = StringProperty('')
    typ     = StringProperty('')
    cont    = StringProperty('')
    dur     = StringProperty('')

#-----------------------------------------------------------------------
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):

    ''' 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)

    slno    = StringProperty('')
    typ     = StringProperty('')
    cont    = StringProperty('')
    dur     = StringProperty('')

    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:
            pass #print("selection changed to {0}".format(rv.data[index]))
        else:
            pass #print("selection removed for {0}".format(rv.data[index]))
#-----------------------------------------------------------------------
class MainScreen(RecycleView):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)
        #fetch data from the database
        app_ref = App.get_running_app()
        ads = app_ref.fetchAds() #function reads everything from db
        rows = len(ads)
        self.data = [{'slno': str(x+1),'typ': str(ads[x][1]),'cont': str(ads[x][2]),'dur': str(ads[x][3])} for x in range(rows)]

dash.kv

<SelectableLabel>:
    canvas.before:
        Color:
            rgba: (0, 0.517, 0.705, 1) if self.selected else (0.4,0.4, 0.4, 1)
        Rectangle:
            pos: self.pos
            size: self.size
    #on_press:

    RecycleViewRow:

#----------------------------------------------------------------
<RecycleViewRow>:
    orientation: 'horizontal'
    size_hint: 1.0, 1.0

    Label:
        text: root.slno
        size_hint_x : 0.2

    Label:
        text: root.typ
        size_hint_x : 0.4

    Label:
        text: root.cont
        size_hint_x : 1.0

    Label:
        text:  root.dur
        size_hint_x : 0.4
#----------------------------------------------------------------
<MainScreen>:
    viewclass: 'RecycleViewRow'
    RecycleBoxLayout:
        default_size: None, dp(40)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
BoxLayout:
    orientation : 'horizontal'
    size_hint: 1.0,0.10
    canvas.before:
        Color:
            rgba: [0.2,0.2,0.2,1.0]
        Rectangle :
            pos: self.pos
            size: self.size

    Label:
        text: "sl/no"
        size_hint: 0.2,1.0

    Label:
        text: "Type"
        size_hint: 0.4,1.0

    Label:
        text: "Content"
        size_hint: 1.0,1.0

    Label:
        text: "Duration"
        size_hint: 0.4,1.0

BoxLayout:
    orientation : 'vertical'
    size_hint: 1.0,1.0

    MainScreen: # the RecylcleView widget

    Label:
        size_hint: 1.0, 0.10
        text: ""
        canvas.before:
            Color:
                rgba: [0.3,0.3,0.3,1.0]
            Rectangle :
                pos: self.pos
                size: self.size

1 Ответ

0 голосов
/ 23 мая 2019

Вам нужно сделать выбор класса RecycleViewRow.
В Python у вас уже есть класс SelectableLabel. Измените его имя на RecycleViewRow и позвольте ему быть производным от BoxLayout вместо Label. И удалите свой оригинальный RecycleViewRow класс. Вот так:

class RecycleViewRow(RecycleDataViewBehavior, BoxLayout):

Затем в верхней части вашего RecycleViewRow в kv определите свойства строки, чтобы убедиться, что она распознает ключи как свойства строки. И переместите материал, который находится внутри SelectableLabel поверх RecycleViewRow и удалите SelectableLabel.
Так что теперь это будет выглядеть примерно так:

RecycleViewRow:

    slno: ""
    typ: ""
    cont: ""
    dur: ""

    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size
...