python - Kivy:是否可以用类级别(而不是实例)属性触发事件?

标签 python properties kivy

考虑以下代码。我想在前缀更改时更新多个小部件实例。由于所有实例都是相同的,因此在类级别仅存储/更新一次似乎很有效(这样当实例没有自己的 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/

相关文章:

python - 在 Python 循环中定义多个字典

python - 通过字符串设置属性

c# - 为什么要在 setter 之前定义 getter(编码约定)

java - 在应用程序启动时参数化 Java 属性文件

kivy - 在 kivy 中居中多行按钮或标签文本?

python - 如何在字符串乘法中添加空格?

python - 如何在 C 模块中使用 python API 访问数组的数组

python - 新项目 : Python 2 or Python 3?

android - 我的 kivy 程序总是在 Android 上旋转屏幕

kivy - 简单的 Kivy 手势(滑动)