簡體   English   中英

Kivy ObjectProperty更新標簽文本

[英]Kivy ObjectProperty to update label text

我正在創建一個kivy用戶界面來顯示由我編寫為標准python對象的數據模型生成的值。 本質上,我希望用戶能夠按下一個按鈕,這將改變底層數據模型,並且將自動更新和顯示此更改的結果。 我的理解是,這可以使用kivy屬性(在本例中為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()

期望的結果是當用戶按下任一按鈕時,標簽將自動更新以顯示新屬性。 從print語句可以看出,data_model正在正確更新。 但是,沒有標簽正在更新。 有人可以澄清如何做到這一點?

但是,沒有標簽正在更新。 有人可以澄清如何做到這一點?

您引用的屬性需要是Kivy屬性,但是您引用的abc都只是python屬性,因此Kivy無法綁定到它們的更改。

要使用屬性,您需要從EventDispatcher繼承對象(Kivy小部件會自動執行此操作,這就是它們的屬性有效的原因)。

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以獲得更像您原始定義的內容。

當然,您還可以在聲明屬性時設置a和b的值。

這是我的解決方案:

https://gist.github.com/jsexauer/8861079

本質上,我創建了一個包裝數據模型和UI的包裝類。 有一些我不喜歡的東西,也許其他人可以改進:

  • 任何更新底層數據模型的UI函數都必須使用UI_DataModel類提供的“update”裝飾器進行修飾。 不必包含那個裝飾器是理想的,雖然我不確定如何在不顯着修改DataModel類的工作方式的情況下做到這一點(但是這一點的全部意義在於你不必觸及底層數據模型類)
  • 我希望能夠將公共數據模型實例傳遞給UI_DataModel的__init__() ,而不是讓它使用全局變量(因此是硬編碼的)。 我試圖讓它工作,但遇到了一個弱的遞歸地獄。 也許對Python對象模型有更好理解的人可以實現這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM