Kivy,RecycleView添加和删除行

时间:2019-05-26 11:11:37

标签: python kivy

我试图更好地了解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 :(得分:0)

您编辑回收视图的数据列表。数据将按照该列表中的顺序进行排序。
因此,这是添加删除功能的示例:

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

这是一个有关如何通过某些键对数据列表进行排序的示例。在这种情况下是ind。

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