learningCurve
learningCurve

Reputation: 109

Kivy 1.10.1 updating a ScreenManager tag with a function

I believe that my problem is that the label_text tag in the ScreenManager: section is not being updated when the change_text() function is run.Because it just shows the original label_text value, which in this case is nothing.

Does anyone know how get the tag to update? My goal is to be able to pass strings between the 2 Screen classes. So when a user enters something like a zip code on the previous screen i can pass it to the new screen.

#:kivy 1.1.3

ScreenManager:
    id: screen_manager

    SearchScreen:
        id: search_screen
        name: 'SearchScreen'
        manager: screen_manager
    ForecastScreen:
        id: forecast_screen
        name: 'ForecastScreen'
        manager: screen_manager
        label_text: search_screen.text

<SearchScreen>:
    display: entry
    FloatLayout:
        TextInput:
            id: entry
            on_text_validate:
                root.change_text()

<ForecastScreen>:
    BoxLayout:
        FloatLayout:
            Label:
                text:root.label_text

Then the py code:

class SearchScreen(Screen):
    text = StringProperty('')

    def change_text(self):
        self.text = "show this text"
        self.manager.current = "ForecastScreen"


class ForecastScreen(Screen):
    label_text = StringProperty()


Builder.load_file('weather.kv')
sm = ScreenManager()
sm.add_widget(SearchScreen(name='SearchScreen'))
sm.add_widget(ForecastScreen(name='ForecastScreen'))

class WeatherApp(App):
    def build(self):
        return sm

if __name__ == "__main__":
    WeatherApp().run()

Upvotes: 0

Views: 27

Answers (1)

eyllanesc
eyllanesc

Reputation: 244321

First, on_text_validate will only be called when you press enter if the TextInput has the multiline property to False, so set it.

On the other hand I see that you do not understand the difference between:

Foo:

and

<Foo>:

In the first case you are creating an instance of Foo (and there can only be one element of this type) and in the second you are implementing a component. When you call Builder.load_file() and having that first element without "<" ">" that instance is returned, that is, there is already a ScreenManager, but in your case you have created another with python code. The ScreenManager instantiated in the .kv already has the Screen where the texts are already linked, and in changes those of Python are not. And when you return the ScreenManager created in python without the linked elements you observe a correct behavior, nothing will be modified.

What you have to do is remove the ScreenManager from the .py and use the .kv:

*.py

class SearchScreen(Screen):
    text = StringProperty('')

    def change_text(self):
        self.text = "show this text"
        self.manager.current = "ForecastScreen"


class ForecastScreen(Screen):
    label_text = StringProperty("")


sm = Builder.load_file('weather.kv')

class WeatherApp(App):
    def build(self):
        return sm

if __name__ == "__main__":
    WeatherApp().run()

*.kv

ScreenManager:
    id: screen_manager
    SearchScreen:
        id: search_screen
        name: 'SearchScreen'

    ForecastScreen:
        id: forecast_screen
        name: 'ForecastScreen'
        label_text: search_screen.text

<SearchScreen>:
    display: entry
    FloatLayout:
        TextInput:
            id: entry
            multiline: False # <----
            on_text_validate:
                root.change_text()

<ForecastScreen>:
    BoxLayout:
        FloatLayout:
            Label:
                text: root.label_text

Upvotes: 1

Related Questions