考虑以下代码。我想在前缀更改时更新多个小部件实例。由于所有实例都是相同的,因此在类级别仅存储/更新一次似乎很有效(这样当实例没有自己的 self.prefix 时,它将自动引用类级别前缀属性)
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import StringProperty
import random
kivy_lang = '''
<MainWidget>:
Button:
id: my_button
text: 'increase indice'
<MyLabel>:
on_prefix: self.text = self.prefix +':'+ self.indice
on_indice: self.text = self.prefix +':'+ self.indice
'''
class MyLabel(Label):
prefix = StringProperty('1')
indice = StringProperty('0')
pass
class MainWidget(BoxLayout):
def __init__(self, **kwargs):
super(MainWidget, self).__init__(**kwargs)
self.my_label1 = MyLabel()
self.my_label2 = MyLabel()
self.add_widget(self.my_label1)
self.add_widget(self.my_label2)
self.ids.my_button.bind(on_press=self.my_method)
def my_method(self,*args,**kwargs):
MyLabel.prefix = str(random.randint(0,9))
self.my_label1.indice = str(int(self.my_label1.indice) + 1)
# my_label2 would also be updated if its 'indice' got changed as below
# self.my_label2.indice = str(int(self.my_label2.indice) + 2)
class MyApp(App):
def build(self):
Builder.load_string(kivy_lang)
return MainWidget()
if __name__ == '__main__':
MyApp().run()
从 python 方面来看,这似乎是正确的,从 Kivy 方面来看,kivy 似乎在识别前缀何时更改时遇到问题(my_label1 只更新,因为 indice 也更新了,on_indice 被触发)。
有没有办法让“类级别属性”前缀更改以触发on_prefix?
最佳答案
我认为这不可能直接实现,但您可以使用 AliasProperty
来模仿该功能另一个属性存储在 App
上。只要MyLabel
的实例没有改变prefix
,为 App
设置的值已使用(并自动更新)。一次prefix
在实例上设置,_my_prefix
不是None
,并将用于检索 prefix
的值.
更改 <MyLabel>
规则为
<MyLabel>:
_prefix: app.prefix
text: self.prefix +':'+ self.indice
并将Python代码更改为
class MyLabel(Label):
indice = StringProperty('0')
_prefix = StringProperty('')
_my_prefix = StringProperty(None)
def get_prefix(self):
if self._my_prefix is None:
return self._prefix
else:
return self._my_prefix
def set_prefix(self, value):
self._my_prefix = value
prefix = AliasProperty(get_prefix, set_prefix, bind=('_prefix', '_my_prefix'))
[...]
def my_method(self,*args,**kwargs):
App.get_running_app().prefix = str(random.randint(0,9))
self.my_label1.indice = str(int(self.my_label1.indice) + 1)
if int(self.my_label1.indice) == 2:
self.my_label2.prefix = 'changed'
[...]
class MyApp(App):
prefix = StringProperty('1')
关于python - Kivy:是否可以用类级别(而不是实例)属性触发事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36436372/