In the earlier chapter on network programming, we introduced
the notion of client/server computing. A windowing system is another example of
a software server. These run on a machine with an attached display, such as a
monitor of some sort. There are clients, tooprograms that require a windowing
environment to execute, also known as GUI applications. Such applications cannot
run without a windows system.
The architecture becomes even more interesting when networking
comes into play. Usually when a GUI application is executed, it displays to the
machine that it started on (via the windowing server), but it is possible in
some networked windowing environments, such as the X Window system on Unix, to
choose another machine's window server to display to. In such situations, you
can be running a GUI program on one machine, but have it displayed on
another!
Introduction to GUI Programming
Before going to the examples, we will give you a brief
introduction to GUI application development in general. This will provide you
with some of the background you need to move forward.
Setting up a GUI application is similar to an artist's
producing a painting. Conventionally, there is a single canvas onto which the
artist must put all the work. The way it works is like this: You start with a
clean slate, a "top-level" windowing object on which you build the rest of your
components. Think of it as a foundation to a house or the easel for an artist.
In other words, you have to pour the concrete or set up your easel before
putting together the actual structure or canvas on top of it. In Tkinter, this
foundation is known as the top-level window object.
In GUI programming, a top-level root windowing object contains
all of the little windowing objects that will be part of your complete GUI
application. These can be text labels, buttons, list boxes, etc. These
individual little GUI components are known as widgets. So when we say create a top-level window, we
just mean that you need such a thing as a place where you put all your widgets.
In Python, this would typically look like this line:
top = Tkinter.Tk() # or just Tk() with "from Tkinter import *"
The object returned by
Tkinter.Tk() is usually
referred to as the
root window, hence the reason
why some applications use
root rather than
top to indicate as
such. Top-level windows are those that show up standalone as part of your
application. You may have more than one top-level window for your GUI, but only
one of them should be your root window. You may choose to completely design all
your widgets first, then add the real functionality, or do a little of this and
a little of that along the way. (This means mixing and matching
steps 3 and
4 from
our list.)
Widgets may be standalone or be containers. If a widget
"contains" other widgets, it is considered the
parent of those widgets. Accordingly, if a widget
is "contained" in
another widget, it's considered a
child of the
parent, the parent being the next immediate enclosing container widget.
Usually, widgets have some associated behaviors, such as when a
button is pressed, or text is filled into a text field. These types of user
behaviors are called events, and the actions that
the GUI takes to respond to such events are known as callbacks.
Actions may include the actual button press (and release),
mouse movement, hitting the RETURN or Enter key, etc. All of these are known to
the system literally as events. The entire system
of events that occurs from the beginning to the end of a GUI application is what
drives it. This is known as event-driven processing.
One example of an event with a callback is a simple mouse move.
Let's say the mouse pointer is sitting somewhere on top of your GUI application.
If the mouse is moved to another part of your application, something has to
cause the movement of the mouse on your screen so that it looks as if it is moving to another location. These are
mouse move events that the system must process to give you the illusion (and
reality) that your mouse is moving across the window. When you release the
mouse, there are no more events to process, so everything just sits there
quietly on the screen again.
The event-driven processing nature of GUIs fits right in with
client/server architecture. When you start a GUI application, it must perform
some setup procedures to prepare for the core execution, just as when a network
server has to allocate a socket and bind it to a local address. The GUI
application must establish all the GUI components, then draw (aka render or
paint) them to the screen. Tk has a couple of geometry managers that help
position the widget in the right place; the main one that you will use is called
Pack, aka the packer. Another geometry manager is
Gridthis is where you specify GUI widgets to be placed in grid coordinates, and
Grid will render each object in the GUI in their grid position. For us, we will
stick with the packer.
Once the packer has determined the sizes and alignments of all
your widgets, it will then place them on the screen for you. When all of the
widgets, including the top-level window, finally appear on your screen, your GUI
application then enters a "server-like" infinite loop. This infinite loop
involves waiting for a GUI event, processing it, then going back to wait for the
next event.
The final step we described above says to enter the main loop
once all the widgets are ready. This is the "server" infinite loop we have been
referring to. In Tkinter, the code that does this is:
This is normally
the last piece of sequential code your program runs. When the main loop is
entered, the GUI takes over execution from there. All other action is via
callbacks, even exiting your application. When you pull down the File menu to
click on the Exit menu option or close the window directly, a callback must be
invoked to end your GUI application.
Top-Level Window: Tkinter.Tk()
We mentioned above that all main widgets are built into the
top-level window object. This object is created by the Tk class in
Tkinter and is created via the normal instantiation:
>>> import Tkinter
>>> top = Tkinter.Tk()
Within this window, you place individual widgets or
multiple-component pieces together to form your GUI. So what kinds of widgets
are there? We will now introduce the Tk widgets.