Home > database >  tkinter PhotoImage with variable name for each list item
tkinter PhotoImage with variable name for each list item

Time:12-30

I am trying to use images in tkinter radiobutton with varying items in my list. For loop is working good. Just getting PhotoImage error while generating variable path for each item.

from tkinter import *
from PIL import Image, ImageTk

win = Tk()
win.title("Review demo")
win.geometry("900x600")
win.minsize(900, 600)
win.maxsize(900, 600)

choices = ["like", "dislike", "love", "garbage"]
x = IntVar()
img = StringVar() # img declaration doesn't work


for r in range(len(choices)):
    item_name = choices[r]
    path = item_name ".png"
    img = PhotoImage(file = path )
    # img = PhotoImage(file = item_name '.png')
    radiobtn = Radiobutton(win,
                           text=item_name,
                           variable=x,
                           value=r,
                           padx=20,
                           pady=20,
                           image= img
                           )
    radiobtn.pack(anchor=E)

win.mainloop()

errors i am getting is

    img = PhotoImage(file = item_name '.png')
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Rohit\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 4130, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Users\Rohit\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 4075, in __init__
    self.tk.call(('image', 'create', imgtype, name,)   options)
_tkinter.TclError: couldn't recognize data in image file "like.png"

CodePudding user response:

I think we cannot use PhotoImage inside loop even with the help of ImageTk. So created a way around by creating a separate list of images path

choice_images = []
for choice in choices:      
   image = Image.open(choice '.png')
   resized_image = image.resize((100, 100))
   final_image = ImageTk.PhotoImage(resized_image)
   choice_images.append(final_image)

# generating radio buttons with respective images
x = IntVar()
for r in range(len(choices)):
   radiobtn = Radiobutton(win,
                        text=choices[r],
                        variable=x,
                        value=r,
                        font=("Noto Sans", 20),
                        image= choice_images[r],
                        compound= 'right',
                        command=rate_item
                        )
   radiobtn.pack(anchor=E)



CodePudding user response:

Since you use same variable img to save the references of the images, so only the last image has variable referencing it after the for loop and the previous images are garbage collected.

You can use an attribute of the radiobutton to store the reference of the image as below:

for r in range(len(choices)):
    item_name = choices[r]
    path = item_name ".png"
    # use ImageTk.PhotoImage instead of PhotoImage
    # to support latest PNG format
    img = ImageTk.PhotoImage(file=path)
    radiobtn = Radiobutton(win,
                           text=item_name,
                           variable=x,
                           value=r,
                           padx=20,
                           pady=20,
                           image=img
                           )
    radiobtn.pack(anchor=E)
    radiobtn.image = img # save the reference of the image
  • Related