Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter vanishing PhotoImage issue [duplicate]

I am trying to display an image in a window...seems simple enough right? Well I have a big bug!

I have this exact same code in one file:

import Tkinter

root = Tkinter.Tk()
canvas = Tkinter.Canvas(root)
canvas.grid(row = 0, column = 0)
photo = Tkinter.PhotoImage(file = '/Users/Richy/Desktop/1.gif')
image1 = canvas.create_image(0,0, image=photo)
root.mainloop()

It works.

I have this in part of a bigger file:

def officialPictureWindow(self):
    t = Toplevel(self)
    t.wm_title("Official Image")
    self.__canvas3 = Canvas(t)
    self.__canvas3.grid(row = 0, column = 0)
    photo = PhotoImage(file = '/Users/Richy/Desktop/1.gif')
    image1 = self.__canvas3.create_image(0,0, image=photo)

It doesn't work!

That function is called when someone presses a button on a menubar I have. All the other menubar buttons I have operate properly and show their windows. There's no images in the others though.

This gives no no error. Just a blank screen. Does anyone know why?

like image 754
user3159537 Avatar asked Sep 16 '25 11:09

user3159537


1 Answers

You need to keep an additional reference to photo so it doesn't get prematurely garbage collected at the end of the function. An Introduction to Tkinter explains further:

Note: When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.

To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:

label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()

In your case, you could attach the image to your self variable, or maybe the canvas. It doesn't really matter, as long as it is assigned to something.

self.image = photo
#or:
self.__canvas3.image = photo
like image 177
Kevin Avatar answered Sep 18 '25 23:09

Kevin