Tkinter - How to display image when clicking a button?
<p>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.</p>

<p>Image does show if I run it separately.</p>

<p>My code:</p>

<pre><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()
</code></pre>

<p>You need to maintain a reference to your <code>PhotoImage</code> object. Unfortunately there is an inconsistency in tkinter in that attaching a <code>Button</code> 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 <code>CharPhoto</code> variable goes out of scope at the end of the function <code>CharClick</code>, the number of reference to the <code>PhotoImage</code> falls to zero and the object is made available for garbage collection.</p>

<p>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.</p>

<p>You can keep a reference to it in the <code>PokemonClass</code> object or in the <code>Label</code> widget.</p>

<p>Below is the later of those options</p>

<pre><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'
        CharPhoto = PhotoImage(file="Charmander.gif")
        ChLabel = Label(root, image=CharPhoto)
        ChLabel.img = CharPhoto
        ChLabel.pack()

CharSwitch = 'No'

k = PokemonClass(root)
root.mainloop()
</code></pre>

python tkinter