Pavan
Pavan

Reputation: 391

How to reference widgets of different screens created in kivy using kv language?

My app consists of 2 screens:

Screen 1 - 1 textinput widget and 1 button widget

Screen 2 - 1 textinput widget

On button press I want to capture the data entered in the textinput of Screen1 and print it in textinput of Screen2.

I have tried the following code but getting error:

main.py

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

class Screen1(Screen):
    pass

class Screen2(Screen):
    pass  

class WindowManager(ScreenManager):
    txtinp1 = ObjectProperty(None)
    txtinp2 = ObjectProperty(None)

class ResultsApp(App):

    def build(self):
        return Builder.load_file("tutorials\Design3.kv")

    def disp(self):
        self.root.txtinp2.text = self.root.txtinp1.text        

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

design3.kv

WindowManager:
    Screen1:        
    Screen2:     

<Screen1>    
    name:'main'
    txtinp1:textinp1 
    GridLayout:
        cols:1                
        TextInput:
            id:textinp1
        Button:
            text:'Submit'
            on_press: 
                app.root.current = 'second'
                app.disp()
<Screen2>
    name:'second'
    txtinp2:textinp2 
    GridLayout:        
        cols:1        
        TextInput:
            id:textinp2

The error I am getting is below.

File "c:/Users/pavan m sunder/projects/kivy/tutorials/tut7(kvlang).py", line 25, in disp
     self.root.txtinp2.text = self.root.txtinp1.text

AttributeError: 'NoneType' object has no attribute 'text'

I tried looking for solutions in stackoverflow but couldn't find.

Upvotes: 2

Views: 665

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

By doing txtinp1: textinp1 you are indicating that Screen1 maps the textinp1 object through the txtinp1 property, but then you want to access that property through the root that is the ScreenManager which is clearly wrong.

There are many solutions but in this case I will show how to map the properties of each Screen in the ScreenManager:

WindowManager:
    txtinp1: screen1.textinp1
    txtinp2: screen2.textinp2
    Screen1: 
        id: screen1       
    Screen2:
        id: screen2


 <Screen1>    
    textinp1: textinp1
    name:'main'
    GridLayout:
        cols:1        
        TextInput:
            id:textinp1
        Button:
            text:'Submit'
            on_press: 
                app.root.current = 'second'
                app.disp()

 <Screen2>
    textinp2: textinp2
    name:'second'
    GridLayout:        
        cols:1        
        TextInput:
            id:textinp2

Upvotes: 2

Related Questions