Search code examples
kivy

pass variable between screens in kivy, in this case


I know there is a lot of question about this. Im new to kivy and i found that there is a lot of ways to do the same. Im trying to write with good structure (using as example some codes i find here).

I want to pass a variable (the token) in this scenario.

main.py / central.kv
login.py / login.kv
settings.py / settings.kv

this is main.py:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager
import login, settings

# hierarhy:
#   ScreensSample (App)
#   |- MyScreens (ScreenManager)
#      |- LoginScreen (Screen)
#      |- SettingsScreen (Screen)

class MyScreens(ScreenManager):
    def screen_manager_method(self):
        print('Hello from screen manager')

class Central(App):
    def app_method(self):
        print('Hello from app Tablero')


Central().run()

this is central.kv:

#:include login.kv
#:include settings.kv

MyScreens:
    LoginScreen:
    SettingsScreen:

This is login.py:

from kivy.app import App
from kivy.uix.screenmanager import Screen


class LoginScreen(Screen):
    def do_login(token):
        print('Hello from Login')
        print("El token es: ", token)

this is login.kv:

<LoginScreen>:
    name: 'login'

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: f'I am {root.name}'

        BoxLayout:
            orientation: 'vertical'
            
            Label:
                text:'Ingresar Token'
                font_size: 20

            TextInput:
                id:token
                multiline: False
                font_size: 20
        Button:
            text: 'Guardar'
            font_size: 24
            on_press: root.do_login(token.text)

This is settings.py:

from kivy.uix.screenmanager import Screen

class SettingsScreen(Screen):
    def screen_method(self):
        print('Hello from Settings screen_method')

setting.kv right now is empty because i just want to have the token from login and i dont know how.

Can you please tell me advice about this? I will like also to save this token to the cellphone in a way that cant be accessible from the user for avoid several logins every time the app is open, and for security.

Thank you very much!


Solution

  • For ease of testing, I put your stuff into one file. I put a value in the main object. I think the most helpful idea in here is that you can get a reference to the main app with App.get_running_app()

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    from kivy.uix.screenmanager import Screen
    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager
    from kivy.lang import Builder
    
    kv_string = """
    <LoginScreen>:
        name: 'login'
    
        BoxLayout:
            orientation: 'vertical'
    
            Label:
                text: f'I am {root.name}'
    
            BoxLayout:
                orientation: 'vertical'
                
                Label:
                    text:'Ingresar Token'
                    font_size: 20
    
                TextInput:
                    id:token
                    multiline: False
                    font_size: 20
            Button:
                text: 'Guardar'
                font_size: 24
                on_press: root.do_login(token.text)
    MyScreens:
        LoginScreen:
        SettingsScreen:
    """
    
    # hierarchy:
    #   ScreensSample (App)
    #   |- MyScreens (ScreenManager)
    #      |- LoginScreen (Screen)
    #      |- SettingsScreen (Screen)
    
    
    class SettingsScreen(Screen):
        def screen_method(self):
            print(f'Hello from Settings screen_method {self}\n{type(self)}')
    
    
    class LoginScreen(Screen):
        def do_login(self, token):
            print('Hello from Login')
            print(f'El token es:  {self}\n{type(self)}')
            app = App.get_running_app()
            print(type(app))
            print(app)
            app.shared_token = token
            print(f'the token is {app.shared_token}')
    
    
    class MyScreens(ScreenManager):
        def screen_manager_method(self):
            print(f'Hello from screen manager {self} {type(self)}\n{App.get_running_app().shared_token}')
    
    
    class Central(App):
        shared_token: str
    
        def __init__(self, argument_to_pass, **kwargs):
            super().__init__(**kwargs)
            self.shared_token = ""
            print(f'{argument_to_pass}\n\n\n{self.shared_token}')
    
        def build(self):
            Builder.load_string(kv_string)
            return LoginScreen()
    
        def app_method(self):
            print(f'Hello from app Tablero {self}')
    
    
    Central(argument_to_pass="program_options").run()