-2

The following code runs properly without error just does not show the image for the label inside the toplevel window

from tkinter import*
from PIL import ImageTk,Image 

root = Tk()
root.title()
root.iconbitmap("SOME IMAGE PATH")


def window():
    global img   # HERE IS THE ONLY CHANGE
    top = Toplevel()
    img = ImageTk.PhotoImage(Image.open("SOME IMAGE PATH"))
    label = Label(top,image=img)
    label.pack()


button = Button(root,text="Open",command=window)
button.pack()

root.mainloop()

But when I run the same code just by declaring the img as global variable It shows the image and runs perfectly Given Below is that code...

from tkinter import*
from PIL import ImageTk,Image 

root = Tk()
root.title()
root.iconbitmap("SOME IMAGE PATH")


def window():
    global img   # HERE IS THE ONLY CHANGE
    top = Toplevel()
    img = ImageTk.PhotoImage(Image.open("SOME IMAGE PATH"))
    label = Label(top,image=img)
    label.pack()


button = Button(root,text="Open",command=window)
button.pack()

root.mainloop()

CAN ANYONE TELL ME WHY THE IMAGE ONLY APPEARS WHEN WE SET IT GLOBAL ?

  • @Random Davis Ya I think pretty much does it means that we have to keep the reference for the object for example here it is img – Raistar Reigns Mar 10 '23 at 18:08

1 Answers1

0

The reason that happens is because the variable photo (in the source of PhotoImage) is a local variable. That means that python automatically deletes the references to the variable as it goes along (called Garbage Collecting).

Your main 3 options here are to define it as global (as you did).

Other available solutions:

class Test:
    def __init__(self, master):
        canvas = tkinter.Canvas(master)
        canvas.grid(row = 0, column = 0)
        self.photo = tkinter.PhotoImage(file = './test.gif') # Changes here
        canvas.create_image(0, 0, image=self.photo) # Changes here

root = tkinter.Tk()
test = Test(root)
root.mainloop()

What the above code does is use the self parameter to increase the reference count for the photo and allows you to therefore save the varable, or image in this case.

    import tkinter
    photos = []
    class Test:
        def __init__(self, master):
            canvas = tkinter.Canvas(master)
            canvas.grid(row = 0, column = 0)
            photo = tkinter.PhotoImage(file = './test.gif')
            l.append(photo)
            canvas.create_image(0, 0, image=photo)

root = tkinter.Tk()
test = Test(root)
root.mainloop()

The method above uses a simplified method of the global variable solution, and allows you to save the photo to a list.

I got some information from here: Why does Tkinter image not show up if created in a function?

For future reference, you should check if your question has been asked before. Anyway, I hope this solves your problem. Good Luck with whatever you're coding!

Jonathan
  • 185
  • 9
  • If a post is a duplicate, it's a better use of your time to just flag the post as a duplicate. This is a helpful answer but it doesn't say anything that wasn't said in the duplicate post of this. – Random Davis Mar 10 '23 at 18:21
  • Just wanted to make it easier for him/her to understand – Jonathan Mar 10 '23 at 18:28