Michal
Michal

Reputation: 259

Tkinter - create buttons and its images using loop

is there a way how to create buttons each with unique images and identities using loop? I came up with the code below but only button that works and has its image is the last one:

import tkinter as tk
from tkinter import *
from functools import partial

win = tk.Tk()
win.geometry('800x500')  # set window size

dic = {0: {"row": 0, "col": 0 }, 1: {"row": 1, "col": 0 }, 2: {"row": 2, "col": 0 }}

chairImg, chair2Img, checkImg = None, None, None

fileList = [chairImg, chair2Img, checkImg]
imgList = ['chair.png', 'chair2.png', 'check.png']
buttonIdentities = []
i=0

def checkButton(n):
    # function to get the index and the identity (bname)
    print(n)
    bname = (buttonIdentities[n])

for img, f in zip(imgList, fileList):
    f = PhotoImage(file=img)
    f = f.zoom(16).subsample(256)
    
    button = Button(win, image=f, command=partial(checkButton, i))
    button.grid(row=dic[i]['row'], column=dic[i]['col'])
    buttonIdentities.append(button)
    i+=1   

print(button_identities)
win.mainloop()

I'd love to simplify my code because I'm gonna be using a lot more buttons and images in my app. Thank you for your time and answers.

Upvotes: 1

Views: 209

Answers (1)

Henry
Henry

Reputation: 3942

It looks like the images are getting lost because of garbage collection. To avoid this, just add a reference to the image, like this:

button = Button(win, image=f, command=partial(checkButton, i))
button.image = f #This line here.
button.grid(row=dic[i]['row'], column=dic[i]['col'])

(It doesn't have to be .image, it can be anything)
By keeping a reference to the image, it doesn't get garbage collected. You can read more about it here.

Upvotes: 1

Related Questions