47
votes

This code works:

import tkinter

root = tkinter.Tk()
canvas = tkinter.Canvas(root)
canvas.grid(row = 0, column = 0)
photo = tkinter.PhotoImage(file = './test.gif')
canvas.create_image(0, 0, image=photo)
root.mainloop()

It shows me the image.

Now, this code compiles but it doesn't show me the image, and I don't know why, because it's the same code, in a class:

import tkinter

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

root = tkinter.Tk()
test = Test(root)
root.mainloop()
3
effbot.org is down. The gist of it is that the image is passed by reference. If the reference is to a local variable, the memory referenced gets reused and the reference becomes stale. The variable storing the image should be in the same scope (has to have the same lifetime) as the Tk gui object it appears on.maszoka

3 Answers

69
votes

The variable photo is a local variable which gets garbage collected after the class is instantiated. Save a reference to the photo, for example:

self.photo = tkinter.PhotoImage(...)

If you do a Google search on "tkinter image doesn't display", the first result is this:

Why do my Tkinter images not appear? (The FAQ answer is currently not outdated)

4
votes
from tkinter import *
from PIL import ImageTk, Image

root = Tk()

def open_img():
    global img
    path = r"C:\.....\\"
    img = ImageTk.PhotoImage(Image.open(path))
    panel = Label(root, image=img)
    panel.pack(side="bottom", fill="both")
but1 = Button(root, text="click to get the image", command=open_img)
but1.pack()
root.mainloop() 

Just add global to the img definition and it will work

0
votes

Just add global photo as the first line inside the function.