Kivy ObjectProperty更新标签文本 [英] Kivy ObjectProperty to update label text

查看:112
本文介绍了Kivy ObjectProperty更新标签文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个kivy用户界面,以显示由我作为标准python对象编写的数据模型生成的值.本质上,我希望用户能够按下一个按钮,这将更改基础数据模型,并且此更改的结果将自动更新和显示.据我了解,这可以使用kivy属性(在本例中为ObjectProperty)实现.

I am working on creating a kivy user interface to display the values generated by a data model I've written as a standard python object. In essence, I would like the user to be able to press a button, which would change the underlying data model and the results of this change would be automatically updated and displayed. It is my understanding that this can be implemented using kivy properties (in this case, ObjectProperty).

这是一些示例代码:

import kivy
kivy.require('1.7.0')

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.lang import Builder

Builder.load_string("""
<RootWidget>:
    cols: 2
    Label:
        text: "Attribute a:"
    Label:
        text: root.data_model.a
    Label:
        text: "Attribute b:"
    Label:
        text: root.data_model.b
    Label:
        text: "Attribute c:"
    Label:
        text: root.data_model.c
    Button:
        text: "Make data_model.a longer"
        on_press: root.button_press()
    Button:
        text: "Make data_model.b shorter"
        on_press: root.button_press2()
""")


class DataModel(object):
    def __init__(self):
        self.a = 'This is a'
        self.b ='This is b'

    @property
    def c(self):
        return self.a + ' and ' + self.b

class RootWidget(GridLayout):
    data_model = ObjectProperty(DataModel())

    def button_press(self, *args):
        self.data_model.a = 'This is a and it is really long now'
        print self.data_model.c

    def button_press2(self, *args):
        self.data_model.b = 'B'
        print self.data_model.c

class TestApp(App):
    def build(self):
        return RootWidget()

app = TestApp()
app.run()

期望的结果是,当用户按下任一按钮时,标签将自动更新以显示新属性.从打印语句可以看出,data_model正在正确更新.但是,所有标签都没有更新.有人可以弄清楚该怎么做吗?

The desired result is for when user presses either button, the labels would automatically update to show the new properties. As can be seen by the print statements, the data_model is getting updated correctly. However, none of the labels are updating. Can someone clarify how to do this?

推荐答案

但是,所有标签都没有更新.有人可以弄清楚该怎么做吗?

However, none of the labels are updating. Can someone clarify how to do this?

您引用的属性必须是Kivy属性,但是您引用的abc都只是python属性,因此Kivy无法绑定到它们的更改.

The attributes you reference need to be Kivy properties, but the a, b and c you reference are all just python attributes so Kivy has no way to bind to their changes.

要使用属性,您需要从EventDispatcher继承对象(Kivy小部件会自动执行此操作,这就是其属性起作用的原因).

To work with properties you need your object to inherit from EventDispatcher (Kivy widgets do this automatically, which is why their properties work).

from kivy.event import EventDispatcher

class DataModel(EventDispatcher):
    a = StringProperty('')
    b = StringProperty('')
    c = StringProperty('')

    def __init__(self, *args, **kwargs):
        super(DataModel, self).__init__(*args, **kwargs)
        self.a = 'This is a'
        self.b ='This is b'
        self.bind(a=self.set_c)
        self.bind(b=self.set_c)

    def set_c(self, instance, value):
        self.c = self.a + ' and ' + self.b        

请注意,这不是 获得您想要的c行为的唯一方法(甚至不一定是最佳方法).您可以用kv语言创建绑定(我通常会那样做),也可以查看Kivy的AliasProperty,以获取更类似于您的原始定义的内容.

Note that this is not the only way (or even necessarily the best way) to get the behaviour you wanted for c. You could create the binding in kv language (I'd usually do it that way) or you can look at Kivy's AliasProperty for something more like your original definition.

当然,您也可以在声明属性时设置a和b的值.

Of course you could also set the values of a and b when the properties are declared.

这篇关于Kivy ObjectProperty更新标签文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆