Tkinter callback arguments

MRAB python at mrabarnett.plus.com
Sun Nov 1 21:13:26 CET 2009


Lord Eldritch wrote:
> Hi
> 
> Maybe this is maybe something it has been answered somewhere but I haven't 
> been able to make it work. I wanna pass one variable to a callback function 
> and I've read the proper way is:
> 
> Button(......, command=lambda: function(x))
> 
> So with
> 
> def function(a): print a
> 
> I get the value of x. Ok. My problem now is that I generate the widgets in a 
> loop and I use the variable to 'label' the widget:
> 
> for x in range(0,3):  Button(......, command=lambda: function(x))
> 
> so pressing each button should give me 0,1,2.
> 
> But with the lambda, I always get the last index, because it gets actualized 
> at each loop cycle. Is there any way to get that?
> 
A lambda expression is just an unnamed function. At the point the
function is /called/ 'x' is bound to 3, so that's why 'function' is
always called with 3.

A function's default arguments are evaluated when the function is
/defined/, so you can save the current value of 'x' creating the
function (the lambda expression, in this case) with a default argument:

     for x in range(0,3):
         Button(......, command=lambda arg=x: function(arg))

The following will also work, although you might find the "x=x" a bit
surprising/confusing if you're not used to how Python works:

     for x in range(0,3):
         Button(......, command=lambda x=x: function(x))



More information about the Python-list mailing list