Kivy Label.text属性不会在用户界面上更新 [英] Kivy Label.text Property doesn't update on the UI

查看:430
本文介绍了Kivy Label.text属性不会在用户界面上更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对标签的更新的text属性有一个问题,该问题无法在UI上正确显示.我检查了text属性,可以验证它是否已设置为新值,但在呈现标签时未显示该值.

I have an issue with the updated text property of a label not displaying correctly on my UI. I check the text property and can verify that it is being set to the new value but that value isn't being shown when the label is rendered.

标签在另一个屏幕上,我正在使用ScreenManager切换到该屏幕.屏幕的子窗口小部件和树是在单独的.kv文件中构造的(在示例中,我使用过load_string()Builder方法,但结果是相同的)

The Label is on a different Screen which I am switching to using a ScreenManager. The Sub Widgets and tree of the screen are constructed in separate .kv files (I have used the load_string() Builder method in the example but the outcome is the same)

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

Here is a simplified example of what is going on:

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中调用该方法,但无济于事. 我想念的是什么?

I have tried various things such as changing how i reference the label widget in python, asking the canvas to update or creating a 'screen2()' object to call the method from in the screen1 but to no avail. What is it that I'm missing?

推荐答案

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

这行代码不符合您的想法-实际上,它会犯多个错误,您是否熟悉python类的工作原理?

This line doesn't do what you think - actually, it makes multiple mistakes, are you familiar with how python classes work?

首先,当您调用方法时,通常希望使用类的实例来完成此操作,例如

First, when you call a method, you generally want to do it with an instance of the class, e.g.

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

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

This will append 10 to this instance of the list.

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

What you've done is not call the update_label method of a class instance, but directly called it with the class definition and a new instance screen2(). Since this didn't crash for you I think it would probably work if you passed in the instance you want to change, but it's not normal and there's no reason to do things this way. The problem is that you changed the text of the new screen2 instance you passed in, but this is a completely different object to the one you're actually displaying in your app, so you see no change.

您需要调用您的应用实际使用的screen2实例的update_label方法.例如,类似以下的内容应该起作用:

You instead need to call the update_label method of the screen2 instance your app actually uses. For instance, something like the following should work:

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

第一行使用screenmanager的get_screen方法检索名称为'screen2'的现有屏幕.第二行使用您的新文本调用其更新标签方法.请注意,您不会传递屏幕实例参数(称为self)-实例方法会自动接收该第一个参数.

The first line uses the get_screen method of the screenmanager to retrieve the existing screen with the name 'screen2'. The second line calls its update label method with your new text. Note that you do not pass in the screen instance argument (called self) - an instance method automatically receives this first argument.

您还应该大写您的类名,这既是因为它是python约定(这显然不是强制性的,但遵循通用社区样式准则有很多话要说),并且因为kv语言使用这种大写字母来标识小部件,所以如果不这样做,以后可能会遇到问题.

You should also capitalise your class names, both because it's a python convention (this is obviously not compulsory but there's a lot to be said for following the general community style guidelines), and because kv language uses this capitalisation to identify widgets so you might hit problems later if you don't do it.

这篇关于Kivy Label.text属性不会在用户界面上更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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