Kivy Label.text Property doesn't update on the UI

走远了吗. 提交于 2019-12-08 08:04:06

问题


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.

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

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?


回答1:


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

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)

This will append 10 to this instance of the list.

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.

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)

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.

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.



来源:https://stackoverflow.com/questions/24305280/kivy-label-text-property-doesnt-update-on-the-ui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!