当根对象改变时更新 Kivy 小部件
Updating Kivy Widgets when Root Object Changes
我有一个对象形式的数据结构,我使用 Kivy 以图形方式表示它。
如果可能的话,我想这样写,当根对象发生变化时,Kivy 中的小部件会反映出变化。到目前为止,我注意到我可以在最初创建小部件时从 KV 语言调用对象,并且我可以让这些小部件修改根对象,但是
应该 "bound" 到根对象变量的小部件不会更新。
我正在寻找一种方法来 "bind" 它们,这样我就不必编写一个 "refresh/reload" 函数来在每次进行更改时循环遍历我的数据对象。
下面是示例代码,展示了到目前为止我是如何设置代码的。
根据我在 kivy api 文档中的理解,使用 ObjectProperty(object, rebind=True) 应该做我想做的事情。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
class DataObject():
def __init__(self, name="foo", data="bar"):
self.name = name
self.data = data
class MainWindow(Screen):
pass
class WindowManager(ScreenManager):
data = DataObject()
data_obj = ObjectProperty(data, rebind=True)
kv = Builder.load_file("my.kv")
class MyMainApp(App):
def build(self):
return kv
if __name__ == '__main__':
MyMainApp().run()
WindowManager:
MainWindow:
<MainWindow>:
name: "Main"
GridLayout:
cols: 1
GridLayout:
cols: 2
Label:
text: root.manager.data_obj.name
Button:
text: "Change Name"
on_release:
root.manager.data_obj.name = "Bar"
print(root.manager.data_obj.name)
按下按钮 "Change Name" 将对象 data_obj.name 从 "foo" 更改为 "bar" 并将其打印到控制台以确认它已更改
我希望标签文本也更改为 "bar"
重新绑定适用于 Properties
, and not for class attributes so your logic fails. One possible solution is that DataObject is an EventDispatcher
and name, data is ObjectProperty
:
from kivy.event import EventDispatcher
class DataObject(EventDispatcher):
name = ObjectProperty("foo")
data = ObjectProperty("bar")
我有一个对象形式的数据结构,我使用 Kivy 以图形方式表示它。
如果可能的话,我想这样写,当根对象发生变化时,Kivy 中的小部件会反映出变化。到目前为止,我注意到我可以在最初创建小部件时从 KV 语言调用对象,并且我可以让这些小部件修改根对象,但是 应该 "bound" 到根对象变量的小部件不会更新。
我正在寻找一种方法来 "bind" 它们,这样我就不必编写一个 "refresh/reload" 函数来在每次进行更改时循环遍历我的数据对象。
下面是示例代码,展示了到目前为止我是如何设置代码的。
根据我在 kivy api 文档中的理解,使用 ObjectProperty(object, rebind=True) 应该做我想做的事情。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
class DataObject():
def __init__(self, name="foo", data="bar"):
self.name = name
self.data = data
class MainWindow(Screen):
pass
class WindowManager(ScreenManager):
data = DataObject()
data_obj = ObjectProperty(data, rebind=True)
kv = Builder.load_file("my.kv")
class MyMainApp(App):
def build(self):
return kv
if __name__ == '__main__':
MyMainApp().run()
WindowManager:
MainWindow:
<MainWindow>:
name: "Main"
GridLayout:
cols: 1
GridLayout:
cols: 2
Label:
text: root.manager.data_obj.name
Button:
text: "Change Name"
on_release:
root.manager.data_obj.name = "Bar"
print(root.manager.data_obj.name)
按下按钮 "Change Name" 将对象 data_obj.name 从 "foo" 更改为 "bar" 并将其打印到控制台以确认它已更改
我希望标签文本也更改为 "bar"
重新绑定适用于 Properties
, and not for class attributes so your logic fails. One possible solution is that DataObject is an EventDispatcher
and name, data is ObjectProperty
:
from kivy.event import EventDispatcher
class DataObject(EventDispatcher):
name = ObjectProperty("foo")
data = ObjectProperty("bar")