YangTegap
YangTegap

Reputation: 461

How do you pass a variable between screens in Kivy?

Here is my code:

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


build = f"""
WindowManager:
    ScreenOne:

<ScreenOne>:
    name: 'one'

    BoxLayout:
        orientation: 'horizontal'
        size: root.width, root.height

        Button:
            text: 'Load Screen Two'
            on_release:
                app.root.load_screen_two('Screen Two')
                app.root.current = 'two'


<ScreenTwo>:
    name: 'two'

    BoxLayout:
        orientation: 'horizontal'
        size: root.width, root.height

        Label:
            text: root.text
"""


class ScreenOne(Screen):
    pass


class ScreenTwo(Screen):
    def __init__(self, text, **kw):
        super().__init__(**kw)
        self.text = text


class WindowManager(ScreenManager):
    def load_screen_two(self, text):
        self.add_widget(ScreenTwo(text))


class Application(App):
    def build(self):
        return Builder.load_string(build)


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

I am attempting to instantiate a new screen by the click of a button in another screen. That in and of itself works flawlessly! The other thing I'm trying to do is pass a variable to that screen for use with methods I will be writing later on. In this sample here I am simply passing a string. Whenever I attempt to run this, after clicking the button in screen one, I get the following error: AttributeError: 'ScreenTwo' object has no attribute 'text'

How can I get around this and successfully pass a variable between screens?

Upvotes: 0

Views: 821

Answers (1)

ApuCoder
ApuCoder

Reputation: 2908

Create a StringProperty for the attribute text and pass it to ScreenTwo as a kwarg.

class ScreenTwo(Screen):
    text = StringProperty("")


class WindowManager(ScreenManager):
    def load_screen_two(self, text):
        self.add_widget(ScreenTwo(text = text))

However, is the following a typing error or it is actually there in the original code ? If the latter is the case here, the indentations should be consistent.

        Button:
            text: 'Load Screen Two'
            on_release:
                on_press: app.root.load_screen_two('Screen Two')
                on_release: Factory.NewGame().open()
                app.root.current = 'two'

Upvotes: 3

Related Questions