3

I am trying to display an image in a window. I tried it two methods, using classes and single snippet. I am confused why this is showing correct output:

from Tkinter import *
from PIL import ImageTk, Image

root = Tk()
picture="path/image.jpg"
image = Image.open(picture).resize((350, 350), Image.ANTIALIAS)
print(image)
pic = ImageTk.PhotoImage(image)
panel = Label(root, image = pic)
panel.grid(sticky="news")
root.mainloop()

but not the below one?

from Tkinter import *
from PIL import ImageTk, Image

class DisplayImage():

    def __init__(self, root):
        self.root = root

    def stoneImg(self, picture="path/default_image.png"):
        image = Image.open(picture).resize((350, 350), Image.ANTIALIAS)
        pic = ImageTk.PhotoImage(image)

        panel = Label(self.root, image=pic)
        panel.grid(sticky="news")

if __name__ == '__main__':
    root = Tk()
    DisplayImage(root).stoneImg()
    root.mainloop()
Sourabh Saini
  • 85
  • 1
  • 11

1 Answers1

8

The difference is that in your second example, the picture was referred to only by a local variable, which went away at the end of the function. Garbage collection works a bit weirdly in Tkinter, since all of the GUI-related objects exist in the embedded Tcl interpreter, outside of Python's control.

The simple solution is to add a line like panel.image = pic, so that a reference to the image exists for as long as the widget itself does.

jasonharper
  • 9,450
  • 2
  • 18
  • 42