Python Forum
[Tkinter] Why does the image for the button not appear?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Why does the image for the button not appear?
#1
Hi all,

The below code is a simple game I'm trying to make within Tkinter. The current issue is that when I press deposit, the menu opens and the button appears, but the picture within the button doesn't appear, it's just a blank button. The button still works but the picture to go inside doesn't show. Can anyone help?

from tkinter import *
from tkinter.ttk import *
from PIL import ImageTk, Image
from playsound import playsound
import pygame

pygame.init()

window = Tk()
window.title("Dice Gamble")
window.attributes("-fullscreen", True)                                                                  
window.resizable(False, False)


pygame.mixer.music.load("dice_gamble_home_music.mp3")
pygame.mixer.music.play()


image_open = Image.open("Z:\Finley\School\Sixth Form\School Images\CS\casinodice.gif") #change to where the picture is
image = ImageTk.PhotoImage(image_open)

bg = Label(image=image)
bg.image = image

bg.place(x=-50, y=-50)

def play():
    print ("PLAY")

def deposit():
    deposit_page = Toplevel()
    deposit_page.title("Deposit")
    deposit_page.attributes("-fullscreen", True)                                                                  
    deposit_page.resizable(False, False)

    deposit_exit_button_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\exit.png")
    deposit_exit_button = Button(deposit_page, text="", image = deposit_exit_button_photo, command = exit_menu)
    deposit_exit_button.place(x=500,y=550)

def exit_menu():
    window.destroy()

def settings():
    print ("SETTINGS")


dice_gamble_label_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\dicegamble.png")
dice_gamble_label = Label(window, text="", image = dice_gamble_label_photo)
dice_gamble_label.place(x=400, y=50)

play_button_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\1c1p.png")
play_button = Button(window, text ="", image = play_button_photo, command=play)
play_button.place(x=500,y=250)

deposit_button_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\deposit.png")
deposit_button = Button(window, text="", image = deposit_button_photo, command = deposit)
deposit_button.place(x=500,y=400)

exit_button_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\exit.png")
exit_button = Button(window, text="", image = exit_button_photo, command = exit_menu)
exit_button.place(x=500,y=550)

settings_button_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\settings.png")
settings_button = Button(window, text="", image = settings_button_photo, command = settings)
settings_button.place(x=790,y=550)


window.mainloop()
"Only Boring People Get Bored"
Reply
#2
deposit_exit_button_photo is a function variable and the only thing referencing the image. When the function exits the variable no longer exists and the image reference count goes to 0. When an object's reference count is zero the object is reclaimed by garbage collection. In short, the garbage man has your image.
Reply
#3
(Oct-21-2021, 04:08 PM)deanhystad Wrote: deposit_exit_button_photo is a function variable and the only thing referencing the image. When the function exits the variable no longer exists and the image reference count goes to 0. When an object's reference count is zero the object is reclaimed by garbage collection. In short, the garbage man has your image.

Thanks for the help. I added this where necessary:

global deposit_exit_button_photo
Now the problem is fixed and the output is as expected. Once again, thank you.
"Only Boring People Get Bored"
Reply
#4
Using global is not a good way to fix it
If you don't want to use classes which is a better way of organising GUI code where you could keep a reference to the image as an attribute of the class instance, you could do the following.
deposit_exit_button_photo = PhotoImage(file = r"Z:\Finley\School\Sixth Form\School Images\CS\exit.png")
deposit_exit_button = Button(deposit_page, text="", image = deposit_exit_button_photo, command = exit_menu)
deposit_exit_button.image = deposit_exit_button_photo
To keep a reference to it on the button object.

Also see Namespace flooding with * imports
Reply
#5
One problem with using a global variable is what to do if you need more than one image? If you modified your program so it could make multiple buttons would you save the images in a list or a dictionary?

I like the idea of adding the image as an attribute to the button that uses the image. I think this will keep the image around as long the button is referenced. I even like this idea if you are using classes. The only time I would use a class variable to keep track of a button image would be for something like a toggle button when the same widget might toggle between different images.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] image inside button rwahdan 4 7,289 Jul-12-2021, 08:49 PM
Last Post: deanhystad
  tkinter showing image in button rwahdan 3 5,746 Jun-16-2021, 06:08 AM
Last Post: Yoriz
  tkinter button image Nick_tkinter 4 4,165 Mar-04-2021, 11:33 PM
Last Post: deanhystad
  Problem about image and button scotesse 5 3,080 Apr-27-2020, 10:09 AM
Last Post: scotesse
  Button with Image Icon Friend 2 6,897 Jul-25-2019, 09:39 AM
Last Post: Friend
  [PySimpleGui] How to alter mouse click button of a standard submit button? skyerosebud 3 5,095 Jul-21-2019, 06:02 PM
Last Post: FullOfHelp
  Simple Button click on image file to create action? jpezz 4 7,035 Mar-27-2019, 10:08 PM
Last Post: jpezz
  set button background with image of window background gray 3 14,528 Oct-18-2017, 08:22 AM
Last Post: gray

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020