我正在使用可回收的视图来显示可供选择的项目列表。该列表有些动态,因此我会定期对其进行更新。
它通常可以正常工作,但是,如果在更新列表时选择了某个项目,则所选条目似乎变得孤立了,因此,当我们尝试访问其父项时,该应用程序会崩溃,不存在。] >
下面的代码和输出-当什么都没有选择时,您可以随意点击'update',但是一旦选择了一个项目并点击update,它就会根据输出爆炸。与可选列表的示例几乎完全相同的代码,因此我有点茫然。
代码:
#!/usr/bin/python import kivy from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.button import Button from kivy.lang import Builder from kivy.uix.recycleview import RecycleView from kivy.uix.recycleview.views import RecycleDataViewBehavior from kivy.uix.label import Label from kivy.properties import BooleanProperty from kivy.uix.recycleboxlayout import RecycleBoxLayout from kivy.uix.behaviors import FocusBehavior from kivy.uix.recycleview.layout import LayoutSelectionBehavior Builder.load_string(''' <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 <SelectableList>: viewclass: 'SelectableLabel' SelectableRecycleBoxLayout: default_size: None, dp(56) default_size_hint: 1, None size_hint_y: None height: self.minimum_height orientation: 'vertical' multiselect: False ''') class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout): # Adds selection and focus behaviour to the view. def uncallable(self): print "It got called." 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. self.selected = is_selected if is_selected: print("selection changed to {0}".format(rv.data[index])) print "Debug self: " + str( self ) print "Debug parent: " + str( self.parent ) self.parent.uncallable() else: print("selection removed for {0}".format(rv.data[index])) class SelectableList(RecycleView): def __init__(self, **kwargs): super(SelectableList, self).__init__(**kwargs) self.currentSelection = None def update(self, data): self.data = data self.refresh_from_data() def getSelected(self): return self.currentSelection pass class repro(App): def build(self): self.selectable=SelectableList() self.updateBtn=Button(text = "Update", on_touch_down = self.update) self.layout=GridLayout(cols=1, rows=2) self.layout.add_widget(self.selectable) self.layout.add_widget(self.updateBtn) self.update(None,None) return self.layout def update(self, obj, data): self.selectable.update( [ { "text": "selectable entry" } ] ) if __name__ == '__main__': repro().run()
输出:
selection removed for {'text': 'selectable entry'} selection removed for {'text': 'selectable entry'} selection removed for {'text': 'selectable entry'} selection removed for {'text': 'selectable entry'} selection removed for {'text': 'selectable entry'} selection removed for {'text': 'selectable entry'} selection removed for {'text': 'selectable entry'} selection changed to {'text': 'selectable entry'} Debug self: <__main__.SelectableLabel object at 0x7f9328e11750> Debug parent: <__main__.SelectableRecycleBoxLayout object at 0x7f9328e316e0> It got called. selection changed to {'text': 'selectable entry'} Debug self: <__main__.SelectableLabel object at 0x7f9328e11750> Debug parent: None [INFO ] [Base ] Leaving application in progress... Traceback (most recent call last): File "repro.py", line 98, in <module> repro().run() File "/home/gareth/.local/lib/python2.7/site-packages/kivy/app.py", line 828, in run runTouchApp() File "/home/gareth/.local/lib/python2.7/site-packages/kivy/base.py", line 504, in runTouchApp EventLoop.window.mainloop() File "/home/gareth/.local/lib/python2.7/site-packages/kivy/core/window/window_sdl2.py", line 663, in mainloop self._mainloop() File "/home/gareth/.local/lib/python2.7/site-packages/kivy/core/window/window_sdl2.py", line 405, in _mainloop EventLoop.idle() File "/home/gareth/.local/lib/python2.7/site-packages/kivy/base.py", line 348, in idle Clock.tick_draw() File "/home/gareth/.local/lib/python2.7/site-packages/kivy/clock.py", line 588, in tick_draw self._process_events_before_frame() File "kivy/_clock.pyx", line 405, in kivy._clock.CyClockBase._process_events_before_frame (/tmp/pip-build-pXL9oI/kivy/kivy/_clock.c:8381) File "kivy/_clock.pyx", line 445, in kivy._clock.CyClockBase._process_events_before_frame (/tmp/pip-build-pXL9oI/kivy/kivy/_clock.c:8255) File "kivy/_clock.pyx", line 443, in kivy._clock.CyClockBase._process_events_before_frame (/tmp/pip-build-pXL9oI/kivy/kivy/_clock.c:8176) File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick (/tmp/pip-build-pXL9oI/kivy/kivy/_clock.c:3490) File "/home/gareth/.local/lib/python2.7/site-packages/kivy/uix/recycleview/__init__.py", line 255, in refresh_views lm.set_visible_views(indices, data, viewport) File "/home/gareth/.local/lib/python2.7/site-packages/kivy/uix/recyclelayout.py", line 250, in set_visible_views refresh_view_layout(index, opt, widget, viewport) File "/home/gareth/.local/lib/python2.7/site-packages/kivy/uix/recycleview/layout.py", line 148, in refresh_view_layout self.apply_selection(index, view, index in self.selected_nodes) File "/home/gareth/.local/lib/python2.7/site-packages/kivy/uix/recycleview/layout.py", line 143, in apply_selection view.apply_selection(self.recycleview, index, is_selected) File "repro.py", line 68, in apply_selection self.parent.uncallable() AttributeError: 'NoneType' object has no attribute 'uncallable'
知道我在做什么错吗?
我正在使用可回收的视图来显示可供选择的项目列表。该列表有些动态,因此我会定期对其进行更新。大多数情况下都可以,但是如果在...
[通过讨论与奇异的用户群找到了答案-不幸的是,这篇文章被否决了,后来被忽略了,所以在SO上没有任何吸引力。