The programs we have written so far are text-based. Each program accepts character data from the keyboard, and produces textual output to the screen. While this can be quite useful, most current computer users are far more familiar with the Graphical User Interface (GUI), which presents buttons and menus which the user can manipulate using the mouse pointer. In this lesson, we'll write a few of these using Python.
An interface is where two things come together and interact; in this case, the program and the human being. The program is still doing the same sorts of things inside. (So, presumably, is the human being.) The difference is the method of interaction. GUIs are used because they are usually easier for humans. For the machine, GUIs require more computational resource, and are generally more difficult to program. But, as Mark Weiser was fond of saying, "Computers should work. People should play." So, off we go to GUI land.
As usual, start Idle.
Now, we'll not just dive right in. First, a bit more on functions. What we told you about function parameters in Lesson 3 was the truth, and nothing but the truth. But not the whole truth. Here comes a bit more of it. Enter and run the following program:
As you can see, a parameter can be given a default value. When you call the function without an argument for that parameter, the extras take their defaults. It is also possible use the parameter names to specify where to send any particular argument, as demonstrated in the last two calls.
Okay, now we can dig in and get our fingers GUI. Enter the following program and follow the instructions.
.pyw
, not .py
.
This program introduces a number of new concepts,
which will need dissecting.
In previous lessons, we've seen some Python types: integer,
float, string and boolean. Variables can contain
data of any type, but what you can do with the variables
depends on that type. Integers can be added; strings can be
concatenated. You can use square brackets to select a character
from a string, but not from an integer. And so forth.
None of the variables in this program contain those types of data.
The variable root
is a window, lab
is a label (text that
appears in a window), and but
is a button.
These are all types which are created by the Tkinter
library. Collectively, these variables are all known as objects,
and they have object types.
For our purposes, objects are variables which have some
type defined in a library. (Object types can be created in
an ordinary program as well, but we won't pursue that.)
Just as with basic types, the things you can do with an object
depend on the type of the object.
Here's what the statements do:
The first line is an import
statement (even though
it starts with the word from
).
We won't be trying to build our own import statements, so we'll
skip the details.
What it does is tell Python to use the contents of a library
called Tkinter
. Libraries are collections of
functions and other program code
which programmers have created and stored in a file.
A library is a programmer's toolbox. Each
library generally holds tools specialized for a specific task.
The Tkinter
library provides tools for creating a GUI.
This a call of the zero-argument function Tk
which
comes from the Tkinter
library.
Tk()
creates an empty window and returns it,
where it is stored in the variable root
.
This adds a label to the empty window root
. Again,
Label
is a function from Tkinter
, and it returns the
label object which it creates. The Label
function
takes a parameter to tell what window the label is on,
and has many other parameters provided with default values.
As you see,
we have sent an argument for one of these parameters using its
name.
This makes the label actually appear on the window, and
tells where to put it. Tkinter
arranges the
parts of the window in a grid,* starting with 0, 0
in the upper left corner. This small example has one column
and two rows.
This creates the button and makes it appear below the label.
The parameter command
is a function
to call when the button is pressed. The Tkinter
package
waits for the button press, and calls the specified function
for us when that happens.
This essentially tells the window that you are done
constructing your GUI, and the system should activate it.
The mainloop
function tells the computer's windowing system to display
your window, then waits for mouse clicks and acts on them.
Tkinter
refers collectively to the objects which make
up the contents of the window, buttons, labels and such,
as widgets.†
As you can see,
the function changelab
is not called anywhere in the program.
Instead, we send the name changelab
to the button object through
the command
parameter. When the button is pressed, the button
object calls it for us. This is an example of
event-driven programming. The function is executed in
response to an event (the mouse click) initiated by the user.
When the program first runs, you see the various widgets you
created. When
you press the button, the button object calls changelab
which
modifies the text on the label. You can observe the change in the window.
Changelab
does its work by running configure
on the label
object stored in lab
.
Configure
is a function which
is part of the button object type, called a method.
Methods are defined when a programmer creates an object type;
they are part of what you can do with objects of that type.
As shown, configure
lets you change things about the label widget
(its properties), including the text it displays.
configure
method. You may choose
any new text you like.
Here's a more colorful version of the above example. Please modify your program to look like this, and run it again.
Tkinter
widgets possess. All the new attributes shown
here are cosmetic: they change the appearance, not behavior, of the widget.
Here's the scoop:
columnspan=2
so that it will fill the
entire first row. (Note that you need to spell out
columnspan
; colspan
won't work.)
bg
attribute
stands for background, and sets the background color. The fg
stands for foreground, and sets the color of the lettering in the
button or label. The activebackground
option sets the
background color when the mouse is over the object.
The colors can be specified by name, or numerically
as in HTML.
sticky
attribute to grid
makes the object
stick to the listed sides, denoted by compass points. The n
for
north means the top, the e
for east means the right, the
w
for west means the left, and s
for south means the bottom.
"Stick to" means that the widget contents will be moved to that
side of its grid cell. If the sticky option specifies
opposite sides, the contents
will be stretched to fill in both directions.
The compass points may be listed in any order.
The example gives all four points, which
causes the widget to fill its grid cell.
This is a very common use of sticky
.
relief
attribute controls how the object
is displayed, particularly the shadow used to give an
appearance of depth.
The default for buttons is raised
, by which
they appear to protrude from the screen. Other legal values are
sunken
, flat
, ridge
, solid
and groove
.
If you can't guess what one of those does, feel free to try it and see.
Exit
button calls stop
, which calls
root.quit()
, which does exactly that.
After you run the program once, take the
sticky='news' away from each button, and run it
again to see the difference. While you're at it, maybe try some
other relief
values.
command
function which
uses configure
to set everything back. Set its text and
colors to appropriate values.
Here's perhaps a better way to this. Please enter and
save this program and run it. Again, save it on
the desktop with a .pyw
ending.
Notice that this one uses an additional library,
tkMessageBox
, from which come
the showwarning
and askokcancel
dialog functions.
Each of these takes two strings and creates a dialog window.
(Notice where each string is displayed on the window.)
These are modal dialogs, which means
that you are forced to respond to the dialog window first, because
the main window ignores all your clicking while the
dialog is displayed.
Our button functions, warn
and stop
, respectively call
the showwarning
and askokcancel
.
Showwarning
just waits until you
click OK. The confirmation dialog displayed by askokcancel
returns a boolean, which is true if the user presses OK, and
false if the presses Cancel.. The code then uses this response to
decide to run quit or not.
These are some of the simplest
dialogs provided by tkMessageBox
and some other
dialog libraries.
Some ask yes/no questions, or questions with more alternatives.
Others ask for strings or numbers, select colors or choose files.
warn
function so that after the
warning dialog is closed it does the following:
askyesno
dialog, which is used just like
askokcancel
, but it shows Yes and No buttons. The
function returns true when the user chooses Yes, and
false for No.
Here's a program for temperature conversions.
Enter it in a new file window, and save it on the desktop
with a .pyw
ending.
Here are the new features demonstrated in this example:
root.title()
call takes a string which it displays
on the frame of the main window. Notice that when the
program runs, you see Temp Conversion on the window border instead
of Tk.
anchor
attribute is used to move the text of a
widget to a side of its area. It is similar to the sticky
option to grid
, except it does not allow
stretching. It takes a list of compass points, but you may
only specify a single side, such as w
for the left, or
a corner, such ne
for the upper right.
This example always grids with sticky='news' so
the background color will stretch to fill the grid cell, then sometimes uses
anchor
to position the contents as desired.
Entry
widget.
See below for more on how this is used.
The function
mkgrid
is a minor convenience. It takes the row, column,
and an object, grids the object there with sticky='news', then
returns it. This saves typing a separate grid line and makes
creating new widgets a little simpler.
The box in which you enter the Fahrenheit temperature is
the entry widget stored in the variable ftmp
.
An entry widget lets you enter and edit whatever you
like, and remembers what you typed.
Pressing the Compute Celsius button calls the findcel
function,
which uses the method ftmp.get()
to ask the
entry object what you have typed. It then tells the
label cent
to display the equivalent Celsius temperature.
If you entered nothing, it sets a blank, otherwise it
computes the correct value. The entry delivers a string,
so we use the built-in float
function to convert to floating point.
Likewise, configure
wants a string for the text
attribute, and the built-in str
function
will provide that from the floating point number we compute.
The color scheme for this
window uses various blues. We start out the program by setting the
variables mainbg
and activebg
to two light blue shades used
for backgrounds. These are ordinary variables set to string values.
They are colors only because they repeatedly appear with bg=
and
activebackground=
when creating other widgets.
The label cent
is designed to look like an entry to give the
overall window a symmetrical appearance.
This is done by setting the relief
and anchor
to values
which are defaults for an entry.
In the upper right corner is a label with blank text. Its only purpose is to provide the background color in that grid slot.
Examine the program so that you understand how it works. Experiment a bit to help you understand. Make each of these changes, run the program, then return to the original.
mkgrid
to
sticky='w' to see how that changes the appearance of the
window.
mkgrid
is used, and modify the program to create
the cent
label without using mkgrid
. Remove the existing call,
and replace it with the plain Label
call followed by a grid
call, such that the program behaves the same way.
mainbg
and
activebg
. Choose light colors so the lettering remains
readable.
fg
property to
your new variable, just as the existing ones have bg
and
activebackground
set.
Try running with several different foreground
colors to see if your change is effective. Then redesign the
color scheme to your liking, making sure to retain good contrast.
ftmp.delete(0, END)
.
The delete
method allows you delete any of the characters in the
entry; this form wipes 'em all. To clear the label, just
configure
with a text=''.
cent
which displays
the compute Celsius temperature to be an entry. Add a
Compute Fahrenheit button which will take the Celsius temperature
and compute an equivalent Fahrenheit one. The
reverse formula is f = 1.8c + 32. Each compute function
will be setting its result into an entry instead of a label. To do
this, first clear the entry as shown in the previous item, then
set the new value with something of the form
lab.insert(0,
newvalue)
. You will also
need to modify your clear button function.
Tkinter
has many more widgets, including large text areas,
various menus, checkboxes, radio buttons, sliders and canvases for displaying
arbitrary images. It is a very rich set of tools, of which we have
provided only a taste. But that's all we set out to do.
This reference has a rather complete list of the available widgets, their attributes, and various methods to manipulate them.
Phone List ExampleThis is a short tutorial which takes you through the construction of a simple phone book program. It introduces a number of Tkinter features which we have not examined.
Tkinter Life PreserverThese are excellent tutorials on Tkinter. You will need to learn a bit about Python classes to get the most from them.
*In fact, there are some
alternatives to grid
layout.
†This term is used by Tkinter and some other GUI systems which have roots in the Unix-based X-Window system created at MIT during the 1980s. Other GUI implementations use some far more boring term, such as Java's component.
Copyright 2005, 2006
Thomas W Bennet •
Image Credits
•
Terms of use:
Creative
Commons