Philip Seimenis
Philip Seimenis

Reputation: 53

Passing a text input from one screen to another in KivyMd.Kivy

I've been reading how to do this, but I can't follow the answer that has been given. I'm am still new to kivy and usually work on the data side of python. I am trying to pass a textinput with the id: client_name to my second screen labelled as Second to the MDlabel with the id: client_label. I may be going in the wrong direction and think my issue is that I'm confusing class with instance but not sure how to rectify this. When the button on screen one is pressed it should save the value of the client name and then transition to the second screen. I need to somehow access that value on my second screen.

My py file is main.py

from funct import *
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
from kivymd.app import MDApp
import os

#Define our different Screens
class FirstWindow(Screen):
    def press(self):
        client_name = self.ids.client_name.text
        print(client_name)
        #test()
        if client_name == '':
            pass
        else:
            if not os.path.exists("clients/" + client_name):
                os.makedirs("clients/" + client_name)
            if not os.path.exists("clients/" + client_name+"/LoanAgreement/"):
                os.makedirs("clients/" + client_name+"/LoanAgreement/")
            if not os.path.exists("clients/" + client_name+"/MortgageBond/"):    
                os.makedirs("clients/" + client_name+"/MortgageBond/")
            if not os.path.exists("clients/" + client_name+"/CertificateOfBalance/"):  
                os.makedirs("clients/" + client_name+"/CertificateOfBalance/")

class SecondWindow(Screen):
    client_name_label = StringProperty()

    def label_name(self):
        select_screen = self.manager.get_screen("First")
        client_name_label = select_screen.ids.client_name.text
        print(client_name_label)

class WindowManager(ScreenManager):
    pass

#Designate our .kv design file
#kv = Builder.load_file('law.kv')

class MainApp(MDApp):
    def build(self):
        self.theme_cls.primary_palette = "Green"
        self.theme_cls.theme_style = "Light"
        self.theme_cls.primary_hue = "700"
        return Builder.load_file('law.kv')

My .kv file is

WindowManager:
    FirstWindow:
    SecondWindow:

<FirstWindow>:
    name: "First"
    canvas.before:
        Color:
            rgba: (202/255, 231/255,193/255,0.4)
        Rectangle:
            pos: self.pos
            size: self.size

    MDCard:
        size_hint: None, None
        size: "400", "150"
        padding: 10
        pos_hint: {"center_x": .5, "center_y": .5}
        orientation: "vertical"
        
        MDTextField:
            id: client_name
            padding: 20, 20, 50, 20
            hint_text: "Type a client name"
            helper_text: "This will create a file for the client"
            #mode: "rectangle"
            size_hint_x: None
            width: 350
            helper_text_mode: "on_focus"
            pos_hint: {"center_x": 0.5, "center_y": 1.0}
            on_text_validate: root.press()
            on_text_validate: app.root.current = "Second"
        MDRaisedButton:
            text: "Create"
            pos_hint: {"center_x": .8}
            #md_bg_color: app.theme_cls.primary_light
            on_release: 
                root.press()
                app.root.transition.direction = 'left'
                app.root.current = "Second"
                root.manager.current_screen.label_name()

<SecondWindow>:
    name: "Second"

    canvas.before:
        Color:
            rgba: (202/255, 231/255,193/255,0.4)
        Rectangle:
            pos: self.pos
            size: self.size

    MDLabel:
        id: client_label
        text: root.client_name_label
        halign: "center"
        background_color: (1, 1, 1, 1)
        pos_hint: {"center_x": .5, "center_y": 0.9}

Upvotes: 0

Views: 963

Answers (2)

Philip Seimenis
Philip Seimenis

Reputation: 53

Based on the above answer just to expand I pasted the full solution that's working: py

from funct import *
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, StringProperty
from kivymd.app import MDApp
import os

#Define our different Screens
class FirstWindow(Screen):
    def press(self):
        client_name = self.ids.client_name.text
        print(client_name)
        #test()
        if client_name == '':
            pass
        else:
            if not os.path.exists("clients/" + client_name):
                os.makedirs("clients/" + client_name)
            if not os.path.exists("clients/" + client_name+"/LoanAgreement/"):
                os.makedirs("clients/" + client_name+"/LoanAgreement/")
            if not os.path.exists("clients/" + client_name+"/MortgageBond/"):    
                os.makedirs("clients/" + client_name+"/MortgageBond/")
            if not os.path.exists("clients/" + client_name+"/CertificateOfBalance/"):  
                os.makedirs("clients/" + client_name+"/CertificateOfBalance/")
            MDApp.get_running_app().root.ids.screen2.ids.client_label.text = self.ids.client_name.text # This updates screen2 label
            

class SecondWindow(Screen):
    pass

       

class WindowManager(ScreenManager):
    pass

#Designate our .kv design file
#kv = Builder.load_file('law.kv')

class MainApp(MDApp):
    def build(self):
        self.theme_cls.primary_palette = "Green"
        self.theme_cls.theme_style = "Light"
        self.theme_cls.primary_hue = "700"
        self.root = Builder.load_file('law.kv')
        return self.root



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

the kv file

WindowManager:
    FirstWindow:
        id: scrren1
    SecondWindow:
        id: screen2

<FirstWindow>:
    name: "First"
    canvas.before:
        Color:
            rgba: (202/255, 231/255,193/255,0.4)
        Rectangle:
            pos: self.pos
            size: self.size

    MDCard:
        size_hint: None, None
        size: "400", "150"
        padding: 10
        pos_hint: {"center_x": .5, "center_y": .5}
        orientation: "vertical"
        
        MDTextField:
            id: client_name
            padding: 20, 20, 50, 20
            hint_text: "Type a client name"
            helper_text: "This will create a file for the client"
            #mode: "rectangle"
            size_hint_x: None
            width: 350
            helper_text_mode: "on_focus"
            pos_hint: {"center_x": 0.5, "center_y": 1.0}
            on_text_validate: root.press()
            on_text_validate: app.root.current = "Second"
        MDRaisedButton:
            text: "Create"
            pos_hint: {"center_x": .8}
            #md_bg_color: app.theme_cls.primary_light
            on_release: 
                root.press() # this function will update screen 2s label
                app.root.transition.direction = 'left'
                app.root.current = "Second"

<SecondWindow>:
    name: "Second"

    canvas.before:
        Color:
            rgba: (202/255, 231/255,193/255,0.4)
        Rectangle:
            pos: self.pos
            size: self.size

    MDLabel:
        id: client_label
        text: '' # This will change when the previous screens button is pressed
        halign: "center"
        background_color: (1, 1, 1, 1)
        pos_hint: {"center_x": .5, "center_y": 0.9}

Upvotes: 1

Edher Carbajal
Edher Carbajal

Reputation: 631

In order to acccess SecondWindow or FirstWindow from anywhere, in your .kv file try the following:

  1. Add id reference to each screen:
WindowManager:
    FirstWindow:
        id: screen1
    SecondWindow:
        id: screen2      
  1. In your build method make a reference to the root:
class MainApp(MDApp):
    def build(self):
        self.theme_cls.primary_palette = "Green"
        self.theme_cls.theme_style = "Light"
        self.theme_cls.primary_hue = "700"
        self.root = Builder.load_file('law.kv')
        return self.root

Now you can acces your Windows from anywhere:

App.get_running_app().root.ids.screen1 #To acces FirstWindow
App.get_running_app().root.ids.screen2 #To acces SecondWindow

And finally, to modify the text of client_label from .py file:

App.get_running_app().root.ids.screen2.name = 'Changed!'

Upvotes: 1

Related Questions