Python - Tkinter with labels & photos

I am making a program that gives you information and a picture about a planet/star. I am using tkinter to do so.

Here is the code that the problem arises around:

sunPic = r'sun.gif'
mercPic = r'merc.gif'


buttonFrame = Frame(root)
buttonFrame.pack(side=LEFT)

textFrame = Frame(root)
textFrame.pack(side=TOP)


def sunInfo():

    sunImage = PhotoImage(file=sunPic)
    img1 = Label(textFrame, image = sunImage)
    img1.image = sunImage
    img1.pack()


def mercInfo():

    mercImage = PhotoImage(file=mercPic)
    img1.configure(image = mercImage)
    img1.image = mercImage
    img1.pack()

sun = Button(buttonFrame, text="THE SUN",command=sunInfo)
sun.pack(side=TOP)

mercury = Button(buttonFrame, text="MERCURY",command=mercInfo)
mercury.pack(side=TOP)

When you press a button, it is supposed to change images. So say if I press THE SUN button, a pic of the sun would appear, and then I press the MERCURY button, a picture of mercury would replace the pic of the sun.

This doesn't work, however. When I click on the mercury button it comes up with this error:

img1.configure(image = mercImage)
NameError: global name 'img1' is not defined

Also, if I press THE SUN button several times, several images of the sun show up! I do not want this.

What I want to do in this program:

  • Create buttons with the planets names on.

  • Allow the user to press those buttons

  • A PICTURE and some INFORMATION on that planet show up

  • If the user presses another button, the PICTURE and INFORMATION is replaced by the new PLANETS information and picture.

This is a project I need to finish by tonight. I have little tkinter experience, and I need help.

Thank you.

ALSO:

Here is the full code that I am working on:

from tkinter import *

root = Tk()



root.geometry('1024x768+200+200') # makes window (x,y+top left corner right + top left corner down)
root.title("Planetary Information") # creates title for window

sunPic = r'sun.gif'
mercPic = r'merc.gif'


buttonFrame = Frame(root)
buttonFrame.pack(side=LEFT)

textFrame = Frame(root)
textFrame.pack(side=TOP)


def sunInfo():

    sunImage = PhotoImage(file=sunPic)
    img1 = Label(textFrame)
    img1.configure(image = sunImage)
    img1.image = sunImage
    img1.pack()


def mercInfo():

    mercImage = PhotoImage(file=mercPic)
    img1.configure(image = mercImage)
    img1.image = mercImage
    img1.pack()




sun = Button(buttonFrame, text="THE SUN",command=sunInfo)
sun.pack(side=TOP)

mercury = Button(buttonFrame, text="MERCURY",command=mercInfo)
mercury.pack(side=TOP)

venus = Button(buttonFrame, text="VENUS")
venus.pack(side=TOP)

earth = Button(buttonFrame, text="EARTH")
earth.pack(side=TOP)

mars = Button(buttonFrame, text="MARS")
mars.pack(side=TOP)

jupiter = Button(buttonFrame, text="JUPITER")
jupiter.pack(side=TOP)

saturn = Button(buttonFrame, text="SATURN")
saturn.pack(side=TOP)

uranus = Button(buttonFrame, text="URANUS")
uranus.pack(side=TOP)

neptune = Button(buttonFrame, text="NEPTUNE")
neptune.pack(side=TOP)

root.mainloop() # 

Answers


It's not working because of the variable scope. To put it simply: the variable img1 belongs to the function suninfo(), so when any other function tries to access it, it can't, so the traceback tells you:

NameError: global name 'img1' is not defined

The best fix would be to put your code inside a class, but the quickest fix would be to make img1 outside the function, then update it as required:

buttonFrame = Frame(root)
buttonFrame.pack(side=LEFT)

textFrame = Frame(root)
textFrame.pack(side=TOP)

img1 = Label(textFrame) #Create img1 outside the function
img1.pack()

def sunInfo():
    sunImage = PhotoImage(file=sunPic)
    img1.pack_forget()                 #Drop previous img1 picture
    img1.configure(image = sunImage)
    img1.image = sunImage
    img1.pack()                        #Re-pack as new image

def mercInfo():
    mercImage = PhotoImage(file=mercPic)
    img1.pack_forget()
    img1.configure(image = mercImage)
    img1.image = mercImage
    img1.pack()

sun = Button(buttonFrame, text="THE SUN",command=sunInfo)
sun.pack(side=TOP)

mercury = Button(buttonFrame, text="MERCURY",command=mercInfo)
mercury.pack(side=TOP)

The reason the picture isn't changing is because you need to update the widget. This can also be accomplished by the .place() method. Place the images on the same coordinates and it will change.

The reason the sun picture is showing several times is because of the .pack() method. The pack method packs the widget, automatically. You need to either create a update function or use the .place() method as said above.

Finally, when you press the mercury button, img1 isn't defined because it is not defined. You can create a global and put the global in the sun function and the mercury function.

The easiest way to refresh widgets is using the .grid() method and when you want to refresh the widget, use .grid_forget().

You should read up on this and learn about the widgets you use.


Need Your Help

How do I fill a column of an array with the contents of another array?

vba excel-2010

Preferably without using loops, is it possible to fill the contents of an empty array, let's call it C with the contents of two other arrays, let's call them A and B?

Having issues with adding user input in to a list in python

python list input append

Ive been working on a password keeper for educational purposes and would like the user to be able to create an account if they dont already have one. I figured the best way to do this was to have a