I have a project made with Tkinter which involves buttons. These buttons have a command which resizes their images. The problem is that the images simply do not display. They only display if I create the image as a ImageTk.PhotoImage object outside the class and don't interfere with the image in the init function. The skeleton of the method I used to do this is like so:
from tkinter import *
from PIL import Image, ImageTk
class GrowingButton(Button):
def __init__(idx, *args, image=None, **kwargs):
super().__init__(*args, **kwargs)
self.img = image
self.grid(row=idx, column=0, sticky="news")
if image:
self.configure(command=self.expand, image=ImageTk.PhotoImage(image))
self.image = ImageTk.PhotoImage(image)
def expand(self):
if self.img:
self.img = self.img.resize((1, 1))
self.configure(image=ImageTk.PhotoImage(image=self.img))
self.image = ImageTk.PhotoImage(image=self.img)
root = Tk()
[root.rowspan(i, weight=1) for i in range(10)]
buttons = [GrowingButton(i, root, image=Image.open("")) for i in range(10)]
root.mainloop()
The issue may have to do with other parts of the code (though I doubt it). If that's the case, please inform me and I'll add other relevant code or maybe post a link the repository. This is a just a minimal reproducible example, but I'm completely stumped on why it doesn't work.
Thanks in advance!
CodePudding user response:
Assigning self.image
doesn't change the button. You need to explicitly reconfigure the button whenever the image changes.
Also, you need to keep a reference to the image that is being used by the button. You're creating two images: one used by the button, and a second identical image is being assigned to self.image
. The one being used by the button isn't being saved, so the garbage collected is destroying it when the function returns.
The code should be something like this:
self.image = ImageTk.PhotoImage(image=self.img)
self.configure(image=self.image)