GIS Logo GSP 118 (318): GIS Programming

The Python GUI

In Review

1. Tkinter

There are a number of graphical user interface (GUI) packages for Python. We've already been using the most popular one, Tkinter so we'll stay with it.

Modal Dialogs

A modal dialog is a window that you keeps you in a "mode" inside an application until you are done with the dialog. This includes message boxes and most settings dialogs. Try creating the very simple dialog box below.

from Tkinter import *

root = Tk() # Get the root object from Tkinter

TheLabel = Label(root, text="Hello, world!") # Add a label to the dialog
TheLabel.pack() # Automatically position the item in the dialog

root.mainloop() # Loop until the user closes the dialog

There are a number of different "widgets" that you can create in Tkinter. You will be familiar with these as a user, now it's time to create them yourself. Try the code below which will put up a series of the basic Tkinter widgets. Try displaying different number of options for popup menus and radio buttons.

from Tkinter import *

root = Tk() # Get the root object from Tkinter

# Add a label to the dialog

TheLabel = Label(root, text="Hello, world!") 
TheLabel.pack() # Automatically position the item in the dialog

# Add a button to the dialog

TheButton = Button(root, text="A Button") 
TheButton.pack() 

# Add a check box

TheCheckBox = Checkbutton(root, text="A Check Box") 
TheCheckBox.pack() 

# Add a text entry widget

TheTextEntry = Entry(root)
TheTextEntry.pack()

# Add a list box

TheListBox = Listbox(root) # Add a list entry widget
TheListBox.pack()

for item in ["one", "two", "three", "four"]: # add four items to the list
    TheListBox.insert(END, item)

# Add a popup menu

TheSelection = StringVar(root)
TheSelection.set("one") # default value
    
ThePopupMenu = OptionMenu(root, TheSelection, "one", "two", "three")
ThePopupMenu.pack()

# Add a radio button group

TheRadioButtonSelected = StringVar()
TheRadioButtonSelected.set(1) # initialize

RadioButton1 = Radiobutton(root, text="One",variable=TheRadioButtonSelected, value=1)
RadioButton1.pack(anchor=W)
RadioButton2 = Radiobutton(root, text="Two",variable=TheRadioButtonSelected, value=2)
RadioButton2.pack(anchor=W)
RadioButton3 = Radiobutton(root, text="Three",variable=TheRadioButtonSelected, value=3)
RadioButton3.pack(anchor=W)

# A slider (scale bar)

TheScale= Scale(root, from_=0, to=100)
TheScale.pack()

# Loop until the user closes the dialog

root.mainloop() 

See the Introduction to Tkinter web site for more information.

A Dialog to Get a Value from the User

A regular problem that will arrise in Python programs is getting values from the user. The code below will display a dialog box and ask the user to enter a value. The value is then printed to "Debug I/O" but it could also be set to a global and then used later in the program. The dialog has been placed into a class to keep the code organized. This is a good practice and you can save the class to a module and use it in different Python programs you create. Try this code now and play around with chnage the names of the labels and buttons.

from Tkinter import *

class MyDialog:

    def __init__(self, master): # called when the object is created

        self.top=frame = Toplevel(master) # get the window "frame"
        #frame.pack() # size it

        Label(self.top, text="Value").pack() # add the label to the frame

        self.TheValue = Entry(self.top) # add the text entry box for the value
        self.TheValue.pack(padx=5) 

        OKButton= Button(self.top, text="OK", command=self.ok) # add the "OK" button
        OKButton.pack(pady=5)

    def ok(self): # Called when the "OK" button is pressed
        print("value is "+self.TheValue.get()) # print the value
        self.top.destroy() # Close the parent

TheRoot = Tk() # Get the root object for Tkinter
TheRoot.withdraw() # Don't show the modeless main window

TheDialog= MyDialog(TheRoot) # Create the Dialog Box

TheRoot.wait_window(TheDialog.top) # Wait until the window is closed

 

Positioning Widgets

I find that the automatic placement options in most languages do not give satisfactory results. Instead, you can place the widgets yourself using the "place()" function. You'll also need to set the minimum size of the window to make sure all the widgets are visible.

from Tkinter import *

root = Tk() # Get the root object from Tkinter

# Add a label to the dialog

TheLabel = Label(root, text="Enter a value:") 
TheLabel.place(x=1,y=5) # position the label in the upper left

# Add a text entry widget to the right of the label

TheTextEntry = Entry(root)
TheTextEntry.place(x=100,y=1) # position the bottom below it

# Add a check box

TheCheckBox = Checkbutton(root, text="A Check Box") 
TheCheckBox.place(x=10,y=40) # position the checkbox to the right

# Add a label to the dialog

TheLabel = Label(root, text="Select a value:") 
TheLabel.place(x=1,y=80) # position the label in the upper left

# Add a popup menu

TheSelection = StringVar(root)
TheSelection.set("one") # default value
    
ThePopupMenu = OptionMenu(root, TheSelection, "one", "two", "three")
ThePopupMenu.place(x=100,y=80) # position the bottom below it

# Add a button to the bottom of the dialog

TheButton = Button(root, text="A Button") 
TheButton.place(x=80,y=130) # position the bottom below it

# Loop until the user closes the dialog

root.wm_minsize(240,150) # set the minimum size of the dinwo
root.mainloop() 

Modeless Windows

Modeless windows allow the user to do other tasks while the window is being displayed.

It is rather easy to put up a modeless dialog in Tkinter:

from Tkinter import *

# Setup the GUI with a modeless window
root = Tk()
root.title("Blobs") # set the title of the window
root.resizable(0, 0) # create the window

root.mainloop()

Additional Resources:

Python Documentation: Classes

An Introduction to tkinter

Tkinter Reference: A GUI for Python