【问题标题】:Kivy: is it possible to trigger events with class level (not instance) Properties?Kivy:是否可以使用类级别(而不是实例)属性触发事件?
【发布时间】:2016-07-25 23:38:25
【问题描述】:

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

有没有办法让“类级别属性”prefix 更改以触发 on_prefix

【问题讨论】:

    标签: python properties kivy


    【解决方案1】:

    我认为这不可能直接实现,但您可以使用AliasProperty 和另一个存储在App 上的属性来模仿该功能。只要MyLabel 的实例没有更改prefix,就会使用为App 设置的值(并自动更新)。在实例上设置prefix 后,_my_prefix 就不是None,并将用于检索prefix 的值。

    &lt;MyLabel&gt; 规则更改为

    <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')
    

    【讨论】:

    • 不错,一口气做两件事! (我还想问一下如何在某个时候使用 AliasProperty,因为我没有从文档中完全掌握它):)
    猜你喜欢
    • 2022-11-27
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多