为什么我的 RecycleView Kivy table 没有刷新?

Why is my RecycleView Kivy table not refreshing?

因此,每当我尝试从回收视图中删除现有项目时,我都必须关闭应用程序并再次打开它才能看到删除。我想让它自动刷新回收视图并显示删除。

要导航应用程序,首先转到 记录新自动化,然后在顶部键入名称并按 保存右下角。然后您必须关闭应用程序并在按 打开旧自动化 之前重新打开它。然后单击您创建的项目并按底部的 Delete。如您所见,数据已删除,但视觉对象没有更新。

kek.py

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import BooleanProperty
from kivy.properties import NumericProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.storage.jsonstore import JsonStore

store = JsonStore('automations.json')

class CustomScreen(Screen):
    hue = NumericProperty(0)


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)

    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. '''
        global selected
        self.selected = is_selected
        if is_selected:
            print("selection changed to {0}".format(rv.data[index]))
            selected = '{0}'.format(rv.data[index])[10:-2]
        else:
            print("selection removed for {0}".format(rv.data[index]))


class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'text': str(x)} for x in store]


class RVScreen(Screen):
    def storedelete(self):
        try:
            store.delete(selected)
            refresh_view_attrs(self, rv, index, data)
        except Exception:
            print("Select Something")

class NewAutoScreen(Screen):
    def recordname(self, inputname):
        if inputname:
            try:
                store.put(inputname, )
            except Exception:
                print("error")


class AutrumApp(App):

    def build(self):
        root = ScreenManager()
        root.add_widget(CustomScreen(name='Autrum'))
        root.add_widget(RVScreen(name='RVScreen'))
        root.add_widget(NewAutoScreen(name='NewAutoScreen'))

        return root


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

autrumapp.kv

#:kivy 2.0
<CustomScreen>:
    hue: 4
    canvas:
        Color:
            hsv: self.hue, .5, .3
        Rectangle:
            size: self.size

    Label:
        font_size: 42
        text: root.name

    Button:
        text: 'Record new Automation'
        size_hint: None, None
        pos_hint: {'right': 1}
        size: 200, 75       
        on_release: 
            root.manager.current = "NewAutoScreen"
            root.manager.transition.direction = 'left'
            root.manager.transition.duration = .25
    Button:
        text: 'Open old Automation'
        size_hint: None, None
        pos_hint: {'left': 1}
        size: 200, 75
        on_release: 
            root.manager.current = "RVScreen"
            root.manager.transition.direction = 'right'
            root.manager.transition.duration = .25

<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'
    SelectableRecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        multiselect: True
        touch_multiselect: True

<RVScreen>:
    id: old
    FloatLayout:
        orientation: "vertical"
        RV:
        Button:
            text: 'Back'
            pos_hint: {'right': 1}
            size_hint: .1, .1
            on_release: 
                root.manager.current = "Autrum"
                root.manager.transition.direction = 'left'
                root.manager.transition.duration = .25
        
        Button:
            text: 'Open'
            pos_hint: {'center_x': .05}
            size_hint: .1, .1
        Button:
            text: 'Edit'
            pos_hint: {'center_x': .15}
            size_hint: .1, .1
        Button:
            text: 'Delete'
            pos_hint: {'center_x': .25}
            size_hint: .1, .1
            on_press:
                old.storedelete()
                

<NewAutoScreen>:
    id: recorder
    FloatLayout:
        Button:
            text: 'Back'
            size_hint: .1, .1
            pos_hint: {'left': 1, 'bottom': 1}
            on_release: 
                root.manager.current = "Autrum"
                root.manager.transition.direction = 'right'
                root.manager.transition.duration = .25
        TextInput:
            id: entry
            size_hint: .5, .05
            pos_hint: {'center_x': .5, 'top': 1}
            multiline: False
            text: ""
        Button:
            size_hint: .1, .1
            pos_hint: {'right': 1, 'bottom': 1}
            text: "Save"
            on_press: recorder.recordname(entry.text)
        Button:
            size_hint: .2, .1
            pos_hint: {'center_x': .4, 'bottom': 1}
            text: "Start Recording"
        Button:
            size_hint: .2, .1
            pos_hint: {'center_x': .6, 'bottom': 1}
            text: "Stop Recording"
            

您还必须更新 RecycleViewdata 属性以反映删除。您可以通过首先修改 kv 来提供对 RecycleView 的轻松访问,如下所示:

<RVScreen>:
    rv: rv  # handy reference to the RV
    id: old
    FloatLayout:
        orientation: "vertical"
        RV:
            id: rv  # the id referenced above

并在您的 storedelete() 方法中使用对 RecycleView 的引用:

class RVScreen(Screen):
    def storedelete(self):
        try:
            store.delete(selected)
            self.rv.data = [{'text': str(x)} for x in store]  # Update RecycleView
        except Exception:
            print("Select Something")