So I have the code below to generate a whole bunch of widgets iteratively from a list of names and other inputs. My problem now is with the button widgets, which have all their commands being the same. The problem with the code is obvious, the command code for each button doesn't run until the loop finish, thus all buttons call the same command as the last/"i-th" button.
So my question would be how do I have each button call the right associated command instead of having the same command as the button in the last row, and still have my widgets be generated iteratively.
# Generates a frame that also contains all the necessary widgets for all mounts in a list
# Takes the parent window the frame will be part of (TK()),
# the row (int) and column (int) the new frame will be located on the parent window,
# the name of the frame we're creating (string),
# and a list of all the mounts to go into the frame (list of string),
# the complement_checkbox (tkinter.CheckButton())
# Returns (tkinter.LabelFrame)
def generate_widgets(master, frame_name, mount_list, complement_checkbox):
new_frame = LabelFrame(master, text = frame_name, font=("Arial Narrow", 18), padx = 5, pady = 5)
new_frame.grid(row = 0, column = 0, padx = 10, pady = 10, sticky = N + S + E + W)
# We have row weight be equal to the number of mounts per frame
master.rowconfigure(0, weight = len(mount_list))
master.columnconfigure(0, weight = 1)
label_widgets = {}
attempts_string = {}
spin_widgets = {}
button_widgets = {}
for i in range(len(mount_list)):
full_name = mount_list[i]
mount_name = full_name.split(' - ')[1]
label_widgets[i] = Label(new_frame, text = mount_list[i], font = ("Arial Narrow", 12))
label_widgets[i].grid(row = i, column = 0, sticky = W)
attempts_string[i] = StringVar()
attempts_string[i].set(load_attempts(mount_name))
spin_widgets[i] = Spinbox(new_frame, from_ = 0, to = 255, width = 5, textvariable = attempts_string[i])
spin_widgets[i].grid(row = i, column = 1, sticky = E)
button_widgets[i] = Button(new_frame,
text = "Calculate",
command = lambda: open_and_save(full_name,
mount_name,
int(spin_widgets[i].get()),
complement_checkbox.get()))
button_widgets[i].grid(row = i, column = 2, sticky = E)
new_frame.rowconfigure(i, weight = 1)
# Column 0 is label, column 1 is spinbox, column 2 is button
new_frame.columnconfigure(0, weight = 1)
new_frame.columnconfigure(1, weight = 1)
new_frame.columnconfigure(2, weight = 1)
return new_frame