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