Search code examples
pythonpython-3.xkivykivy-language

Kivy: How to bind text in TextInput widget to track a string variable


To be honest I have no clue what is going on regarding this. I made this example just to illustrate my problem. I read in a .txt file on the first page. One of the strings in this file gets saved. Then when I go to screen 2 I want the initial text inside the TextIpunt widget to be the text extracted from the file. I made a attempt using a StringProporty but like i said dont have a clue. Here is the code:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import ObjectProperty, StringProperty

month = ''

class FileChoose(BoxLayout):
    mnth = ''
    def select(self,filename):  
        try:
            
            with open(filename[0],'r') as f:
                for line in f:
                    i = [s.strip() for s in line.split(',')]
                    if i[0] == 'jan':
                        self.mnth = i[0]
            
            month = self.month
        except: pass   

class popup(Popup):
    pass

class Screen1(Screen):
    def open(self):
        pop = popup()
        pop.open()

class Screen2(Screen):
    m = StringProperty('')
    def on_enter(self):
        self.m = month
        self.ids.pie.text = self.m

root = ScreenManager()
class MyApp(App):
    def build(self):
        root.add_widget(Screen1(name='scr1'))
        root.add_widget(Screen2(name='scr2'))
        return root

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

and the kv file:

<Screen1>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text: 'Load file'
            on_press: root.open()
        Button: 
            text: 'next screen'
            on_press: root.manager.current = 'scr2'

<Screen2>:
    TextInput:
        id: pie
        size_hint: 0.6,0.2
        text: ''
        
<popup>:
    auto_dismiss: False
    size_hint: 0.6,0.6
    BoxLayout: 
        orientation: 'vertical'
        FileChoose:
            id: pie
            size_hint: 1,0.8
            dirselect: True
        Button:
            size_hint: 1,0.2
            text: "dismiss"
            on_press: root.dismiss()

<FileChoose>:
    id: File
    BoxLayout: 
        orientation: 'vertical'
        FileChooserListView:
            id: file2
            on_selection: File.select(file2.selection)

I set month as a global variable because I dont know how to get access to the FileChoose attributes whose parent is a popup. Can anyone help with this to maybe not use global variable. Thank you

the text file just looks like this: please just make one

feb
mar
jan

Solution

  • You had the right idea. Your solution does work, but you need to declare "month" as a global variable inside of your function. Otherwise a new variable, only visible to the function, with the same name is defined.

    I edited your code:

    class FileChoose(BoxLayout):
    mnth = ''
    
    def select(self, filename):
        global global_month
        try:
    
            with open(filename[0], 'r') as f:
                for line in f:
                    i = [s.strip() for s in line.split(',')]
                    if i[0] == 'jan':
                        self.mnth = i[0]
    
            global_month = "This works"  # self.month
        except:
            pass
    

    Note: I couldn't really get your function to read the line from my file. Perhaps I did something wrong. Therefore I assigned a hard-coded string to the variable when the function is called. I also changed the variables name from "month" to "global_month" to indicate, that it's a global variable.

    A more "pythonic" way of doing this, would be to "chain" the functions together and pass your values as a function-parameter.