Search code examples
pythonkivykivy-language

How can i make textinput a class variable


I am trying to get TextInput's text from another screen. In the code below I can get the text but my project has multiple functions. So I thought if I can make textinput a class variable it would be eaiser to coding.

Example Code:

.py

from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.screenmanager import NoTransition
import requests


class MainPage(Screen):
    pass


class ExercisePage(Screen):

    def test(self):
        link = self.manager.get_screen('mainpage')
        a = requests.get(f'{link.ids.http.text}/gpio12On')

    def testt(self):
        link = self.manager.get_screen('mainpage')
        a = requests.get(f'{link.ids.http.text}/gpio12Off')


class MyApp(App):

    def build(self):
        global sm
        sm = ScreenManager(transition=NoTransition())
        sm.add_widget(MainPage(name='mainpage'))
        sm.add_widget(ExercisePage(name='exercisepage'))
        return sm


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

Here is the .kv file

<MainPage>
    FloatLayout:
        TextInput:
            id: http
            text: ""
            multiline: False
            size_hint: 0.5,0.05
            pos_hint: {"x": 0.3, "y": 0.8}
        Button:
            text:"Enter"
            size_hint: 0.1,0.06
            pos_hint: {"x": 0.82, "y": 0.795}
            on_release:
                app.root.current = "exercisepage"

<ExercisePage>
    FloatLayout:
        Button:
            text:"test"
            size_hint: 0.5,0.075
            pos_hint: {"x": 0.2, "top": 0.4}
            on_release:
                root.test()
        Button:
            text:"test2"
            size_hint: 0.5,0.075
            pos_hint: {"x": 0.2, "top": 0.5}
            on_release:
                root.testt()

What I am trying to do is like this:

class ExercisePage(Screen):
    link = self.manager.get_screen('mainpage')
    
    def test(self):
        a = requests.get(f'{self.link.ids.http.text}/gpio12On')

    def testt(self):
        a = requests.get(f'{self.link.ids.http.text}/gpio12Off')

Solution

  • If you define your application root in the kv file, then the ids are available everywhere in that root rule. And then you can define an ObjectProperty in the ExercisePage that refers to the TextInput text. Here is what such a kv file could look like:

    ScreenManager:
        MainPage:
            name: 'mainpage'
            FloatLayout:
                TextInput:
                    id: http
                    text: ""
                    multiline: False
                    size_hint: 0.5,0.05
                    pos_hint: {"x": 0.3, "y": 0.8}
                Button:
                    text:"Enter"
                    size_hint: 0.1,0.06
                    pos_hint: {"x": 0.82, "y": 0.795}
                    on_release:
                        app.root.current = "exercisepage"  # this could also be just root.current = "exercisepage"
        
        ExercisePage:
            id: escr
            link: http.text  # link to the TextInput text
            name: 'exercisepage'
            FloatLayout:
                Button:
                    text:"test"
                    size_hint: 0.5,0.075
                    pos_hint: {"x": 0.2, "top": 0.4}
                    on_release:
                        escr.test()  # changed to use id
                Button:
                    text:"test2"
                    size_hint: 0.5,0.075
                    pos_hint: {"x": 0.2, "top": 0.5}
                    on_release:
                        escr.testt()  # changed to use id
    

    Then you define the ObjectProperty in the ExercisePage, and use that in the methods:

    class ExercisePage(Screen):
        link = ObjectProperty(None)
    
        def test(self):
            # link = self.manager.get_screen('mainpage')
            print(self.link)
            # a = requests.get(f'{link.ids.http.text}/gpio12On')
    
        def testt(self):
            # link = self.manager.get_screen('mainpage')
            print(self.link)
            # a = requests.get(f'{link.ids.http.text}/gpio12Off')
    

    And since you define the root widget in the kv file, you can completely eliminate the build() method from your MyApp class.