user2607820
user2607820

Reputation: 21

Add an image button to top level window Tkinter

I'm building a small GUI application, that once a button is clicked a new top level window will open and it should display images for buttons.

I can get the image button to work on the root window, but not on the top level window. Only a blackbox appears.

I have a generic button on both windows and they do work.

I'm new to Python.

import Tkinter 
from Tkinter import *
from PIL import ImageTk, Image

root = Tkinter.Tk()

root.title("First Window")                  
root.configure(background = "black")    

def new_window():
    win2 = Toplevel(root)
    win2.geometry("650x350+50+40")        
    win2.title("Second Window!")            
    win2.configure(background = "white")    

    def close1():
        win2.destroy()

    img1 = ImageTk.PhotoImage(Image.open("./images/close.gif"))
    c1 = Button(win2, image = img1, bg ="black", command = close1)
    c1.grid(row = 1)

    c2= Tkinter.Button(win2, text='close', command = close1)
    c2.grid(row = 2)    


nw = Tkinter.Button(root, text = 'New Window' , command = new_window)
nw.grid(row = 1)

def close3(): 
    root.destroy()

img3 = ImageTk.PhotoImage(Image.open("./images/close.gif"))
c3 = Button(root, image = img3, bg ="black", command = close3)
c3.grid(row = 2)


root.mainloop()

Upvotes: 2

Views: 2501

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385980

When you create the new toplevel, you are using a local variable to refer to the image. Because of this, when the method exits, the garbage collector will delete the image. You need to save a reference in a global variable, or some other way to protect it from the garbage collector

A common way to save a reference is to make it an attribute of the button:

img1 = ImageTk.PhotoImage(...)
c1 = Button(...)
c1.image = img1

Upvotes: 3

Related Questions