防止Kivy Properties发生不必要的事件

时间:2017-12-14 15:28:16

标签: python kivy

我在一个应用程序中使用Kivy,其中有几个小部件用于修改/编辑一组数据(模型)。当在一个小部件中更改某些数据时,需要通知其他内容已更改,以便他们可以更新其视图。 为此,我使用Kivy Properties镜像模型数据,这很好。

然而,第一次设置Kivy属性时,在读取模型数据时,会在UI中生成大量不必要的更新。我希望有一种方法来更新Kivy属性而不生成更新事件。 我查看了文档(https://kivy.org/docs/api-kivy.properties.html)和代码(https://github.com/kivy/kivy/blob/master/kivy/properties.pyx),但我找不到任何要做的事情。

如何解决这个问题? 我做了一个非常简单的示例应用程序,以显示代码的组织方式以及问题发生的位置。

#! /usr/bin/env python

import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListView
from kivy.adapters.listadapter import ListAdapter
from kivy.uix.listview import ListItemButton
from kivy.properties import StringProperty
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

model_data = ["Data1","Data2","Data3"]

class TestApp(App):
    def build(self):
        tl = TestLayout()
        tl.read_data(model_data)
        return tl

class TestLayout(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.test_list = TestList()
        self.test_edit = TestEdit()
        self.add_widget(self.test_list)
        self.add_widget(self.test_edit)

        self.test_list.adapter = ListAdapter(data=[],
                                             cls=ListItemButton,
                                             selection_mode='single')
        self.test_list.adapter.bind(selection=self.select_data)
        self.test_edit.bind(data=self.update_list)

    def read_data(self, data_list):
        self.test_list.init_list(data_list)

    def select_data(self, list_adapter, selection):
        if len(selection) > 0:
            data =  selection[0].text
            self.test_edit.init_data(data)

    def update_list(self, test_edit, data):
        self.test_list.adapter.selection[0].text = data


class TestList(ListView):
    def init_list(self, data_list):
        self.adapter.data = [str(data) for data in data_list]

class TestEdit(BoxLayout):
    data = StringProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = "vertical"
        self.text_input=TextInput()
        self.add_widget(self.text_input)
        btn_update = Button(text="Update data")
        self.add_widget(btn_update)

        btn_update.bind(on_press=self.update_data)

    def init_data(self, data):
        # Setting the data property the first time triggers an unnecessary update.
        # How can this be prevented?
        self.data = data 
        self.text_input.text = data

    def update_data(self, btn):
        self.data = self.text_input.text

if __name__ == "__main__":
    app = TestApp()
    app.run()

正如您在示例代码中看到的那样,只要您在列表视图中选择新项目,就会调度不必要的更新。

我忽略了一些明显的东西吗?或者Kivy不支持这个吗? 谢谢!

0 个答案:

没有答案