Search code examples
pythonkivyscreens

Kivy - Screen Manager - Accessing attribute in other class


Using the Kivy Screen Manager, I create two Screens. Whilst being in screen 1, i want to change a label in screen two. I highlight the problematic area in my code:

my test.ky:

#: import ScreenManager kivy.uix.screenmanager.ScreenManager
#: import Screen kivy.uix.screenmanager.ScreenManager
#: import SettingsScreen screen


ScreenManager:
    MenuScreen:
    SettingsScreen:


<MenuScreen>:
    name: 'MenuScreen'
    BoxLayout:
        Button:
            text: 'Goto nn'
            on_press: 
                root.manager.current = 'SettingsScreen'
                root.change_text()


<SettingsScreen>:
    name: 'SettingsScreen'
    label_id: label_field
    BoxLayout:
        Label:
            id: label_field
            text: "to_be_changed"

and my screen.py

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


class MenuScreen(Screen):
    def change_text(self):
        pass
        # HERE: something like
        # root.SettingsScreen.label_field.text = 'new text'


class SettingsScreen(Screen):
    pass


class TestApp(App):
    pass

TestApp().run()

Any help is greatly appreciated! Thanks, Nico


Solution

  • How about this:

    When you press the button on MenuScreen, it sets an attribute on itself containing the text you want to put in the SettingsScreen Label. Then the MenuScreen is assigned an id value in the kv file, which is used to reference this attribute. Example:

    main.py

    class MenuScreen(Screen):
        text = StringProperty('')
        def change_text(self):
            self.text = "The text you want to set"
            self.manager.current = "SettingsScreen"
    
    class SettingsScreen(Screen):
        label_text = StringProperty('')
    

    kv file

    ScreenManager:
        id: screen_manager
        MenuScreen:
            id: menu_screen
            name: 'MenuScreen'
            manager: screen_manager
        SettingsScreen:
            name: 'SettingsScreen'
            manager: screen_manager
            label_text: menu_screen.text
    
    <MenuScreen>:
        BoxLayout:
            Button:
                text: 'Goto nn'
                on_press:
                    root.change_text()
    
    <SettingsScreen>:
        BoxLayout:
            Label:
                text: root.label_text
    

    As you can see, I set the names and id of the screens under ScreenManager itself in the kv file, as this is what I would usually do to make this work.