Search code examples
pythonpython-3.xkivykivy-language

kivy reference text of TextInput by StringProperty


I would like to get the text of my TextInput via a StringProperty, but it does not work. I get an empty string. In the second example, I am declaring the whole TextInput as an ObjectProperty and then it does work. What is wrong with my first example?

How can a StringProperty be used to define the text inside a TextInput?

First example does not print text of TextInput example1.py

from kivy.app import App
from kivy.base import Builder
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout

Builder.load_string("""
<rootwi>:
    orientation: 'vertical'
    Button:
        on_press: root.print_txt()
    TextInput:
        text: root.textinputtext
""")
class rootwi(BoxLayout):
    textinputtext = StringProperty()

    def print_txt(self):
        print(self.textinputtext)


class MyApp(App):
    def build(self):
        return rootwi()

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

Second example does print text of TextInput, but uses a ObjectProperty not StringProperty example2.py

from kivy.app import App
from kivy.base import Builder
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock


Builder.load_string("""
<rootwi>:
    txt: txt
    orientation: 'vertical'
    Button:
        on_press: root.print_txt()
    TextInput:
        id: txt
""")
class rootwi(BoxLayout):
    txt = ObjectProperty()

    def print_txt(self):
        print(self.txt.text)


class MyApp(App):
    def build(self):
        return rootwi()

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

If I set the text to sth specific, it shows up in the TextInput. (But still, cannot be printed)

from kivy.app import App
from kivy.base import Builder
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout

Builder.load_string("""
<rootwi>:
    orientation: 'vertical'
    Button:
        on_press: root.print_txt()
    TextInput:
        text: root.textinputtext
""")
class rootwi(BoxLayout):
    textinputtext = StringProperty()

    def __init__(self, **kwargs):
        self.textinputtext = 'palim'
        super(rootwi, self).__init__(**kwargs)

    def print_txt(self):
        print(self.textinputtext)


class MyApp(App):
    def build(self):
        return rootwi()

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

Solution

  • If you want set and get the text using the StringProperty then you should create a bidirectional bind:

    from kivy.app import App
    from kivy.base import Builder
    from kivy.properties import StringProperty, ObjectProperty
    from kivy.uix.boxlayout import BoxLayout
    
    
    Builder.load_string("""
    <rootwi>:
        orientation: 'vertical'
        textinputtext: txt.text
        Button:
            on_press: root.print_txt()
        TextInput:
            id: txt
            text: root.textinputtext
    """)
    
    class rootwi(BoxLayout):
        textinputtext = StringProperty()
    
        def __init__(self, **kwargs):
            super(rootwi, self).__init__(**kwargs)
            self.textinputtext = 'palim'
    
        def print_txt(self):
            print(self.textinputtext)
    
    
    
    class MyApp(App):
        def build(self):
            return rootwi()
    
    if __name__ == '__main__':
        MyApp().run()
    

    Output:

    enter image description here