可选择的列表(可回收)在选择项目时未正确更新

问题描述 投票:-1回答:1

我正在使用可回收的视图来显示可供选择的项目列表。该列表有些动态,因此我会定期对其进行更新。

它通常可以正常工作,但是,如果在更新列表时选择了某个项目,则所选条目似乎变得孤立了,因此,当我们尝试访问其父项时,该应用程序会崩溃,不存在。] >

下面的代码和输出-当什么都没有选择时,您可以随意点击'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'

知道我在做什么错吗?

我正在使用可回收的视图来显示可供选择的项目列表。该列表有些动态,因此我会定期对其进行更新。大多数情况下都可以,但是如果在...

python kivy kivy-language
1个回答
0
投票

[通过讨论与奇异的用户群找到了答案-不幸的是,这篇文章被否决了,后来被忽略了,所以在SO上没有任何吸引力。

© www.soinside.com 2019 - 2024. All rights reserved.