# 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 = {}
image = {}
icon_label = {}
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)
image[i] = PhotoImage(file = "Assets\" + mount_name + ".png")
icon_label[i] = Label(new_frame, image = image[i])
icon_label[i].grid(row = i, column = 1, sticky = E)
attempts_string[i] = StringVar()
attempts_string[i].set(load_attempts(mount_name))
spin_widgets[i] = Spinbox(new_frame, from_ = 0, to = 1024, width = 5, textvariable = attempts_string[i])
spin_widgets[i].grid(row = i, column = 2, sticky = E)
button_widgets[i] = Button(new_frame,
text = "Calculate",
# j = i saves the current value of i into j when lambda is defined,
# if we don't have this line, the command will always use the value of i when the
# command is called, which will be the last row (i-th)
command = lambda j = i: open_and_save(mount_list[j],
mount_list[j].split(' - ')[1],
spin_widgets[j].get(),
complement_checkbox.get()))
button_widgets[i].grid(row = i, column = 3, 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)
new_frame.columnconfigure(3, weight = 1)
return new_frame
I'm using the above code to create a new frame and fill it iteratively with widgets. So the problem I'm having right now is that the images I'm trying to display with icon_label[i] isn't working, and is instead just a blank space. I'm quite sure why this is happening, as when I try adding an image to the frame after the function has already run, the image display. I also noticed that if I make images{} and icon_label{} global, some of the images display, but not all (some frames have none, some only have the last few, or only the last). So I'm just wondering what is going on?
question from:
https://stackoverflow.com/questions/66056445/displaying-images-iteratively-in-tkinter