为什么我的 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"
您还必须更新 RecycleView
的 data
属性以反映删除。您可以通过首先修改 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")
因此,每当我尝试从回收视图中删除现有项目时,我都必须关闭应用程序并再次打开它才能看到删除。我想让它自动刷新回收视图并显示删除。
要导航应用程序,首先转到 记录新自动化,然后在顶部键入名称并按 保存右下角。然后您必须关闭应用程序并在按 打开旧自动化 之前重新打开它。然后单击您创建的项目并按底部的 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"
您还必须更新 RecycleView
的 data
属性以反映删除。您可以通过首先修改 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")