Read Programming Python Online

Authors: Mark Lutz

Tags: #COMPUTERS / Programming Languages / Python

Programming Python (55 page)

Chapter 8. A tkinter Tour, Part 1
“Widgets and Gadgets and GUIs, Oh My!”

This chapter is a continuation of our look at GUI programming in
Python. The previous chapter used simple widgets—buttons, labels, and the
like—to demonstrate the fundamentals of Python/tkinter coding. That was
simple by design: it’s easier to grasp the big GUI picture if widget
interface details don’t get in the way. But now that we’ve seen the
basics, this chapter and the next move on to present a tour of more
advanced widget objects and tools available in the tkinter library.

As we’ll find, this is where GUI scripting starts getting both
practical and fun. In these two chapters, we’ll meet classes that build
the interface devices you expect to see in real programs—e.g., sliders,
check buttons, menus, scrolled lists, dialogs, graphics, and so on. After
these chapters, the last GUI chapter moves on to present larger GUIs that
utilize the coding techniques and the interfaces shown in all prior GUI
chapters. In these two chapters, though, examples are small and
self-contained so that we can focus on widget details.

This Chapter’s Topics

Technically, we’ve already used a handful of simple widgets in
Chapter 7
. So far we’ve met
Label
,
Button
,
Frame
, and
Tk
, and studied
pack
geometry management concepts along the
way. Although all of these are basic, they represent tkinter interfaces
in general and can be workhorses in typical GUIs.
Frame
containers, for instance, are the basis
of hierarchical display layout.

In this and the following chapter, we’ll explore additional
options for widgets we’ve already seen and move beyond the basics to
cover the rest of the tkinter widget set. Here are some of the widgets
and topics we’ll explore in this chapter:

  • Toplevel
    and
    Tk
    widgets

  • Message
    and
    Entry
    widgets

  • Checkbutton
    ,
    Radiobutton
    , and
    Scale
    widgets

  • Images:
    PhotoImage
    and
    BitmapImage
    objects

  • Widget and window configuration options

  • Dialogs, both standard and custom

  • Low-level event binding

  • tkinter linked variable objects

  • Using the Python Imaging Library (PIL) extension for other
    image types and
    operations

After this chapter,
Chapter 9
concludes the two-part tour by presenting the remainder of the tkinter
library’s tool set: menus, text, canvases, animation, and more.

To make this tour interesting, I’ll also introduce a few notions
of component reuse along the way. For instance, some later examples will
be built using components written for prior examples. Although these two
tour chapters introduce widget interfaces, this book is also about
Python programming in general; as we’ll see, tkinter programming in
Python can be much more than simply drawing circles and arrows.

Configuring Widget Appearance

So far, all the buttons
and labels in examples have been rendered with a default
look-and-feel that is standard for the underlying platform. With my
machine’s color scheme, that usually means that they’re gray on Windows.
tkinter widgets can be made to look arbitrarily different, though, using a
handful of widget and packer options.

Because I generally can’t resist the temptation to customize widgets
in examples, I want to cover this topic early on the tour.
Example 8-1
introduces some of the
configuration options available in tkinter.

Example 8-1. PP4E\Gui\Tour\config-label.py

from tkinter import *
root = Tk()
labelfont = ('times', 20, 'bold') # family, size, style
widget = Label(root, text='Hello config world')
widget.config(bg='black', fg='yellow') # yellow text on black label
widget.config(font=labelfont) # use a larger font
widget.config(height=3, width=20) # initial size: lines,chars
widget.pack(expand=YES, fill=BOTH)
root.mainloop()

Remember, we can call a widget’s
config
method
to reset its options at any time, instead of passing all of
them to the object’s constructor. Here, we use it to set options that
produce the window in
Figure 8-1
.

Figure 8-1. A custom label appearance

This may not be completely obvious unless you run this script on a
real computer (alas, I can’t show it in color here), but the label’s text
shows up in yellow on a black
background
, and with a font that’s very
different from what we’ve seen so far. In fact, this script
customizes the label in a number of ways:

Color

By setting the
bg
option of
the label widget here, its background is displayed in
black; the
fg
option
similarly changes the foreground (text) color of the
widget to yellow. These color options work on most tkinter widgets
and accept either a simple color name (e.g.,
'blue'
) or a hexadecimal string. Most of
the color names you are familiar with are supported (unless you
happen to work for Crayola). You can also pass a hexadecimal color
identifier string to these options to be more specific; they start
with a
#
and name a color by its
red, green, and blue saturations, with an equal number of bits in
the string for each. For instance,
'#ff0000'
specifies eight bits per color
and defines pure red; “f” means four “1” bits in hexadecimal. We’ll
come back to this hex form when we meet the color selection dialog
later in this chapter.

Size

The label is
given a preset size in lines high and characters wide
by setting its
height
and
width
attributes. You can use
this setting to make the widget larger than the tkinter geometry
manager would by default.

Font

This script specifies a
custom font for the label’s text by setting the
label’s
font
attribute to a
three-item tuple giving the font family, size, and style (here:
Times, 20-point, and bold). Font style can be
normal
,
bold
,
roman
,
italic
,
underline
,
overstrike
, or combinations of these
(e.g., “bold italic”). tkinter guarantees that
Times
,
Courier
, and
Helvetica
font family names exist on all
platforms, but others may work, too (e.g.,
system
gives the system font on Windows).
Font settings like this work on all widgets with text, such as
labels, buttons, entry fields, listboxes, and
Text
(the latter of which can even display
more than one font at once with “tags”). The
font
option still accepts older
X-Windows-style font indicators—long strings with dashes and
stars—but the newer tuple font indicator form is more platform
independent.

Layout and expansion

Finally, the label is
made generally expandable and stretched by setting the
pack expand
and
fill
options we met in the last chapter;
the label grows as the window does. If you maximize this window, its
black background fills the whole screen and the yellow message is
centered in the middle; try it.

In this script, the net effect of all these settings is that this
label looks radically different from the ones we’ve been making so far. It
no longer follows the Windows standard look-and-feel, but such conformance
isn’t always important. For reference, tkinter provides additional ways to
customize appearance that are not used by this script, but which may
appear in others:

Border and relief

A
bd=
N
widget option
can be used to set border width, and a
relief=
S
option can specify a border style;
S
can
be
FLAT
,
SUNKEN
,
RAISED
,
GROOVE
,
SOLID
, or
RIDGE
—all constants exported by the
tkinter module.

Cursor

A
cursor
option can be
given to
change the appearance of the mouse pointer when it
moves over the widget. For instance,
cursor='gumby'
changes the pointer to a
Gumby figure (the green kind). Other common cursor names used in
this book include
watch
,
pencil
,
cross
, and
hand2
.

State

Some widgets also
support the notion of a state, which impacts their
appearance. For example, a
state=DISABLED
option will generally
stipple (gray out) a widget on screen and make it unresponsive;
NORMAL
does not. Some widgets
support a
READONLY
state as well,
which displays normally but is unresponsive to changes.

Padding

Extra space can be
added around many widgets (e.g., buttons, labels, and
text) with the
padx=
N
and
pady=
N
options. Interestingly, you can set these options both in
pack
calls (where it adds empty space
around the widget in general) and in a widget object itself (where
it makes the widget larger).

To illustrate some of these extra settings,
Example 8-2
configures the custom
button captured in
Figure 8-2
and changes
the mouse pointer when it is positioned above it.

Figure 8-2. Config button at work

Example 8-2. PP4E\Gui\Tour\config-button.py

from tkinter import *
widget = Button(text='Spam', padx=10, pady=10)
widget.pack(padx=20, pady=20)
widget.config(cursor='gumby')
widget.config(bd=8, relief=RAISED)
widget.config(bg='dark green', fg='white')
widget.config(font=('helvetica', 20, 'underline italic'))
mainloop()

To see the effects generated by these two scripts’ settings, try out
a few changes on your computer. Most widgets can be given a custom
appearance in the same way, and we’ll see such options used repeatedly in
this text. We’ll also meet operational configurations, such as
focus
(for focusing input) and others. In fact,
widgets can have dozens of options; most have reasonable defaults that
produce a native look-and-feel on each windowing platform, and this is one
reason for tkinter’s simplicity. But tkinter lets you build more custom
displays when you
want to.

Note

For more on ways to apply configuration options to provide common
look-and-feel for your widgets, refer back to
Customizing Widgets with Classes
, especially its
ThemedButton
examples. Now that you know more
about configuration, its examples’ source code should more readily show
how configurations applied in widget subclasses are automatically
inherited by all instances and subclasses. The new
ttk
extension described in
Chapter 7
also provides additional ways to
configure widgets with its notion of themes; see the preceding chapter
for more details and resources on ttk.

Other books

Waiting Spirits by Bruce Coville
Nicole Kidman: A Kind of Life by James L. Dickerson
The Passport by Herta Muller
Zombie Fallout by Mark Tufo
La gran caza del tiburón by Hunter S. Thompson
The Mephistophelean House by Benjamin Carrico


readsbookonline.com Copyright 2016 - 2024