Kivy Label.text属性不会在UI上更新

时间:2014-06-19 11:17:30

标签: python user-interface text label kivy

我的UI上更新的文本属性无法正确显示。我检查了text属性,并且可以验证它是否被设置为新值,但是在呈现标签时没有显示该值。

标签位于不同的屏幕上,我使用ScreenManager切换到该屏幕。屏幕的子窗口小部件和树是在单独的.kv文件中构建的(我在示例中使用了load_string()Builder方法,但结果是相同的)

以下是正在发生的事情的简化示例:

from kivy.config import Config
Config.set('graphics', 'width', '300')
Config.set('graphics', 'height', '200')
Config.set('graphics', 'resizable', '0')

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder

Builder.load_string("""
<screen1>:
    Button:
        id: button
        text: 'Press me to Update Screen2'
        on_press:
            root.update_screen2()

<screen2>:
    Label:
        id: mainLabel
        text: 'I have not been updated'
""")

class screen1(Screen):

    def __init__(self, **kwargs):
        """
            Set super and store the id of the button
        """
        super(screen1, self).__init__(**kwargs)
        self.button = self.ids.button.__self__
        return

    def update_screen2(self):
        """
            send text 1 and text 2 to the screen2 object 
            for it to set on it's label
        """
        text1 = 'Hi There'
        text2 = 'Does this work'
        screen2.update_label(screen2(),text1, text2)
        return


class screen2(Screen):

    def __init__(self, **kwargs):
        """
            set super ond store the id of the label
        """
        super(screen2, self).__init__(**kwargs)
        self.mainLabel = self.ids.mainLabel.__self__
        return

    def update_label(self, text1, text2):
        """
            using text1 and text2, update the text property of the label
            the output of each print() shows the text property is being updated
            it just doesn't display on the UI
        """
        print(self.mainLabel.text)
        self.mainLabel.text = text1 + '\n\n' + text2
        print(self.mainLabel.text)
        screenManager.current = 'screen2'
        return

screenManager = ScreenManager()


class MainApp(App):
    def build(self):
        #root widget is abox layout
        self.root = BoxLayout()

        #instantiate the screen objects
        self.screen1 = screen1(name='screen1')
        self.screen2 = screen2(name='screen2')

        #add the screens to the screenManager
        screenManager.add_widget(self.screen1)
        screenManager.add_widget(self.screen2)

        #set the current screen
        screenManager.current = 'screen1'

        #add the screenManager to the root widget and return it
        self.root.add_widget(screenManager)
        return self.root


if __name__ == '__main__':
    MainApp().run()

我尝试了各种各样的事情,比如改变我在python中引用标签小部件的方式,要求画布更新或创建一个'screen2()'对象来从screen1中调用方法但是无济于事。 我错过了什么?

1 个答案:

答案 0 :(得分:3)

screen2.update_label(screen2(),text1, text2)

这一行没有按照你的想法行事 - 实际上,它会犯多重错误,你熟悉python类是如何工作的吗?

首先,当你调用一个方法时,你通常想要用一个类的实例来做,例如。

a = [1, 2, 3]
a.append(10)

这会将10附加到列表的实例

您所做的不是调用类实例的update_label方法,而是使用类定义和新实例screen2()直接调用它。由于这并没有让你崩溃,我认为如果你传递了你想改变的实例,它可能会有效,但它不正常,并且没有理由这样做。问题是您更改了传入的新screen2实例的文本,但这与您在应用中实际显示的对象完全不同,因此您看不到任何更改。

您需要调用应用实际使用的screen2实例的update_label方法。例如,类似下面的内容应该有效:

screen2_instance = self.parent.get_screen('screen2')
screen2_instance.update_label(text1, text2)

第一行使用screenmanager的get_screen方法检索名为&#39; screen2&#39;的现有屏幕。第二行使用新文本调用其更新标签方法。请注意,您在屏幕实例参数(称为self)中执行 not 传递 - 实例方法会自动接收此第一个参数。

你也应该把你的班级名称大写,因为它是一个python惯例(这显然不是强制性的,但是遵循一般的社区风格指南还有很多要说的),并且因为kv语言使用这个大小写可以识别小部件,这样如果你不这样做,你可能会遇到问题。