Kivy Label.text Property doesn't update on the UI
Question: 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?


Answer: 
    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.

