Oct-20-2020, 04:30 PM
command = lambda:do_something(x) does not work because lambdas are evaluated when called. IN this example I make three buttons and all are set to call DoSomething and passing the argument I.
How about answer this. What is the value of i? In my Python console I type i and it responds "2". I press a button, the button executes the lambda. The lambda calls DoSomething and passes the value of i.
To lock in the "i" argument in the callback you can use a partial function. The partial function arguments are frozen when the partial function is created. You are not actually setting the "command" to DoSomething(i), you are setting it to DoSomething(0) or DoSomething(1). You can do something similar with a lambda.
import tkinter as tk buttons = [] def DoSomething(args): print(args) root = tk.Tk() f = tk.Frame() f.pack() for i in range(3): b = tk.Button(f, command = lambda : DoSomething(i), text=str(i)) b.grid(row=0, column=i) buttons.append(b)When I press any button the program prints "2". Why is that?
How about answer this. What is the value of i? In my Python console I type i and it responds "2". I press a button, the button executes the lambda. The lambda calls DoSomething and passes the value of i.
To lock in the "i" argument in the callback you can use a partial function. The partial function arguments are frozen when the partial function is created. You are not actually setting the "command" to DoSomething(i), you are setting it to DoSomething(0) or DoSomething(1). You can do something similar with a lambda.
import tkinter as tk buttons = [] def DoSomething(args): print(args) root = tk.Tk() f = tk.Frame() f.pack() for i in range(3): b = tk.Button(f, command = lambda x = i: DoSomething(x), text=str(i)) b.grid(row=0, column=i) buttons.append(b)