Patrisious Haddad
Patrisious Haddad

Reputation: 3

storing text input data kivy python

I need to do the simplest task which is that the input i receive from the first screen text input affects the results on the second screen , i have tried every thing i know such as global variables .. storing into variables then using and even putting the classes into each other nothing seems to work. what is the simplest way to take the input from the first screen and store it into variables that I can use later at the second screen.. there is a piece of the code below

def screenswitch(self):
    sm.current= 'settings'



class LoginScreen(GridLayout):
    def __init__(self, **kwargs):
            super(LoginScreen, self).__init__(**kwargs)
            self.cols = 2
            self.spacing = [5,140]
            self.test=Label(text='nothing')
            self.add_widget(self.test)
            self.add_widget(Label(text='Gender',color=(1, 0, 0, 1), font_size= 42))
            self.gender = TextInput(text='why',multiline=False,font_size=32,write_tab=False)
            self.add_widget(self.gender)
            self.gender.bind(text=self.test.setter('text'))
            self.btn1=(Button(text='Submit'))
            self.add_widget(self.btn1)
            self.btn1.bind(on_press=screenswitch)




class MenuScreen(Screen):
    def __init__(self,**kwargs):
            super(MenuScreen, self).__init__(**kwargs)
            self.loginscreen = LoginScreen()
            self.add_widget(self.loginscreen)


class TestScreen(BoxLayout):

    def __init__(self, **kwargs):
        super(TestScreen, self).__init__(**kwargs)
        self.loginscreen = LoginScreen()
        print self.loginscreen.gender.text
        self.orientation = 'vertical'
        self.add_widget(Label(text=self.loginscreen.gender.text))
        self.add_widget(Label(text='password'))



class SettingsScreen(Screen):
    def __init__(self,**kwargs):
        super(SettingsScreen,self).__init__(**kwargs)
        self.testscreen = TestScreen()
        self.add_widget(self.testscreen)

sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SettingsScreen(name='settings'))

class MyApp(App):

    def build(self):
        return sm


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

so no matter what I do at the second screen the first label always displays "why" while I'm sure that the gender.text is changing and I'm changing it what am I doing wrong ?

Upvotes: 0

Views: 947

Answers (2)

Albert Gao
Albert Gao

Reputation: 3769

The easiest way is Kivy way:

  • declare a class variable at your MyApp
  • Then you can get the value by app.get_running_app().your_class_variable_name
  • Don't forget to from kivy.app import app

That means you can use the kivy way to create a middle variable to manage the communication between two modules. You can use python way as well which use a single module to hold all the shared variables. Then you can just import the module you want, and access their values. So many ways, this one is quick since you don't need a new file.

Here is the main file to hold the 2 screens, it doesn't matter whether the 2 screens are in the same file or in 2 different files, here I put them all in main.py just for a quick hack. You can separate them if you need.

Every screen has 3 buttons

  • Read: read value of MY_NUMBER
  • Change: add MY_NUMBER by 1
  • Go: Go to next screen

You can see how the two screens can access the same shared variable and change it

And I show 2 way here to access the shared variable:
- how to access it in .kv file.
- how to access it in .py file.

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

Builder.load_string("""
<LoginScreen>:
    BoxLayout:
        orientation:'vertical'
        Label:
            text: 'I am LoginScreen'
        Label:
            id: lbl1
        Button:
            text: 'Read'
            on_press: root.press_read()
        Button:
            text: 'Change'
            on_press:
                app.MY_NUMBER = app.MY_NUMBER + 1
                root.ids.lbl1.text = 'SharedVar is ' + str(app.MY_NUMBER)
        Button:
            text: 'Go to ScreenTwo'
            on_press: app.sm.current = "screen_2"
<MenuScreen>:
    BoxLayout:
        orientation:'vertical'
        Label:
            text: 'I am MenuScreen'
        Label:
            id: lbl2
        Button:
            text: 'Read'
            on_press: root.press_read()
        Button:
            text: 'Change'
            on_press: 
                app.MY_NUMBER = app.MY_NUMBER + 1
                root.ids.lbl2.text = 'SharedVar is ' + str(app.MY_NUMBER)
        Button:
            text: 'Go to ScreenOne'
            on_press: app.sm.current = "screen_1"
""")

class LoginScreen(Screen):
    def press_read(self):
        app = App.get_running_app()
        self.ids.lbl1.text = "SharedVar is " + str(app.MY_NUMBER)

class MenuScreen(Screen):
    def press_read(self):
        app = App.get_running_app()
        self.ids.lbl2.text = "SharedVar is now " + str(app.MY_NUMBER)

class HandSetApp(App):
    MY_NUMBER = 0
    sm = ScreenManager()

    def build(self):
        HandSetApp.sm.add_widget(ScreenOne(name='screen_1'))
        HandSetApp.sm.add_widget(ScreenTwo(name='screen_2'))
        return HandSetApp.sm

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

Upvotes: 0

Karl Wagner
Karl Wagner

Reputation: 1

Should be:

class HandSetApp(App):
    MY_NUMBER = 0
    sm = ScreenManager()

    def build(self):
        HandSetApp.sm.add_widget(LoginScreen(name='screen_1'))
        HandSetApp.sm.add_widget(MenuScreen(name='screen_2'))
        return HandSetApp.sm

Then the program will run.

Upvotes: 0

Related Questions