16.1 Tkinter Fundamentals

The Tkinter module makes it easy to build simple GUI applications. You simply import Tkinter, create, configure, and position the widgets you want, and then enter the Tkinter main loop. Your application becomes event-driven, which means that the user interacts with the widgets, causing events, and your application responds via the functions you installed as handlers for these events.

The following example shows a simple application that exhibits this general structure:

import sys, Tkinter
Tkinter.Label(text="Welcome!").pack(  )
Tkinter.Button(text="Exit", command=sys.exit).pack(  )
Tkinter.mainloop(  )

The calls to Label and Button create the respective widgets and return them as results. Since we specify no parent windows, Tkinter puts the widgets directly in the application's main window. The named arguments specify each widget's configuration. In this simple case, we don't need to bind variables to the widgets. We just call the pack method on each widget, handing control of the widget's geometry to a layout manager object known as the packer. A layout manager is an invisible component whose job is to position widgets within other widgets (known as container or parent widgets), handling geometrical layout issues. The previous example passes no arguments to control the packer's operation, so therefore the packer operates in a default way.

When the user clicks on the button, the command callable of the Button widget executes without arguments. The example passes function sys.exit as the argument named command when it creates the Button. Therefore, when the user clicks on the button, sys.exit( ) executes and terminates the application (as covered in Chapter 8).

After creating and packing the widgets, the example calls Tkinter's mainloop function, and thus enters the Tkinter main loop and becomes event-driven. Since the only event for which the example installs a handler is a click on the button, nothing happens from the application's viewpoint until the user clicks the button. Meanwhile, however, the Tkinter toolkit responds in the expected way to other user actions, such as moving the Tkinter window, covering and uncovering the window, and so on. When the user resizes the window, the packer layout manager works to update the widgets' geometry. In this example, the widgets remain centered, close to the upper edge of the window, with the label above the button.

All strings going to or coming from Tkinter are Unicode strings, so be sure to review Section 9.6 in Chapter 9 if you need to show, or accept as input, characters outside of the ASCII encoding (you may then need to use some other appropriate codec).

Note that all the scripts in this chapter are meant to be run standalone (i.e., from a command line or in a platform-dependent way, such as by double clicking on a script's icon). Running a GUI script from inside another program that has its own GUI, such as a Python integrated development environment (e.g., IDLE or PythonWin), can cause various anomalies. This can be a particular problem when the GUI script attempts to terminate (and thus close down the GUI), since the script's GUI and the other program's GUI may interfere with each other.

Note also that this chapter refers to several all-uppercase, multi-letter identifiers (e.g., LEFT, RAISED, ACTIVE). All these identifiers are constant attributes of module Tkinter, used for a wide variety of purposes. If your code uses from Tkinter import *, you can then use the identifiers directly. If your code uses import Tkinter instead, you need to qualify those identifiers, just like all others you import from Tkinter, by preceding them with 'Tkinter.'. Tkinter is one of the rare Python modules designed to support from Tkinter import *, but of course you may choose to use import Tkinter anyway, sacrificing some convenience and brevity in favor of greater clarity. A good compromise between convenience and clarity is often to import Tkinter with a shorter name (e.g., import Tkinter as Tk).

    Part III: Python Library and Extension Modules