7

Hi i am trying to put an image as the background on one of my buttons, i have already done this on lots of other buttons in my main window but this particular button sits inside a top level window and the image doesn't load like it should, does anyone know why? (i have also tried defining the width and height of the button but that still doesn't show the image)

def rec_window():
    recw = Toplevel(width=500,height=500)
    recw.title('Record To.....')
    img1 = PhotoImage(file="C:/Users/Josh Bailey/Desktop/pi_dmx/Gif/mainmenu.gif")
    Button(recw, image=img1, command=rec_preset_1).grid(row=1, column=1)
    Button(recw, text="Preset 2", bg = 'grey70',width=40, height=12,command=rec_preset_2).grid(row=1, column=2)
    Button(recw, text="Preset 3", bg = 'grey70',width=40, height=12,command=rec_preset_3).grid(row=2, column=1)
    Button(recw, text="Preset 4", bg = 'grey70',width=40, height=12,command=rec_preset_4).grid(row=2, column=2)
    Button(recw, text="Cancel", bg='grey70', width=20, height=6, command=recw.destroy). grid(row=3,column=1,columnspan=2, pady=30)
user2996828
  • 1,137
  • 3
  • 12
  • 19

2 Answers2

37

Depending on how the rest of your program is structured, your image might be getting cleared by garbage-collection:

From http://effbot.org/tkinterbook/photoimage.htm

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 can start your function by declaring img1 as a global variable to retain a reference:

global img1

or, if you already have img1 elsewhere in your program:

img1 = PhotoImage(file="C:/Users/Josh Bailey/Desktop/pi_dmx/Gif/mainmenu.gif")
img1Btn = Button(recw, image=img1, command=rec_preset_1)
img1Btn.image = img1
img1Btn.grid(row=1, column=1)
atlasologist
  • 3,824
  • 1
  • 21
  • 35
  • There's nothing about this [here](http://www.tkdocs.com/tutorial/widgets.html) or [here](http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Button.html) and it was exactly why an icon didn't show up on a button in my app - so much appreciated. – z33k Feb 06 '18 at 20:15
  • 1
    Along with this, it seems that if you have a width and height defined for you label/button then it won't sometimes work. Remove the width and height and it should work. – KingMak Sep 09 '20 at 09:39
  • 1
    Wow wtf, I have been using python for a very long amount of time, I've created around 10 massive programs that use Tkinter and Tkinter icons on labels, and I've never had this problem, no idea why I need it now but thanks so much man! – Arjuna Nov 17 '22 at 18:12
0

Same problem with this code

    photo = PhotoImage(file="app/foo.png")
    self.snipButton = Button(
        self.menu_button_bar,
        image=photo
    )
    self.snipButton.pack()

I was also able to resolve this issue by adding self to my photo variable.

    self.photo = PhotoImage(file="app/foo.png")
    self.snipButton = Button(
        self.menu_button_bar,
        image=self.photo
    )
    self.snipButton.pack()
Brett La Pierre
  • 493
  • 6
  • 15