Text Input kivy, print text input

2,212 views
Skip to first unread message

JoesMaker

unread,
Jul 20, 2014, 6:59:01 AM7/20/14
to kivy-...@googlegroups.com
Hi everyone,

I must say I am new to kivy and python and I am trying to learn both at the same time.
I have tried to look for an answer online but could not find exactly what I was looking for so I ll post my code here.
excuse me also if it is a bit of a mess in the code.

But first let me try to explain what I am doing in it.

I create labels and text input depending on how many result I hit inside a csv file. So the number of results can vary each time.
Then, for each hit I also create a text input going with the label. For each box I want to print on the screen the label next to it and the text inserted in it, (once it works on the screen I will write it in a txt file). The idea after is to create a button to save everything in one click in the text file.

I managed to do it when it is one output defined in the kv file but here I am not sure how to do it when it is varying.

Could anyone help me please? Thank you in advance, here is the code:

In my app.py:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput

import csv

file_name=' any.csv'

class Screen(BoxLayout):

    def on_text(self, *args):
        print(self.address.id)

    def __init__(self, **kwargs):
        super(Screen, self).__init__(**kwargs)
        text= 'Street Name'
        file=open(file_name, 'r')
        reader = csv.reader(file)
        for row in reader:
            if row[1]==text:
                y= Label(text=row[2])
                self.box1.add_widget(y)
                self.address = TextInput(id='id'+row[2], multiline=False)
                self.box2.add_widget(self.address)
                self.address.bind(on_text_validate=self.on_text)

class MyApp(App):

    def build(self):
        return Screen()


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


then in my kv file it is:


<Screen>:

    box1: box1
    box2: box2


    BoxLayout:
        cols:2
        orientation: 'horizontal'

        BoxLayout:
            id: box1
            orientation: 'vertical'
        BoxLayout:
            id: box2
            orientation: 'vertical'
       
So here what I get is the last self.address.id when I press return on any box. The idea would be to print self.y.text and self.address.text for each box but that is where I am struggling. I have found in the doc this:

def
on_enter(instance, value): print('User pressed enter in', instance) textinput = TextInput(text='Hello world', multiline=False) textinput.bind(on_text_validate=on_enter)

However I am unable to print the y.text.
I apologize if it is a silly question and the fix is easy but it s driving me mad for not finding a solution.
Thank again
Message has been deleted

ZenCODE

unread,
Jul 20, 2014, 2:04:06 PM7/20/14
to kivy-...@googlegroups.com
Hello. There seems to be some confusion here between the Screen widget and the TextInput. The Screen has as an "on_enter", and the "TextInput" has an "on_text_validate". Try hooking into those event reliably, and then it will all be a bit easier...
Message has been deleted
Message has been deleted

Philip

unread,
Jul 20, 2014, 8:31:21 PM7/20/14
to kivy-...@googlegroups.com
I'm kinda new to Kivy as well, so handle the following advice with caution :)

Il giorno domenica 20 luglio 2014 12:59:01 UTC+2, JoesMaker ha scritto:
        
So here what I get is the last "self. address. id" when I press return on any box. 

Let's look at your code:

Il giorno domenica 20 luglio 2014 12:59:01 UTC+2, JoesMaker ha scritto:
    def __init__(self, **kwargs):

        for row in reader:
            if row[1]==text:
                ......

                self.address = TextInput(id='id'+row[2], multiline=False)
                .......

Every iteration overrides the "self.address" variable: at the end of the for-cycle, it will contain a reference to the last TextInput widget created. In order to store multiple values, you need to use data structures such as lists, dictionaries, sets, etc.

However, in your case, you don't actually need that; you just need to change your callback as follows:

 
def on_text (self, instance):
        print (instance.id)  
        print (instance.text)


Event callbacks, like yours, are called with one argument, a reference to the widget which fired the event. You can read more on callbacks here.  

Hope it helps,
Philip

JoesMaker

unread,
Jul 21, 2014, 4:17:24 AM7/21/14
to kivy-...@googlegroups.com
Hi, Thanks a lot for the reply to both of you.

Philip, your solution worked, Thank you very much cause it has been bothering me for a while. Now I see the answer it seems simple (as always =) )

All the best,

J
Reply all
Reply to author
Forward
0 new messages