Chapter 5. Label and Entry Widgets

Contents:

There are times you'll want users to type in specific
information, such as their names, addresses, or even serial numbers.
The simplest way to do this is to use Entry widgets. You can use a
Label widget with an Entry to clearly communicate to the user what
should be typed in the Entry. Most often, you'll see the Label
and Entry combination used multiple times in a database Entry-type
window where there are many different pieces of information the user
must enter.

5.1. The Label Widget

A Label is
like a Button that doesn't do anything. It is a noninteractive
widget and by default cannot have the keyboard focus (meaning you
can't tab to it). It does nothing when you click on it (see
Figure 5-1).

Figure 5-1. Label widget

Excluding Frame-like widgets, the Label is the simplest widget. It is
similar to a Button in that it can show text (or a bitmap), have
relief (default is flat), display multiple lines
of text, have a different font, and so on. Figure 5-2 shows a simple window, with both a Button and
Label, created with this code:

Figure 5-2. A simple window with Label and Button

Put a Label to the left of an Entry widget so the user knows what
type of data is expected.

Put a Label above a group of Radiobuttons to clarify its purpose
(e.g., "Background Color:"). You can do the same with
Checkbuttons if they happen to be related or along the same theme.

Use a Label to tell users what they did wrong: "The number
entered must be between 10 and 100." (Typically, you would use
a Dialog composite widget to give messages to the user like this, but
not always.)

Put an informational line across the bottom of your window. Each of
the other widgets would have a mapping that displays a string
containing information about that widget.

Add an icon or decorative image to your application.

5.1.1. Creating a Label

The command to create a Label is, of course,
Label. Here's the basic usage:

$label = $parent->Label( [ option => value . . . ] )->pack( );

Hopefully you are starting to see a trend in the creation command. As
you might expect, when you create a Label, you can specify options
that will change its appearance and how it behaves.

5.1.2. Label Options

Causes the text to stick to that position
in the Label widget. This won't be obvious unless the Label is
forced to be larger than standard size.

-background =>color

Sets the background color of the Label
to color.

-bitmap =>bitmap

Displays the bitmap contained in
bitmap instead of text.

-borderwidth =>amount

Changes the width of the edges of the
Label.

-cursor =>cursorname

Changes
the cursor to cursorname when the mouse is
over this widget.

-font =>fontname

Indicates that the text in the
widget will be displayed with fontname.

-foreground =>color

Changes the text of the Button (or the
bitmap) to color.

-height =>amount

Sets the height of the Label to
amount; amount
is a valid screen distance.

-highlightbackground =>color

Sets the color of the focus rectangle when
the widget is not in focus to color.

-highlightcolor =>color

Sets the color of the focus rectangle when
the widget has focus to color.

-highlightthickness =>amount

Sets the width of the focus rectangle.
Default is 0 for the Label.

-image =>imgptr

Displays the image to which
imgptr points, instead of text.

-justify => 'left' | 'right' | 'center'

Sets the side of the Label against which
multiline text will justify.

-padx =>amount

Adds extra space inside the edge to the
left and right of the Label.

-pady =>amount

Adds extra space inside the edge to the
top and bottom of the Label.

-relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken'

Changes the type of edges drawn around the
Button.

-takefocus =>0| 1 | undef

Changes the ability of the Label
to have the focus or not.

-text =>text

Displays a text string in the Label.

-textvariable => \$variable

Points to the variable containing
text to be displayed in the Label. Label will change automatically as
$variable changes.

-underline =>n

Causes the
nth character to be underlined. Allows
that key to invoke the widget when it has the focus. Default value is
-1 (no character underlined).

-width =>amount

Causes the Label width to be
amount.

-wraplength =>amount

Indicates that the text in the
Label will wrap when it gets longer than
amount.

This list briefly describes each option and what it does. Some of the
options have different defaults for the Label widget than we are used
to seeing with Button-type widgets, causing the Label to behave a bit
differently.

5.1.3. How a Label Differs from Other Widgets

When we created Button-type widgets, we could either click them with
the mouse or tab to them and then use the keyboard to press the
Button. A Label widget, on the other hand, does not interact with the
user unless we add explicit bindings. It is there for informational
purposes only, so there is no -command option.

The default value for the -takefocus option is 0,
which means you cannot tab to it. When tabbing between widgets on the
screen, the highlight rectangle shows us which widget currently has
the keyboard focus. Since we don't allow the Label to have the
focus (remember, -takefocus is set to 0), it
doesn't make sense to have a visible highlight rectangle. The
default value for the -highlightthickness option
in a Label widget is 0. You can make a rectangle appear around a
Label by setting -highlightthickness to something
greater than 0, and setting -highlightbackground
to a color, such as blue or red.

The Label widget also doesn't have a -state
option. Since we shouldn't be able to click a Label, we should
never have to disable it.

5.1.4. Relief

In Figure 5-3, you can see what happens when you
change the Label's -relief option. Notice that the edges of the widget are very close
to the text. Unlike a Button, you usually don't want much extra
space around the Label (space is controlled by the
-padx and -pady options). Normally you want the Label widget to sit right
next to the widget (or widgets) it is describing.

Figure 5-3. Labels with different relief values; window on right has a -borderwidth of 10

Seeing what a widget looks like with different relief values
sometimes helps determine where the widget ends, especially with a
widget that has a default value of 'flat'. Also,
changing the relief of different widgets ensures that we know which
widgets are where on the screen. After creating 10 Entries and Labels
with less-than-creative variable names, it's easy to lose
track. Changing the border width is bound to make that one widget
stand out. Color is also a good way to make a diagnostic message.

5.1.5. Status Message Example

You can use the
groove or ridge relief when
making a help or status Label along the bottom of a window. Such a
Label is packed with -side => 'bottom' and
-fill =>'x'. There are two
different ways you can use a status Label:

Set the variable associated with it so it changes as your program
progresses, announcing to the user that it is busy or that something
is happening.

Have the help Label give information on each of the different widgets
in your application when it becomes active, using the
bind command.

The Label is created across the bottom of the screen. We
pack it first because we want it to stay on the
screen if we resize the window (remember, the last widgets packed get
lower priority if the window runs out of room). As the program
executes (represented by the ...), it changes the
Label accordingly.

This example is a bit longer, because we are using the
bind method (the bind method is
explained in more detail in Chapter 15, "Anatomy of the MainLoop"). We want to
associate a help message with each widget we create. We do this by
adding bindings to each widget, which change the variable
$message to a specified string when the mouse
enters the widget and to an empty string if the mouse leaves the
widget. We use a subroutine to avoid writing the same two
bind lines over and over. Figure 5-4 shows what our window looks like with the
mouse over the center Button.

Figure 5-4. Window with Label across the bottom

5.1.6. Container Frames

In Figure 5-4, you can
see the example text is centered within the Label widget. When using
a single line Label and filling the widget across the screen, the
text remains centered, even if you add the-justify=>'left' option. You can get around this by creating
a container Frame, giving it the desired relief, filling the Frame
across the screen (instead of the Label), and placing the Label
widget within the Frame:

This allows the Label to grow and shrink within the Frame as
necessary, while the text sticks to the left side. Even better,
perhaps, is to simply use -anchor => 'w' when
configuring the Label.

If you've typed in this short example and played with the
strings bound to each widget, you might have noticed that the window
will resize itself if the text assigned to
$message is too long to display in the Label. This
can get annoying if your window is fairly small to begin with. There
are two ways to deal with this: first, you can always use really
short text strings; second, you can tell the window not to resize
when the Label changes size.

The drawbacks with each approach aren't too bad, and which one
you pick just depends on the application you are working on. If you
can write really short sentences that make sense, great. Telling the
window not to resize is almost as easy, though; it is accomplished by
adding one line to your program:

$mw->packPropagate(0);

Using
packPropagate will cause your window not to resize
when a widget is placed inside the window (we first talked about
packPropagate in Chapter 2, "Geometry Management").
This means that your window might not show all your widgets right
away. You can deal with this by keeping
packPropagate on until you get all your widgets
in, figuring out a good starting size for your window, and using
$mw->geometry(size) to request that size initially. (See Chapter 11, "Frame, MainWindow,and Toplevel Widgets" for
info on the geometry method.)

5.1.7. Label Configuration

Label is a pretty boring widget, so there are only two methods
available to change or get information on it: cget
and configure. Both methods work for Label the
same way they work for the Button widget. Please refer to
Chapter 5, "Label and Entry Widgets"
for details on arguments and return values.