0

I have a program where an image on a Tkinter GUI is replaced on a button click. I attached a function to the button where the original label is destroyed and replaced with a new one. Then I pack the new image using the new label. However, the image is not shown. It seems that I have to call mainloop() in the new function as well. Even that doesn't solve it.

def update():
    global imglabel
    imglabel.destroy()
    Img = ImageTk.PhotoImage(Image.open("img7.bmp"))
    imglabel = Label(image=Img)
    imglabel.pack()


root = Tk()
button1 = Button(root, text="Update", command=update)
button1.pack()

Img = ImageTk.PhotoImage(Image.open("img27.bmp"))
imglabel = Label(image=Img)
imglabel.pack()

root.mainloop()
  • 1
    @acw1668 I believe that's it as well, but then I don't quite understand why `imglabel = Label(image=Img)` isn't enough for the garbage collector to know it should keep the image in memory. – OctaveL Dec 20 '20 at 10:38

1 Answers1

1
def update():
    global imglabel
    imglabel.destroy()
    Img = ImageTk.PhotoImage(Image.open("img7.bmp"))
    imglabel = Label(image=Img)
    imglabel.image = Img # ADDED THIS LINE
    imglabel.pack()


root = Tk()
button1 = Button(root, text="Update", command=update)
button1.pack()

Img = ImageTk.PhotoImage(Image.open("img27.bmp"))
imglabel = Label(image=Img)
imglabel.pack()

root.mainloop()

Adding the image to it via imglabel.image = Img fixes it. My best guess is that the image gets garbage-collected since it's declared in update(), and so gets thrown out at the end of this method : while when it's explicitly attributed to imglabel.image, the interpreter knows it should keep it since it's now an attribute of a global variable. That would still make it odd for it not to keep it in memory when associated to the Label via Label(image=Img), so I'm really not sure I'm correct.

You may also avoid destroying the label and recreating it with this code:

def update():
    global imglabel
    Img = ImageTk.PhotoImage(Image.open("image7.bmp"))
    imglabel.configure(image=Img)
    imglabel.image = Img
OctaveL
  • 1,017
  • 8
  • 18