Kivy, RecycleView Добавить и удалить строки - PullRequest
0 голосов
/ 26 мая 2019

Я пытаюсь лучше понять, как функционирует RecycleView. Кажется, только практические примеры научат меня. Документы не помогают. Пожалуйста, взгляните на мой текущий экран на картинке ниже.

RV Screenshot

Теперь вот что я пытаюсь достичь.

  1. Добавить / удалить новые строки в / из списка.
  2. Первый столбец sl / no должен поддерживать порядок даже после удаления между ними.
  3. Как добиться функции сортировки? Это происходит путем переноса данных в python, выполнения сортировки и последующего обновления до RV?

Ниже приведены коды .py и .kv.

rv_main.py

import os
os.environ['KIVY_GL_BACKEND'] = 'gl'
import kivy
kivy.require('1.11.0')

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.label import Label

from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.properties import ListProperty, BooleanProperty
from kivy.properties import NumericProperty


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):

    ''' Adds selection and focus behaviour to the view. '''
#-----------------------------------------------------------------------
class RecycleViewRow(RecycleDataViewBehavior, BoxLayout):
    ''' Add selection support to the Label '''

    index = None
    selected = BooleanProperty(False)
    selectable = BooleanProperty(True)

    slno    = StringProperty('')
    typ     = StringProperty('')

    def refresh_view_attrs(self, rv, index, data):
        ''' Catch and handle the view changes '''
        self.index = index
        return super(RecycleViewRow, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        ''' Add selection on touch down '''
        if super(RecycleViewRow, 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
        else:
            pass

    def delete_row(self,rv, index, is_selected):
        if is_selected:
            rv.data.pop(index)
            rv.layout_manager.clear_selection()

#-----------------------------------------------------------------------
class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        #fetch data from the database
        self.data = [{'slno': str(x+1),'typ': 'default'} for x in range(4)]

#-----------------------------------------------------------------------

class DataTable(BoxLayout):

    def addRow(self):
        pass

    def removeRow(self):
        pass

#-----------------------------------------------------------------------

class RvMainApp(App):
    def build(self):
        return DataTable()

if __name__ == '__main__':
    RvMainApp().run()

rvmain.kv

#: kivy 1.11.0

<RecycleViewRow>:
    id: rv
    slno: ""
    typ: ""

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

    orientation: 'horizontal'
    size_hint: 1.0, 1.0

    Label:
        text: root.slno
        size_hint_x : 1.0

    Label:
        text: root.typ
        size_hint_x : 1.0

#----------------------------------------------------------------
<RV>:
    id : rv
    viewclass: 'RecycleViewRow'
    SelectableRecycleBoxLayout:
        default_size: None, dp(40)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'

#----------------------------------------------------------------
<DataTable>:
    orientation : 'vertical'

    Button:

    BoxLayout:
        Button:
        RV:
        Button:

    BoxLayout:
        Button:
            text: "Add"
            on_release: rv.data.append({"slno": "?", "typ": 'default'})

        Button:
            text: "Remove"
            on_release:

1 Ответ

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

Вы редактируете список данных повторного просмотра. Данные будут отсортированы так, как они отсортированы в этом списке.
Вот пример функции добавления и удаления:

from kivy.app import App
from kivy.lang import Builder


KV = '''

<Row@BoxLayout>:
    ind: 1
    Button:
        text: str(root.ind)
    Button:
        text: "default"

BoxLayout:
    ind: 1
    orientation: "vertical"
    Button:
    BoxLayout:
        Button:
        RecycleView:
            id: rv
            data: [{"text":"first","ind":1}]

            viewclass: 'Row'
            RecycleBoxLayout:
                default_size_hint: 1, None
                default_size: None, dp(56)
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
        Button
    BoxLayout:
        Button:
            text: "Add"
            on_release:
                root.ind += 1
                rv.data.append({"ind": root.ind})
        Button:
            text: "Remove"
            on_release:
                root.ind = root.ind - 1 if root.ind > 0 else 0
                if len(rv.data): rv.data.pop(-1)

'''



class Test(App):
    def build(self):
        self.root = Builder.load_string(KV)
        return self.root


Test().run()

А вот пример того, как отсортировать список данных по некоторому ключу. В этом случае инд.

from kivy.app import App
from kivy.lang import Builder

KV = '''
RecycleView:
    viewclass: 'Label'
    data: sorted([{"text":"!", "ind":3},{"text":"world", "ind":2},{"text":"hello", "ind":1}], key=lambda k: k["ind"])
    RecycleBoxLayout:
        id: layout
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
'''

class TestApp(App):
    def build(self):
        return Builder.load_string(KV)

if __name__ == '__main__':
    TestApp().run()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...