Generate Button and Entry pair based on list and have the Button
I'm trying to create a tkinter GUI that will be used to communicate with a microcontroller.
I want to create a bunch of Button - Entry pairs that each will send a command to the microcontroller together with the input of each Entry (formatted specific to that command).
I want to create the buttons by iterating over a list which contain the button name and a formatting function for the Entry widget.
See the code below for an example.
import tkinter as tk
root = tk.Tk()
class ButtonEntryFrame():
def __init__(self, parent, params, txtVar) -> None:
self.txt = params[0]
self.fn = params[1]
self.txtVar = txtVar
self.frame = tk.Frame(parent)
self.button = tk.Button(self.frame, text=self.txt, command=self.fn(self.txtVar))
self.entry = tk.Entry(self.frame, textvariable=self.txtVar)
self.button.pack(side=tk.LEFT)
self.entry.pack()
self.frame.grid()
frameInput = tk.Frame(root)
frameInput.pack(side=tk.LEFT)
inputFunctions = [
('Func A', lambda x: print(f"startMotor {x} 0 1")),
('Func B', lambda x: print(f"stopMotor")),
('Func C', lambda x: print(f"increaseSpeed 100 {x} 3"))]
frames = []
for i, params in enumerate(inputFunctions):
txtVar = tk.StringVar()
f = ButtonEntryFrame(frameInput, params, txtVar)
frames.append(f)
root.mainloop()
The code above does not work as I intend it to work. When I run it the lambdas are executed and printed directly. I understand why.
Is it possible to achieve what I want?
Solution 1:
You must do:
self.button = tk.Button(self.frame, text=self.txt, command=lambda: self.fn(self.txtVar))
I added the lambda
else self.fn
is immediately called.