简体   繁体   中英

Tkinter - How to display image when clicking a button?

First time here so forgive me as this is my FIRST attempt at making a silly GUI game (if you want to call it that). I'm trying to get the user to click a button and the image of their selection pops up. I can't seem to figure out how to get the image to pop up though.

Image does show if I run it separately.

My code:

from Tkinter import *

root = Tk()

class PokemonClass(object):
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
                                  bg="Black", fg="White")
        self.WelcomeLabel.pack(fill=X)

        self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
                                 command=self.CharClick)
        self.CharButton.pack(side=LEFT, fill=X)

        self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
        self.SquirtButton.pack(side=LEFT, fill=X)

        self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
                                 fg="White")
        self.BulbButton.pack(side=LEFT, fill=X)

    def CharClick(self):
        print "You like Charmander!"
        global CharSwitch
        CharSwitch = 'Yes'

CharSwitch = 'No'

if CharSwitch == 'Yes':
    CharPhoto = PhotoImage(file="Charmander.gif")
    ChLabel = Label(root, image=CharPhoto)
    ChLabel.pack()

k = PokemonClass(root)
root.mainloop()

This works, but the actual image no longer shows, if I keep the PhotoImage OUT of the class it will print but I want to have it print IF they click the specific button:

from Tkinter import *



root = Tk()


class PokemonClass(object):

    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        self.WelcomeLabel = Label(root, text = "Welcome! Pick your Pokemon!", bg = "Black", fg = "White")
        self.WelcomeLabel.pack(fill = X)

        self.CharButton = Button(root, text = "Charmander", bg = "RED", fg = "White", command = CharClick)
        self.CharButton.pack(side = LEFT, fill = X)

        self.SquirtButton = Button(root, text = "Squirtle", bg = "Blue", fg = "White")
        self.SquirtButton.pack(side = LEFT, fill = X)

        self.BulbButton = Button(root, text = "Bulbasaur", bg = "Dark Green", fg = "White")
        self.BulbButton.pack(side = LEFT, fill = X)

    def CharClick():
    print "You like Charmander!"
    CharPhoto = PhotoImage(file = "Charmander.gif")
    ChLabel = Label(root, image = CharPhoto)
    ChLabel.pack()


k = PokemonClass(root)
root.mainloop()

You need to maintain a reference to your PhotoImage object. Unfortunately there is an inconsistency in tkinter in that attaching a Button to a parent widget increments the reference count, but adding an image to a widget does not increment the reference count. As a consequence at the moment the CharPhoto variable goes out of scope at the end of the function CharClick , the number of reference to the PhotoImage falls to zero and the object is made available for garbage collection.

If you keep a reference to the image somewhere, it will appear. When you kept it globally it remained in scope for the entire script and hence appeared.

You can keep a reference to it in the PokemonClass object or in the Label widget.

Below is the later of those options

from Tkinter import *

root = Tk()

class PokemonClass(object):
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
                                  bg="Black", fg="White")
        self.WelcomeLabel.pack(fill=X)

        self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
                                 command=self.CharClick)
        self.CharButton.pack(side=LEFT, fill=X)

        self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
        self.SquirtButton.pack(side=LEFT, fill=X)

        self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
                                 fg="White")
        self.BulbButton.pack(side=LEFT, fill=X)

    def CharClick(self):
        print "You like Charmander!"
        global CharSwitch
        CharSwitch = 'Yes'
        CharPhoto = PhotoImage(file="Charmander.gif")
        ChLabel = Label(root, image=CharPhoto)
        ChLabel.img = CharPhoto
        ChLabel.pack()

CharSwitch = 'No'

k = PokemonClass(root)
root.mainloop()

The solution which helped me is just simply declaring all the image variables on the next line after 'root = Tk()'. Doing so won't spoil your code or anything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM