Python DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


Python Programming on Win32 using Tkinter
Pages: 1, 2, 3

Widgets

Core widgets

Tkinter implements a fairly small set of core widgets, from which other widgets or complete applications can be based. Table 20-1 lists these core widgets with a short description of how they are used.

Table 20-1: Core Tkinter Widgets

Widget Name

Description

Toplevel

Toplevel widgets are special in that they have no master widget and don't support any of the geometry-management methods (as discussed later). All other widgets are directly or indirectly associated with a Toplevel widget.

Frame

Used as a container widget for other child widgets. For instance, the tkDemo example consists of a number of frames within frames within frames to achieve its particular layout.

Label

Displays text or images.

Message

Displays text with automatic line-break and justification capabilities.

Text

Displays text with advanced formatting, editing, and highly interactive capabilities.

Canvas

Displays graphical items from a display list, with highly interactive capabilities.

Button
Checkbox
Entry
Scale
Radiobutton
List box
Scrollbar

Standard simple entry widgets, also known as the control widgets.

Menu
Menubutton

Widgets for implementing and responding to menus.

Quite a few of these widgets are demonstrated in the tkBrowser sample, and every one gets an exercise in the tkDemo sample, so you are encouraged to experiment with these samples to get a feel for the capabilities of each widget. Of these widgets, we will discuss two of the most popular and powerful in more detail: the Text and Canvas widgets.



The Text widget provides for the display and editing of text, as you would expect from a text control. The Text widget is also capable of supporting embedded images and child windows, but the real power of the text control can be found in its support of indexes, tags, and marks:

Indexes
Indexes provide a rich model for describing positions in the text control. The position specification can be in terms of line and column position (relative or absolute), pixel position, special system index names, and so forth.

Tags
Tags are an association between a name and one or more regions of text. There is no restriction on overlapping regions, so a character may belong to any number of tags, and tags can be created and destroyed dynamically. In addition, the text associated with a tag may be given any number of display characteristics (such as font, color specifications, and so forth). When we combine these capabilities with the Tkinter event model described later, it becomes easy to build highly interactive applications (such as a web browser) around this Text widget.

Marks
A mark is a single position within the text (or more accurately, a position between two characters). Marks flow naturally with the surrounding text as characters are inserted and deleted, making them particularly suitable for implementing concepts such as bookmarks or breakpoints. Tkinter manages a number of predefined marks, such as insert, which defines the current insertion point.

The Canvas widget displays graphical items, such as lines, arcs, bitmaps, images, ovals, polygons, rectangles, text strings, or arbitrary Tkinter widgets. Like the Text widget, the Canvas widget implements a powerful tagging system, allowing you to associate any items on the canvas with a name.

Dialog and other noncore widgets

Many useful widgets are actually built from the core widgets. The most common example is the dialog widget, and recent versions of Tkinter provide some new sophisticated dialog widgets similar to the Windows common dialogs. In many cases when running on Windows, the standard Windows dialog is used.

Many of these dialogs come in their own module. Table 20-2 lists the common dialog box modules and their functionality.

Table 20-2: Tkinter Common Dialog Box Modules

Module Name

Description

tkMessageBox

Simple message box related dialogs, such as Yes/No, Abort/Retry/Ignore, and so forth.

tkSimpleDialog

Contains base classes for building your own dialogs, and also includes a selection of simple input dialogs, such as asking for a string, integer, or float value.

tkFileDialog

A dialog with functionality very close to the Windows common file dialogs.

tkColorChooser

A dialog for choosing a color.

There are many other widgets available; both included with the Tkinter package, and also available externally. One interesting and popular source of Tkinter widgets can be found in the Python megawidgets (Pmw) package. This package comes with excellent documentation and sample code and can be found at http://www.dscpl.com.au/pmw/.

In most cases, you build your own dialogs by deriving them from the tkSimpleDialog.Dialog. Our tkBrowser sample defines an EditTransaction class that shows an example of this.

Widget properties and methods

Tkinter provides a flexible and powerful attribute set for all widgets. Almost all attributes can be set at either widget-creation time or once the widget has been created and displayed. Although Tkinter provides obvious attributes for items such as the color, font, or visible state of a widget, the set of enhanced attributes for widgets is usually the key to tapping the full potential of Tkinter.

Tkinter makes heavy use of Python keyword arguments when specifying widget attributes. A widget of any type (for instance a Label) is constructed with code similar to:

w = Label(master, option1=value1, option2=value2,...)

And once constructed, can be reconfigured at any time with code like:

w.configure(option1=value1, option2=value2, ...)

For a specific example, you can create a label with the following code:

label = Label(parent, background='white', 
                      text='Hello World!',
                      relief=RAISED, 
                      borderwidth=3)

And provide an annoying blinking effect by periodic execution of:

label.configure(background='red')

And:

label.configure(background='white')

There are dozens of options that can be specified for each widget. Table 20-3 lists a few common properties available for each widget.

Table 20-3: Common Tkinter Widget Properties

Property

Description

height
width

The height and width of the widget in pixels.

background
foreground

The color of the widget as a string. You can specify a color by name (for example, red or light blue), or you can specify each of the RGB components in hexadecimal notation prefixed with a # (e.g., #ffffff for white).

relief

A 3D appearance for the object (RAISED, SUNKEN, RIDGE, or GROOVE) or a 2D appearance (FLAT or SOLID).

borderwidth

Width of the border, in pixels.

text wrap
justify

The Window text (i.e., the caption) for the widget and additional formatting options for multiline widgets.

font

The font that displays the text. This can be in a bewildering array of formats: some platform-independent and some platform-dependent. The most common form is a tuple containing font name, point size, and style (for example, ("Times", 10, "bold"). Tkinter guarantees that the fonts Times, Helvetica, and Courier exist on all platforms, and styles can be any combination of bold, roman, italic, underline, and overstrike, which are always available, with Tkinter substituting the closest matching font if necessary.

command
variable

Techniques used by control widgets to communicate back to the application. The command option allows you to specify an arbitrary Python function (or any callable Python object) to be invoked when the specified action occurs (e.g., when a Button widget is pushed). Alternatively, several widgets take the variable option and, if specified, must be an instance of one of the StringVar, IntVar, DoubleVar, or BooleanVar classes (or subclass). Once set up, changes to the widget are immediately reflected in the object, and changes in the object are immediately reflected to the widget. This is demonstrated in tkBrowser.py in a number of places including the EditTransaction class, which uses this technique for managing the data shown in the dialog.

There are also dozens of methods available for each widget class, and the Tkinter documentation describes these in detail, but there is one important method we mention here because it's central to the Tkinter event model.

The bind() method is simple, but provides an incredible amount of power by allowing you to bind a GUI event to a Python function. It takes two parameters, the event you wish to bind to (specified as a string) and a Python object to be called when the event fires.

The power behind this method comes from the specification of the event. Tkinter provides a rich set of events, ranging from keyboard and mouse actions to Window focus or state changes. The specification of the event is quite intuitive (for example, <Key> binds any key, <Ctrl-Alt-Key-Z> is a very specific key, <Button-1> is a the first mouse-button click, and so forth) and covers over 20 basic event types. You should consult the Tkinter reference guides for a complete set of events supported by Windows and a full description of the Tkinter event model.

Geometry Management

Tkinter provides a powerful concept typically not found in Windows GUI toolkits, and that is geometry management. Geometry management is the technique used to lay out child widgets in their parent (for example, controls in a dialog box). Most traditional Windows environments force you to specify the absolute position of each control. Although this is specified in dialog units rather than pixels and controls can be moved once created, Tkinter provides a far more powerful and flexible model.

Tkinter widgets provide three methods for geometry management, pack(), grid(), or place().

place() is the simplest mechanism and similar to what most Windows users are used to; each widget has its position explicitly specified, either in absolute or relative coordinates. The grid() mechanism, as you may expect, automatically aligns the widgets in a grid pattern, while the pack() method is the most powerful and the most commonly used. When widgets are packed, they are automatically positioned based on the size of the parent and the other widgets already placed. All of these techniques allow customization of the layout process, such as the padding between widgets.

These geometry-management capabilities allow you to define user interfaces that aren't tied to particular screen resolutions and can automatically resize and layout controls as the window size changes, capabilities that most experienced Windows user-interface programmers will know are otherwise difficult to achieve. Our two samples (described next) both make extensive use of the pack() method, while the tkDemo sample also makes limited use of grid().

Tkinter Sample Code

We have included a sample Doubletalk browser written in Tkinter. This is a fully functional transaction viewer and editor application and is implemented in tkBrowser.py. This implements a number of features that demonstrate how to build powerful applications in Tkinter. A number of dialogs are presented, including the transaction list, and the detail for each specific transaction. To show how simple basic drawing and charting is, a graphical view of each account is also provided. Rather than labor over the details of this sample, the best thing to do is just to run it. Then once you have a feel for the functionality, peruse the source code to see the implementation. There are ample comments and documentation strings included less than 700 lines of source. Figure 20-4 shows our final application in action.

Figure 20-4. The Tkinter Doubletalk browser in action

 

The second sample is TkDemo.py, which is a demonstration of all the Tkinter core widgets. It is highly animated and provides a good feel for the basic operation of these widgets.

As mentioned previously, Tkinter is the standard GUI for Python applications, therefore you can find a large number of resources both in the standard Python documentation and referenced via the Python web site.

Tkinter Conclusion

Tkinter is excellent for small, quick GUI applications, and since it runs on more platforms than any other Python GUI toolkit, it is a good choice where portability is the prime concern.

Obviously we haven't been able to give Tkinter the depth of discussion it warrants, but it's fair to say that almost anything that can be done using the C language and Tk can be done using Python and Tkinter. One example is the Python megawidgets (PMW) package mentioned previously; this is a pure Python package that creates an excellent widget set by building on the core Tkinter widgets.

To learn more about any of the Tkinter topics discussed here, you may like to refer to the following sources:

  • The standard Python documentation is optionally installed with Python on Windows and is also available online at http://www.python.org/doc.
  • PythonWare and Fredrik Lundh provide excellent Tkinter resources, including tutorials available at http://www.pythonware.com.
  • Tcl and Tk are developed and supported by the Scriptics Corporation, which can be found at http://www.scriptics.com. Tcl and Tk documentation is available from http://www.scriptics.com/resource/doc/. O'Reilly has an excellent book on the subject, Tcl/Tk in a Nutshell by Paul Raines and Jeff Trantor.
  • Python megawidgets are available via http://www.dscpl.com.au/pmw/.
  • Keep your eye out for O'Reilly's Tkinter Programming by Fredrik Lundh.

Mark Hammond is an independent Microsoft Windows consultant working out of Melbourne, Australia.

Andy Robinson is a London-based consultant specializing in business analysis, object-oriented design, and Windows development.


Discuss this article in the O'Reilly Network Python Forum.

Return to the Python DevCenter.





Sponsored by: