Kivy:在排序ListAdapter d时无法更新ListView

2024-07-21 09:48:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在listview中对字典列表进行排序。我要通过改变列表适配器.data. 在

在kv文件中,列表视图上方的微调器按钮选择排序值,并在释放时调用根。啤酒吗这会更改ListAdapter(名为beer_la)数据。打印出啤酒_洛杉矶数据在控制台中,它看起来好像发生了变化,但应用程序的显示顺序没有更新。在

class CellarDoor(BoxLayout):
    def __init__(self, **kwargs):
        self.beer_archive = []
        self.wine_archive = []
        with open(join(FILE_ROOT, 'beer_archive.csv'), 'rb', 1) as beer_csv:
            self.beer_archive = list(csv.DictReader(beer_csv))

        self.beer_la = ListAdapter(data=self.beer_archive, 
                          args_converter=self.beer_formatter,
                          cls=CompositeListItem,         
                          selection_mode='single',
                          allow_empty_selection=True)
        super(CellarDoor, self).__init__(**kwargs)

    def beer_formatter(self, row_index, beer_data):
        return {'text': beer_data['Beer'],
                'size_hint_y': None,
                'height': 50,
                'cls_dicts': [{'cls': ListItemImage,
                               'kwargs': {'size_hint_x': .2,
                                          'size': self.parent.size,
                                          'cellar': 'Beer',
                                          'style': beer_data['Style']}},
                              {'cls': ListItemLabel,
                               'kwargs': {'text': beer_data['Beer']}},
                              {'cls': ListItemButton,
                               'kwargs': {'text': str(beer_data['Stock'])}}]}

    def beer_sort(self, sort, reverse):
        self.beer_la.data = sorted(self.beer_archive,
                                   key=lambda k: k[sort],
                                   reverse=reverse)
        print "new sort = %s" % sort
        print self.beer_la.data

kv文件的相关部分

^{pr2}$

Tags: csvtextself列表datasizedefsort
3条回答

在O'Reilly的“Creating apps in Kivy”一书中,它提出了_trigger_reset_populate()函数:

    def update_data(self):
        self.list_adapter.data = mydata
        self.list_view._trigger_reset_populate()

我希望我能帮你解决这个问题。我发现,如果我在调用CellarDoor的构造函数后添加列表视图(而不是使用Kivy语言),那么sort方法就开始工作了。我的例子是你的简化版,但你描述的行为仍然存在。在

如果取消注释:

#    ListView:
#        adapter: root.beer_la

和评论:

^{pr2}$

然后,排序停止工作,正如你所描述的那样。在

奇怪的是,如果我有一个大列表(假设是100个),那么ListView在对其执行和操作(滚动或选择)和项之后被更新。这意味着适配器的属性没有绑定到更新屏幕。这可能是一个值得向Github中的开发人员报告的问题。我不能更好地解释你,但我希望至少能解决你的问题。您可能还想试试create and add the adapter directly in Kivy Language。在

from kivy.adapters.listadapter import ListAdapter
from kivy.uix.listview import ListView, ListItemButton
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.app import App

Builder.load_string("""
<CellarDoor>:
    ToggleButton:
        text: 'Reverse'
        on_state: root.beer_sort((True if self.state=='down' else False))
#    ListView:
#        adapter: root.beer_la
""")

class CellarDoor(BoxLayout):
    def __init__(self, **kwargs):
        self.beer_archive = ["Item #{0}".format(i) for i in range(10)]
        self.beer_la = ListAdapter(data=self.beer_archive, 
                          cls=ListItemButton,
                          selection_mode='single',
                          allow_empty_selection=True)

        super(CellarDoor, self).__init__(**kwargs)
        self.add_widget(ListView(adapter=self.beer_la))


    def beer_sort(self, reverse):
        self.beer_la.data = sorted(self.beer_archive,
                                   reverse=reverse)
        print self.beer_la.data

class TestApp(App):
    def build(self):
        return CellarDoor()

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

也许这对有同样问题的人有帮助。。。在

当向ListView添加新元素时,我也遇到了类似的问题。 在更新时再次设置data属性(如上所述),实际上对我来说并不可行(kivy1.8.0)。在

在KivyGoogle小组的某个地方,展示了一个使用ListViews.populate()方法的解决方案。在

def update_data(self):
  self.list_adapter.data = mydata
  self.list_view.populate()

此方法的一个问题是.populate()属性在创建ListView之后似乎不存在。因此,在调用该属性之前,必须检查该属性是否存在:

^{pr2}$

这实际上解决了,但不幸的是,列表底部的新项目是可见的,但您无法向下滚动到这些项目。在

在挖掘了ListView的源代码之后,我遇到了.u reset_spopulate()方法,它似乎正是我想要的:

def update_data(self):
  self.list_adapter.data = mydata
  if(hasattr(self.list_view, '_reset_spopulate')):
    self.list_view._reset_spopulate()

底部的新项目被正确添加,滚动也起作用。 别问我这到底是怎么回事,也别指望这在未来的Kivy版本中也能起作用。在

相关问题 更多 >