Python Tkinter button callback Python Tkinter button callback tkinter tkinter

Python Tkinter button callback


Easy fix is to initialize the lambda function with the current value of i each time the lambda function is created. This can be done using Python default values for another dummy variable j.

command = lambda j=i: myfunction(j)


Blender's answer is a clever solution but in case you get thrown off by the function abstraction, here is another possible way to do it. It really just creates a mapping, saved in buttons, from Button widgets to their proper numbers.

import Tkinter as tkroot = tk.Tk()def myfunction(event):    print buttons[event.widget]buttons = {}for i in range(10):    b = tk.Button(root, text='button' + str(i))    buttons[b] = i # save button, index as key-value pair    b.bind("<Button-1>", myfunction)    b.place(x=10,y=(10+(25*i)))root.mainloop()


It's because i in your anonymous function refers to the counter variable, not to the value:

from __future__ import print_functionx = [lambda: print(i) for i in range(10)]for f in x:    f()

This produces an output of 10 consecutive 9s.

To get around this, you'd have to use two lambdas and shadow i with a second function (which creates your first function):

from __future__ import print_functionx = [(lambda i: (lambda: print(i)))(i) for i in range(10)]for f in x:    f()

Although at that point, you'd be better off just making a named function:

def my_command(i):    def inner_function():        return my_function(i)    return inner_function

And using it like this:

tk.Button(root, text='button' + str(i), command=my_command(i))