Reputation: 533
so I've asked this question on kivy user support (google groups) but haven't got any replies yet, so I'll try here.
I've got a set of buttons which are created based on a search tool. Basically the way it works is that the user inputs a search term in a textinput box and based on the input text, my program searches a database for matched results. If there are any matched results, buttons are created (with their text as the text of the matched result) and this works very well. But my question is when buttons are created in a loop, how does one assign their individual on_press to call backs? For example in the my case, the code looks something like this:
In my .kv file I have the textinput widget:
<my rule>:
ti: Ti
TextInput:
id: Ti
on_text: root.function()
in my .py file I have the following (plus some other code):
t1 = ObjectProperty()
function():
layout = StackLayout(orientation = 'lr-tb', size_hint = (0.3, 0.8), pos_hint = {'top' : 0.87})
root.clear_widgets() #added this so that upon user input (i.e. on_text event of textinput) only matching results create new buttons
list_1 = ['a', 'b', 'c'] #this is a list of matching results
root.add_widget(layout)
for item in list_1: #this is the loop which creates the buttons
buttons = Button(text = str(item), size_hint = (1, 0.1), background_color = [255, 0, 0, 1])
buttons.bind(on_press = self.t1.insert_text(str(item)))
layout.add_widget(buttons)
The on_press assigned to the callback (as shown above) doesn't really work. What it is supposed to accomplish is that when the user presses that button, the text in textinput widget (self.ti1) is supposed to change to the button text (i.e. the buttons work as an auto-fill widget). What am I doing wrong?
Note that the above is only part of the code. The main code is structured as it should be, the only issue lies in the above snippet.
Thanks!
Upvotes: 2
Views: 4945
Reputation: 4162
Bind an event type or a property to a callback
self.bind(x=my_x_callback, width=my_width_callback,...)
So x
should be a event or a property, and my_x_callback
needs to be the reference to a callback/method
What's the difference between my_method() and my_method?
let's do this on the console, consider the method what_up
in the following code::
python<enter>
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def what_up():
... return 'nothing man, same old stuff'
...
>>> print what_up
<function what_up at 0x7f8df8a76a28>
>>> print what_up()
nothing man, same old stuff
As you can see from the results above, if you print what_up
directly you get a ref to the method, on the other hand if you call the method what_up()
you get whatever the function returns or None if it returns nothing.
You can just pass the reference of the function to any variable like ::
>>>my_up = what_up
>>> my_up()
'nothing man, same old stuff'
>>>
In your code::
buttons.bind(on_press = self.t1.insert_text(str(item)))
You are calling the function
on_press = self.t1.insert_text(str(item))
Instead of passing the function
on_press = partial(self.t1.insert_text, str(item))
call from functools import partial
before hand
Upvotes: 2