Learning Perl/Tk is a tutorial for Perl/Tk, the extension to Perl for creating graphical user interfaces. With Tk, Perl
557 70 36MB
English Pages 373 [390] Year 1999
Graphical User Interfaces with Perl
O'REILLY
Nancy Walsh
n^v^icT AivSU^s
3-
Learning Perl/Tk
Learning Perl/Tk
Nancy Walsh
O'REILLY^ Beijing
•
Cambridge
•
Famham
•
Koln
•
Paris
•
Sebastopol
•
Taipei
•
Tokyo
Learning Perl/Tk
by Nancy Walsh Copyright
©
1999 O'Reilly
&
Associates, Inc. All rights reserved.
Printed in the United States of America.
Published by O'Reilly fd/tor; Linda
& Associates,
Inc.,
101 Morris Street, Sebastopol,
CA
95472.
Mui
Editorial and Production Services:
Production Editor:
Ellie
Fountain
tips— Technical
Publishing, Inc.
Maden
Printing History:
Nutshell
January 1999:
First Edition.
March
Minor corrections.
1999:
Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks & Associates. The use of an emu image in association with Perl/Tk is a trademark of & Associates, Inc. Permission may be granted for non-commercial use; please inquire by
of O'Reilly O'Reilly
sending mail to [email protected].
Many
of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps.
While every precaution has been taken
book, the publisher assumes no from the use of the information
in the preparation of this
responsibility for errors or omissions, or for
damages
resulting
contained herein.
@ This book O'Reilly
&
is
85% recycled content, 15% post-consumer waste. committed to using paper with the highest recycled content available
printed on acid-free paper with
Associates
is
consistent with high quality.
ISBN:
1-56592-314-6
[5/99]
Table of Contents
xi
Preface 1.
Introduction to Perl/Tk
A
Bit of History
About
Perl
Perl/Tk for Both Unix and
Why Why
Use a Graphical
1
(and Tk)
Windows 95/NT
Interface?
Use Perl/Tk?
Installing the
Tk Module
5 6
Style
8
Displaying a Widget
9 9
Coding
The Anatomy of an Event Loop Hello World Example
Using
exit
10
Versus Using destroy
Naming Conventions
for
Widget Types
Using print for Diagnostic/Debugging Purposes Designing Your
Windows (A
Short Lecture)
Geometry Management
12 12 13
14
15
Pack
16
Grid
Geometry Management Summary
34 47 56
The Basic Button
37
The Button Widget
57 80
Place
3.
2 3
Creating Widgets
2.
1
2
Some Fun Things
to Try
V
Table of Contents
4.
Checkbuttons and Radiobuttons
81
The Checkbutton Widget
81
The Radiobutton Widget Fun Things 5.
6.
Label
to Try
and Entry Widgets
102
The Label Widget
102
The Entry Widget
108
Fun Things
123
to Try
124
Scrollbars Defining Scrollbar Parts
124
The
Scrolled
Method
126
The
Scrollbar
Widget
128
Examples
137
Fun Things 7.
93 101
140
to Try
The Listbox Widget
141
Creating and Filling a Listbox
141
Listbox Options
142
Modes
144
Selection
145
Colors Listbox Style
146
Configuring a Listbox
147
Inserting Items
147
Deleting Items
148
Retrieving Elements
148
Selection
Moving
Methods
to a Specific
149 Index
130
Translating Indexes
130
Counting Items
130
Active Versus Selected
130
Bounding Box
131
Finding an Index by Scrolling
Listbox
Methods
Example
Fun Things
to Try
Y
Coordinate
131 131
132 133
Table of Contents
8.
154
Text Widget Options
155
A
160
Short Break for a Simple Example
Text Indexes
161
Text Tags
164
Inserting Text
171
Deleting Text
172
Retrieving Text
172
Translating Index Values
172
Comparing Index Values
173
Showing an Index
175
Getting the Size of a Character
173
Getting Line Information
173
Searching the Contents of a Text Widget
174
Scrolling
175
Marks
175
Embedding Widgets
176
Internal
Debug
Fun Things 9.
154
The TextWidget Creating and Using a Text Widget
179
Flag
180
to Try
The Canvas Widget
181
Creating a Canvas
181
Coordinate System
182
The
Scrollable Region
183
Using Bind with a Canvas
184
Canvas Options
184
Creating Items in a Canvas
188
Configuring the Canvas Widget
198
Configuring Items in the Canvas Widget
199
Tags
199 202
Retrieving
Bounding Box Coordinates
Translating Coordinates
202
Moving Items Around
202
Changing the Display
List
203
Deleting Items
203
Deleting Tags
204 204 204
Determining Item Type Set
Keyboard Focus
via
10.
Table of Contents
Rendering the Canvas as PostScript
204
Scaling the Canvas
205
Scanning
206 206 209
A Drawing
Program Example
Fun Things
to Try
The Scale Widget
210
Assigning a Callback
213
Orientation
213
Minimum and Maximum Values
213
Displayed Versus Stored Value
Displaying Value Increments
214 214 214
Adding a Label Changing the Size of the Scale
215
Options You'll Probably Never Need
215
Configuring a Scale
216 216 216 216 216 217
Getting the Value of a Scale Setting the Value of a Scale
Determining Coordinates Identifying Parts of a Scale
Fun Things 11.
to Try
218
Menus Different
Types of Menus
The Menubutton Widget Complete Menubutton Examples
The Menu Widget
Optionmenu Widget Fun Things 12.
210
Creating a Scale
to Try
236 238 248 250
251
Frames Creating a Frame
Frame
218 220
251
253
Style
Frames Aren't
Interactive
255
Colormap Complications
255
Frame Methods
256 256
Fun Things
to Try
Table of Contents
13.
257
Toplevel Widgets
257 260 269 269
Creating a Toplevel Widget
Toplevel Methods
Review
Fun Things 14.
to Try
Binding Events
270
The bind Method
270
Arguments Sent
272
to the Callback
Defining Event Sequences
273 278
Event Information Bailing
Out of
a Callback Created with
bind
The bindtags Method
Ways 15.
to
Use bind
281
Composite Widgets Looking
at
282
an Example Sideways
Location of Files Creating a Composite Widget Based
Toplevel-Based Composite Widgets 16.
Methods for Any Widget
279 280 280
on Frame
283 284
289
290
Color-Related Methods
290 292
Option Databases
293
Building a Family Tree
The
Application's
Name
Widget Existence Is
the Widget
Mapped?
Converting Screen Distances Size of
Widget
Widget Position Screen Information
Atom Methods Ringing a Bell
Clipboard Methods Selection
Methods
Destroying a Widget
Focus Methods
Grab Methods Interapplication
Communication
295
295 295 295
296 297 298 300 300 300 301
302 302 303 304
X
Table of Contents
Waiting for Events to Parsing
Happen
304 306 306
Command-Line Options
Time Delays
and cget
309
A.
Configuring Widgets with configure
B.
Operating System Differences
331
C.
Fonts
334
Index
341
Preface
Perl
is
a great language for
file
processing, connecting to databases, and
do manually. For many command-line interface. The Tk
years,
programs were limited
interface
to a
many
however, Perl
other tasks that are too tedious to
changed
all
that.
The Tk extension
to Perl allows
you
to create graphical interfaces for
your pro-
grams. Using the modules included with the distribution of Tk, you can create
windows with
buttons,
lists,
text,
and other types of widgets
to help
your user
navigate within your application.
What You Should Already Know To
get the
book, you should already know the basics of Perl (speYou should be familiar enough with Perl to be able to at some code and know what the code is doing. You don't have to be a
most out of
cifically, Perl
least
read
version
this
5).
Perl guru or Perl hacker to learn Perl/Tk, but
with the language. Here's the laundry hashes, arrays, subroutines, and their
list
it
will
of things
anonymous
help
if
you
feel
you should at $_ and
versions,
Perl/Tk utilizes the object-oriented features available in Perl
5,
least recognize:
©_.
so even
completely understand them, you should be able to recognize them them. The only other thing you'll need
is
comfortable
if
you don't
when you
see
your prior knowledge of other graphical
user interfaces (GUIs) and what you did and did not like about them. This helps
when
deciding what features to include in your
own
applications.
Take
a look at
word processor you use on your PC, your web browser, or any program has buttons and scrollbars and accepts both mouse and keyboard input.
the
that
xt
xii
Preface
Those applications are
and build up from
pretty major ones; we'll start with
there. We'll
ated options in detail. You'll learn it
how
to look. You'll also learn
much
simpler examples
be covering each basic widget and to
how
all
its
associ-
make a window look the way you want make a window user-friendly and attractive. to
you want to know more about Perl in general, you should read Learning Perl, Programming Perl, Advanced Perl Programming, and Perl Cookbook, which are also published by O'Reilly & Associates, Inc. There are also numerous FAQs and documents available on the 'Web. This book's focus is the Tk extension to Perl, which is a fairly specific portion of Perl. If
Whafs Chapter
1
,
in This
Book
Introduction to Perl/Tk
The
first
ule.
It
chapter contains
some
you out with
starts
and the Tk modWorld program and gives a short
interesting history about Perl
a simple Hello
introduction to event-driven programs. 2, Geometry Management Geometry management is probably the most important concept in using Perl/Tk. It determines how your widgets are to be drawn on the screen (or, in some cases, how not to be drawn on the screen). The three geometry managers ^pack, grid, and place are covered here. Most examples in the book
Chapter
—
—
use pack.
Chapter
3,
The Basic Button
The button
is
the
are also tons of
first
widget
we
cover and there are
manipulate and mutilate the button widget. here are
Chapter
4,
lots
of details here. There
code snippets and screen shots showing
common among
Checkbuttons
Many
different
ways
to
of the options discussed
the other standard widgets.
and Radiobuttons
Checkbuttons and radiobuttons are similar to the standard button, but they look different and are usually programmed differently.
Chapter
5,
Label
and Entry
Widgets
The label is the simplest widget of all. It is usually used with an entry widget, which is why they are included in the same chapter. The entry widget will let you get input from your user. Chapter
6,
Scrollbars
Certain widgets in Perl/Tk can be scrolled,
more information than you can see on
which means they can contain
the screen. Scrollbars are used to navi-
gate the data inside these widgets. Chapter 6
tells
you how
scrollbars
commu-
nicate with each widget and what you need to do to create and use them.
Preface
xiii
Chapter
A
The List box Widget
7,
any
listbox can contain
sort of data, but
from which the user can listbox,
fill
from the Chapter
some
with
items,
it
Chapter
usually contains a 7, you'll
learn
and change the way the user
of options
list
how
to create the
selects the items
list.
The Text Widget
8,
The
it
select. In
text
widget
is
a versatile
many purposes
widget you can use for
besides
Chapter 8 covers the different things you can put inside a
just
displaying
text
widget (such as text or other widgets) and
text.
how
to get the best use out of
them.
Chapter
A
The Canvas Widget
9,
canvas can display objects such as
widgets. Chapter 9 covers
all
circles, rectangles, text,
the options and
and even other
and how
to
numbers from which
to
methods
available
use them.
Chapter
10,
The
The Scale Widget
scale widget
select so there
is
is
great for giving the user a range of
no
possibility of a user typing in a
accidentally typing in letters. Chapter 10 includes get
and covers
all
the
11, Menus Once an application
methods available
for setting
number out
of range or
examples of the scale widit
up and using
it.
Chapter
gets
complex enough, you
will
need
Chapter 11 shows different ways to create menus and
used
in
to put a
how
menu
in
it.
they can best be
an application.
12, Frames The frame widget is used for organizing your other widgets on the screen to get the look you want. Chapter 12 shows how you can use frames in coordination with a geometry manager (covered in Chapter 2) to make your windows look the way you want them to.
Chapter
Chapter
An
13, Toplevel
Widgets
more than one window in it. You can use a toplevel widget to create a second window. In Chapter 13 you'll learn how to create one and display it. We also cover the numerous methods available for application often needs
manipulating toplevel widgets.
Chapter
One
14,
Binding Events
of the best
ways
to
add
functionality to
your application
tional bindings to the widgets. This chapter tells
how
to create
one and use
it.
you what
is
to
add addi-
a binding
is
and
xiv
Preface
Chapter
Composite Widgets
15,
You can combine widgets to make a much more useful, Many of the additional widgets you can use with Perl/Tk are
reusable widget. created this way.
Chapter 15 includes an example of a composite widget and gives you some ideas for creating your own.
Chapter
16,
Methods for Any Widget
There are several methods available for in
Chapter 16 and show you
how
all
widgets in Perl/Tk.
We
cover them
to use them.
Appendix A, Configuring Widgets with configure and cget Appendix A explains the configure and cget methods, which are used with every widget. It also includes a table that shows the options and defaults for each widget option.
Appendix B, Operating System Differences Appendix B covers the differences you'll encounter when you use Perl/Tk on different operating systems, specifically, Unix and Win32.
Appendix C, Fonts Appendix C covers covers the
new
font usage for Tk, for both
Unix and Win32 systems.
It
also
font syntax in Tk8.
Reading Order This
new
book was designed and written with two major audiences and those who have experience with it.
in
mind: people
to Perl/Tk
Perl/Tk Novices If
you have no idea where
to start, start at the beginning. This
book
designed to
is
lead you into topics by building a foundation of knowledge. We'll
with the button widget in Chapter plicated widgets. Using Perl/Tk
basic fundamentals of
how
it
is
3,
The Basic Button,
and move up
start
to
simple
more com-
not really that hard once you understand the
works.
Somewhat Experienced to Gurus Okay, so you've written a ton of programs with Perl/Tk and think you to
do
it.
I
things.
Chances are you have found
recommend reading through Chapter
complete understanding of to the widget sections
you are
code (and sometimes
full
gets in different ways.
The
all
how
those pesky options and
2,
"way
interested
know how
and have stuck with Geometry Management, so you have a that works,"
the geometry managers work.
programs) list
a
in.
I
Then
skip around
have included useful snippets of
that will give
you ideas on how
to use
wid-
of options for each widget are helpful reminders of
how
they affect each widget.
xu
Preface
Typographical Conventions The following typographical conventions
are used in this book:
Italic
command names,
is
used
is
used to identify replaceable values.
for filenames,
URLs, and emphasis. In syntax
lines,
it
Constant Width used for function and method names and
is
code
eral
their
arguments, and to
show
lit-
in text.
Bold is
used to show default values
in syntax lines.
We'd Like to Hear from You We
have tested and verified the information
may
but you Please
find that features
us
let
know
O'Reilly
&
about any errors you
by writing
future editions,
in this
book
to the best of
have changed (which may
in fact
find, as well as
our
ability,
resemble bugs).
your suggestions for
to:
Associates, Inc.
101 Morris Street Sebastopol,
CA
95472
1-800-998-9938 (in U.S. or Canada) 1 -707-829-05 1 5
(international/local)
1-707-829-0104 (fax)
You can
also
send us messages
request a catalog, send email
electronically.
To be put on our
mailing
list
or
to:
info@oreilly. com
To ask
technical questions or
comment on
the book, send email
to:
bookquestions@oreilly. com
We
have a
tions.
Here
able for
web
where
we'll
list
errata
you'll also find all the source
code
for
programs from the book
site for
the book,
download so you
don't have to type
http://www. oreilly. com/catalog/lperltk
it
all in.
and plans
for future ediavail-
xvi
Preface
Acknowledgments quite a bit of time out of my life, and would like to thank who helped make possible and put up with me while was off writfirst, my husband Mike, who helped out in so many little ways is impossito list them all; our dogs. Brandy and Theo, for keeping my feet warm; our
This
book has taken
I
the people ing ble
I
it
it
it:
cats,
Thumper and
Sasha, for keeping the monitor
desk (any typos are completely gested
this
whole crazy
idea;
their fault);
and
my
editor,
my
and keyboard anchored
co-worker, Kreg Webb,
to the
who
sug-
Linda Mui, for always coming up with
positive things to say in addition to the not-so-good things. I'd also like to
Achim
thank
all
the reviewers of the book.
They
include: Stephen Lidie,
Bohnet, Peter Prymmer, Nick Ing-Simmons, and Phivu Nguyen.
Introduction to Perl/Tk
There are many different modules available This
book
add
a graphical interface
Perl great. Instead of requiring a
on the command
mand and
that
extend the
functionalit\- of Perl.
on the Tk module. The Tk module allows us to easily to our Perl scripts and still use all the features that make
will concentrate
line,
command
typed
your program
is
with
some options
or user input
invoked with an icon or a simple com-
the interface handles ever\ihing from there.
The Tk extension to Perl doesn't come with the standard distribution of Perl.* need to get it separately from a CPAN site and install it. After you install the Tk module, you simply add use Tk; to the top of your Perl scripts.
You'll
A Bit of History About Perl (and Tk) was
Originally. Perl
with his
way
v^Titten as a "quick-fLx" to a
job. Typical of all self-admittedly lazy
problem
Larr\"
Wall was ha\'ing
people, he found a better and eas-
was bom. It has since evolved into a widespread and well-used language. Perl has been made available for numerous different platforms, has been well documented, and best of all. is license-fee free. Hopefully the reason you're looking at this book is because you're already com-erted to the wayier
of-Perl
to
do
and thus
it.
and want
to
The Tk extension
Perl
know how
to utilize
it
to the fullest.
and whatsits that comwas ported by Nick Ing-Simmons from Tcl/Tk for use with Perl. A common misconception is that you need Tel Tk installed in addition to Perl and Tk for the whole thing to v^ork. but all you really need is Perl bine to
make
to Perl handles
all
a graphical interface.
the widgets, whodads.
It
Unless you get the Win32 binar\' from CPAN, or another pre-built distribution such as Acti\ eState
Perl.
Chapter
and
Tk
its
tedly lazy people like in less
me
Introduction to Perl/Tk
a lot of other people, self-admit-
can download the binary for the machine they have and
than 10 minutes (download time not included).
install
it
pile
from source for your machine.
it
work by
extension. Thanks to a lot of
1:
You can
also
com-
and Windows 95/
Perl/Tk for Both Unix
NT was
book and cursing the fact that I didn't have enough machines at home to write this book with MS Word and test code examples on my Linux machine without booting back and forth from OS to OS, a miracle was happening. The Tk extension for Perl was ported to Windows. By Windows, I mean the overly-large, overly-influencing OS that is the default on most PCs nowadays, Microsoft Windows. Most people don't have C compilers for their Windows machines, but thanks to the work of Gurasamy Sarathy, there's a great binary distribution of Perl and a good selection of the Perl extensions, including Tk. You simply download the binary, run the install, and you're ready to go.
As
I
writing this
way you
There are no differences between the
write Perl/Tk applications
on
a
Unix machine and the way you write them on a Windows machine. You can use any simple
text editor
on
either system.
There
a small difference in the
is
run them; see Appendix B, Operating System Differences, for just
say that
I
3) rather than
prefer to run
Windows
my
Perl applications
details.
on Windows NT
way you
For now,
4.0 (Service
I'll
Pack
95.
Versions when
and greatest versions of Perl and Tk were Win32 version of the Tk module has been developed and released. Perl has also had some changes. Right before the book was going to print, the port of Tk800.007 was in beta and Perl was up to 5.004_68 (also I
started writing this book, the latest
5.003 and 400.202. Since
beta).
have made every
I
version of
Tk and
Perl
then, a
effort to include information that
and
certain instances (fonts, for
added
in the
new
I
is
relevant to the
new
examples with the new versions. There are
example) where some
version of Tk.
apply, but for the most part,
Why
to test the
have
tried to
you don't have
to
been where they
significant functionality has
note
all
the changes
worry about which version you have.
Use a Graphical Interface?
book (or are considering it in the bookstore) because you have some idea of why you might want to use a graphical interface for one or more of your scripts. Just in case you don't, read on.... Hopefully, you bought this
Why
Use Perl/Tk?
Because you are familiar with writing Perl can get information ing/writing
files,
and out of one.
in
and
input,
fed to
it
from
Do you want can
up
set
a
such as an
others,
I
)
installation script, require constant information
to create this directory?
Do you want
the help
bunch of
be nice
A GUI
adds a
interface
the keyboard to gather
button to execute
when
I
overwrite this DLL?
files?
Sometimes you
little flair
all
all
and waiting
for the next question to
that information
up
front
and then have
the steps after the decisions
and professionalism
to
were made?
an application. However,
would be overkill to add a GUI to a script. If all you are file, munging a bit with no user input, and spitting out GUI would be silly and unnecessary. GUI interfaces work best where
there are times
it
reading in one
another, a
you require a lot of decisions and input from the example in the preceding paragraph. Here are some examples of good uses
A
Can
defaults so the user just has to press return to say yes, but
sitting at it
Go
•
in or out at application
or . Certain applications can run with
file?
up. Wouldn't
is
(
to install this
the user press a
doing
usually involves a combination of read-
Do you want
the user:
then they are stuck
come
you understand the ways you
command-line options, and possibly, data
runtime (STDIN/STDOUT, using pipes
no
It
scripts,
mini
web
client that
user,
such as our
installation
for a graphical user interface:
connects to a dictionary server and
lets
you look up
words. •
An application that takes a regular expression map graphically in a scrollable window.
•
An
A
and displays the
and displays query what the data is.
application that interfaces with a database
several widgets, with labels to indicate •
as input
state
results in
mail reader that interfaces with your inbox and can also send out mail
messages. •
Sometimes your boss says "make a
wrapper around a
script or
it
easy to use!" and that usually means either
an interface that makes
it
easy for users to under-
stand the decisions they have to make. Your users also might be used to a graphical interface rather than a command-line interface.
Why
Use Perl/Tk?
Have you ever tried to draw a window using so-called "native" facilities? If you do it in C, you'll end up with about 100 lines of code just to create a Hello World program, whether you use MS Windows or X Windows. This doesn't even include an Exit button that would allow you to quit the application nicely. I
have used several different methods
tions throughout
my programming
life.
to
draw windows and
Using the basic
create
X Windows
GUI
applica-
routines (such
Chapter
X_Create_Line_from_x_to_y)
as
trol
over every
Sometimes
me
to
I
little
like
know
details of the
it
did.
Introduction to Perl/Tk
basically a drag. True,
is
you have
but then again, you have to control every
detail,
not knowing exactly
that
1:
how
combustion engine.
I
little detail.
enough for and don't exactly understand the intricate
drive a car,
(I
con-
total
the button got drawn;
like that
it is
can turn the key and succeed in
I
my
mission of driving to work.)
You have probably seen
several books on Tcl/Tk. The problem with Tel is that program within the constraints of the Tel language. I much prefer using a language that I already know really well and adding on to it.
you have
to
Perl/Tk provides you with It
hang
the annoying
3D edges on your
handles drawing the
talking about,
all
in there;
I'll
explain
"
(
)
complex widget types
in
all
Something" ->pack
In addition, because of the wonderful different
buttons
which
Perl language to "place a button here," $rr[w->Button -text =>
it
little
details. (if
due
It
handles the event loop.
you're not quite sure what I'm time).
You can simply use
( )
;
community
available for use.
Perl has, there are multitudes of If
you
own by
using a combination of
wid-
can't find the perfect
get (such as a multi-listbox-selection-thingy with associated canvas), ple to create your
the
translates to real Perl as:
some
it
is fairly
sim-
basic and/or not so basic
widgets and constructs.
From
a programmer's
view the bottom
line
is
that using Perl/Tk to write a
GUI
is
programming high. With just a few lines of code, you can instantly display a button and several other widgets that look like a full-blown application. Of course, it takes a bit more time to code the guts behind fun!
it,
It
but
is
it's
the best instant-gratification
almost as
As you go through
much this
fun.
book, the best
way
to understand
what
is
going on
is
to try
lots
of different examples. There are tons of working code snippets included for
this
very reason.
to the button as
your very Also,
own
with the basic Hello World program and change the options you go through Chapters 2 and 3- See what the results are on
Start
screen.
you might want
to
check out these tools (which
we
don't cover in this book,
but they are fun to use): tkpsh and ptksh (new in Tk800.007, the
Tk
for Perl).
You
latest
version of
can download them from http://www.monmouth.com/~beller.
Both programs allow you to type statement (similar to wish).
in
code on STDIN and have
it
evaluate each
Installing the
Tk Module
Installing the Tk Before
we go
into
more
Module on using
details
we
Perl/Tk,
should cover
There are many different ways to get Perl and Tk and
it.
machine.
You can
get the source
and compile
Windows), or you can get a binary
may
distributions
not have
you read any README
sure
The two major binary
all
the
files
how
to install
them on your
(easy in Unix; not so easy in
MS
and install that. Some of the binary components you want in it though, so make
distribution
included with the package.
distributions for Perl
ihttp://www.activestate.com) and
it
install
CPAN
on Win32
are available from ActiveState
{http://www.perl.coni).
tion
on CPAN includes the Tk module, so
First
you need
that's the
one
I'll
The binary
distribu-
cover here.
to get Perl installed:
You can test to see if you already have mand (both Unix and Win32):
Tk module
the
installed
by using
this
com-
perl -e 'use Tk' If
you don't
get an error, you're ready to go.
If
you do get one, the
error will look
like this:
Can't locate Tk.pm in @INC (©INC contains: C:\PERL\lib\site C:\PERL\lib c:\ .) at rayscript line 1.
perlMib c:\perl\lib\site c:\perl\lib\site You'll
need
to find the
Tk module on
a
CPAN
site.
Try starting with
http://
www.perl.com/CPAN/modules/by-module/Tk/. From that directory, find the following
Tk*readme and Tk*tar.gz (always
files:
for the version
systems a
number). Be careful
rename the extension and
try to
.tar.gz
README
make
file it
try to
to .tar. tar. Simply
will
grab the
when you download
latest versions; the
the .gz
rename the
file
file
*
is
because some
back so
that
it
has
unzip properly. Follow the instructions in the
you have the right version of Perl already. After downloading Tk*tar.gz, you need to uncompress it using WinZip for MS Windows or gunzip and tar -xvffor Unix. Follow the instructions in the Install file once you
have
Run
it
file
to
unpacked.
It is
sure that
very similar to installing Perl
itself.
the test
perl -e 'use Tk'
again to make sure it all worked correctly. (Note: Windows users will need to use perl -e "use Tk"). For both MS Windows and Unix, make sure your perl/bin directory is in your PATH environment variable. You can then use the widget demo to see what types of widgets are available.
;
Chapter
1:
Introduction to Perl/Tk
Creating Widgets same
All widgets are created in the
track of
while
it
it
to
exists in the application.
have a central window
few exceptions. created and keep
basic fashion, with only a
Each widget must have a parent widget
watch over
When you
as
it
it
is
create an application, you'll
that will contain other widgets. Usually, that
window
will
and any other windows you create in your application. You are creating an order to the widgets so the communication between child and parent widgets can happen automatically without any intervention from you once you set it all up. be the parent of
all
the widgets inside
$parent widget already Widget type is as follows:
Assuming
that the
ate widget
$child = $parent->Widgettype
Note
it
-option => value,
[
(
generic usage
exists, the
.
.
.
]
when you
cre-
)
that the variables that store the widgets are scalars. Actually, they are refer-
know that right now. If you aren't programming in Perl, using the -> between the $parent and Widgettype invokes the method Widgettype, from the $parent object. It makes the $parent related to the child $child. As you might guess, the $parent becomes the parent of the widget being created. A parent can have many children, but a child can only have one parent. That's pretty much all there ences to widget objects, but you don't need to
familiar with the object-oriented
is
to assigning children to their parents.
When you
invoke the Widgettype method, there are usually configuration param-
to set up the widget and interactions within the application. The configuration parameters will occur in pairs: an option and associated value.
you send
eters that
You
-text, -state, or -variable. Notice that the
will see options similar to
options
all start
with a dash. Even with the dash, they are really
labels to indicate the next value to
come
in the
list.
Usually,
put quotation marks around the options because Perl nize
them
as strings.
However,
about an option that options
all
are always
the time to avoid all
if
you are using the -w
is
not
this,
but
thinks
it
text. it
You can
is
it
just strings that are is
not necessary to
smart enough to recog-
switch, Perl
stick
may complain
quotes around
all
your
The option names which are noted as we
shouldn't be necessary.
lowercase (except in a few very rare cases,
cover them).
Options are specified
in
(-option -> value,
list
form
like this:
-option => value,
-option => value)
Don't be fooled by the funny-looking =>;
"comma."
In fact,
(-option,
you could use
value,
-option,
just
value,
the
it
is
just
commas and
-option, value)
a different
way
of saying
not the => notation, that
is:
Creating Widgets
However,
much
it's
harder to
which are the option/value
tell
Consider the
pairs.
following syntactically equal statements (which each create a button widget that
word
10 pixels by 10 pixels, displays the
when
ting the application
and performs the action of
is
quit-
pressed):
$bttn = $parent->Button(-text, -height,
"Exit,"
"Exit",
sub
-conunand,
{
exit
-width,
},
10,
10);
$bttn = $parent->Button(-text 10, -height => 10)
==>
"Exit",
-command => sub
{
exit
-width =>
},
In the second line, it is much more obvious which arguments are paired together. The option must be directly before the value associated with it: -text is paired with "Exit," -command has the value sub { exit }, and -width and -height
both have values of
10.
Congratulations, we're not even
know how
done with the
first
chapter yet, and you already
to read a typical line of Perl/Tk code!
Quick Definitions ofToplevel, MainWindow, and
Frame Widgets The next chapter covers geometry management, and widgets you don't
know
anything about
several of the
examples use
Most of the widgets are easy
yet.
to fig-
ure out, but a few require a short introduction.
A MainWindow widget is a special version of a toplevel widget. Both MainWindow and toplevel are the windows that contains other widgets. The only difference between a toplevel and a MainWindow
window you
is
that the
MainWindow
is
the
first
create in your application. Both of these widgets are covered in
greater detail in a later chapter (Chapter 13, Toplevel Widgets).
The other type of widget you need
to
know
container that can also contain other widgets.
about It is
a
is
frame widget.
usually invisible
arrange the widgets as desired. The frame widget
A
and
frame
just
also discussed in
is
is
a
used to its
own
chapter (Chapter 12, Frames).
Here
is
what each widget's creation code looks
like:
$mw = new MainWindow; # or $mw = MainWindow->new() $top = $raw->Toplevel $frame = $raw->Frame -borderwidth => 2, -relief => "groove"); ;
( )
(
For now,
just
frame widgets.
keep
in
mind
the general meanings of
MainWindow,
toplevel,
and
;
,
;
,
Chapter
Coding The code of
lines in a Perl/Tk script
ways
are several
can get quite cumbersome and clunky because
Most
"edit-ability").
code
to format the
involve adding extra spaces or tabs to line
just
get used and unwieldy.
quite so mysterious
I
use
to seeing the code,
$bttn = $parent->Button(-text => "my text", -command => sub { exit -width => 10, -height => 10)
With
this
value
is
type of coding
lines (this
is
my
per-
the time):
all
it
some cases, up different
won't appear to be
it
each option/value pair on separate
style places
sonal favorite, and
and configuring each widget. There
to deal with readability (and in
Once you
portions of code.
One coding
Introduction to Perl/Tk
Style
the option/value pairs used in defining
all
1:
style,
it
is
}
extremely obvious what the pairs are and what
associated with which option. (You could also go to the extreme of align-
ing each
=>
to
make nice columns, depending on how much Some people like to start the option/value
press the space bar.) line
and put the ending
pair,
which
retains the
)
on
;
comma
$bttn = $parent->Button( -text => "Exit", -command => sub { exit -width => 10, -height => 10,
its
own
separate
line, after
time you have to pairs
on the next
the last option/value
for formatting ease:
}
);
This makes the code easier to
on each
line
edit;
an option/value pair can be added or deleted
without having to mess with parentheses, semicolons or commas.
also keeps the next lines closer to the
Sometimes,
if
all
there are only
on
side of the
you don't end up with code
indentation levels,
leave them
left
the
same
quite so
one or two option/value
line
and conserve a
page so
deep
pairs,
little bit
to the right. it
just
come up with
and the way you
edit
throughout your scripts
code
(it
a style that
works
makes sense
to
of space:
$bttn = $parent->Button(-text => "my text", -command => sub
Eventually you'll
It
you have several
if
{
exit
}
)
way you
read the code
just try to
be consistent
for the
it.
Whichever way you choose,
in
case someone else takes over the maintenance of your
could even be you a year or more
down
the road).
The Anatomy of an Event Loop
Displaying a Widget You use two
separate
commands
command.
In the
examples so
button, but nothing
is
widget and display
to create a
times they are squished into the same far,
line,
it,
although some-
which makes them look
like the
same
we've used the Button method to create the
displayed by using that method alone. Instead you have to
use a geometry manager to cause the widget to be displayed
in
its
parent widget
The most commonly used geometry manager is pack, and simply call the pack method on the widget object like this: you
or in another widget.
use
it,
to
( )
$widget->pack
{ )
For example: $button->pack
( )
There are arguments that can be sent to the pack method, but we'll cover those Chapter
2,
not necessary to invoke the
It is
be added
in
Geometry Management.
pack method on
a separate line.
The ->pack can
to the creation of the widget:
$parent->Button(-text => "Bye!", -command => sub
{
exit })->pack();
The other geometry managers available are grid and place. All three behave differently, and which one you use often depends on the look you are trying to get in your application. Again, look for information on the geometry managers in Chapter
2.
The Anatomy of an Event Loop When you
are
programming an application
than a textual interface, there are a
lot
that uses a graphical interface rather
of different things to consider. In a text-
based application, you can read from standard input (STDIN), use command-line options, read
files,
or
prompt the user
your only avenue of input from the those places, but as a
"close"
Although
it
our job more
The keyboard
is
GUI, input can not only come from
window manager (such mwm. or MS Windows).
can also come from the mouse and the
from a window manager
directive
this extra
for specific information.
user. In a
input allows
difficult.
As long as
more
we
flexibility in
tell
it
what
like
our applications,
it
also
to do, Perl/Tk helps us
makes
handle
all
that extra input gracefully.
Input in a
GUI
is
defined by events. Events are typically different combinations of
mouse at the same or different times. If the user pushes mouse button on button "B", that is one type of event. Pushing the right mouse button on button "C" would be another event. Typing the letter "a" would
using the keyboard and the
left
10
Chapter
1:
Introduction to Perl/Tk
be another event. Yet another event would be holding down the Control key and clicking with the middle mouse button. You get the idea. Events are processed during an event loop. This event loop does
name
—
says
it
handles events during a loop.
It
based on what type of event happened. Here
just
what
determines what subroutines to
is
a
its
call
pseudo-code event loop:
while (1) { ge t_even t_info
if event is left-mouse-click call process_left_mouse_click else if event is right-mouse-click call process_right_mouse_click else if event is keyboard- input call type_it else handle events for redrawing, resizing etc }
very simplistic approach to an event loop, yet
Obviously,
this is a
basic idea.
The event loop
input
was given
is
a
it still
shows the
weeding-out process to determine what type of
to the application. For example, the subroutine
process_lef t_
inouse_click might determine where the pointer was when the mouse occurred and then
call
In Perl/Tk, the event loop
we
If
happen
initiated
is
thing prior to this statement will not
is
until after the
forget to include the
MainLoop
calling a routine called
up
GUI has been
MainLoop
windows, buttons, or widgets occurs after calling
by
just setting
and then go
things for a while
click
other subroutines based on that information.
right will
is
the interface. exited
to the
be drawn
at
that the interface
after this call
by using $itiw->destroy.*
statement, the
back
MainLoop. Any-
Any code
program
will think
about
command prompt. None of the all. One of the first things that is
drawn and
the event loop
is
started.
Before
we
much
get too
further into the event loop
you need to do so it works right), let's look at World. (You were expecting something else?)
and what it does (and what working program. Hello
a real, live,
Hello World Example Every programming language goes through the Hello World example.
example because
*
shows how
it
Throughout the book,
I
will
use
the beginning of the application.
$mw
It is
a
good
to do something very simple but useful. In our
to indicate the variable that refers to the
main window created
at
Hello World
Example
11
Hello World example, we'll have the
title
window
of our
say "Hello World" and
create a button that will dismiss the application: # /usr /bin/perl use Tk; my $inw = MainWindow->new; $mw->title( "Hello World"); !
$iiiw->Button(-text => "Done",
-command => sub
{
exit
}
)
->pack;
MainLoop
Despite only being six lines long, there
gram. The
first line,
as
is
quite a bit going
Win32 you have to type perl hello.pl to invoke Perl that we would like to use the Tk module. The
on
in
our
little
pro-
any Perl programmer knows, invokes Perl (only on Unix; the program).
The second
in
line tells
third line
my $mw
=
how we
MainWindow->new;
window. The window will have the same basic window manager decorations as all your other windows. In a Unix environment, it will look like all your other windows, and if it were in MS Windows, it would look like those windows. is
create a
window
The
title
this
method, the
of our
is
changed by using the title method.
text across the top of the
If
window would be
we
the
hadn't used
same
as the
name of the file containing the code. For instance, if my code were stored in a file named hello_world, the string "Hello_world" would appear across the title bar of
my
application (Tk automatically capitalizes the
title method
Any
is
not required, but
makes
character for you). Using the
first
the application look
more
polished.
we put as an argument becomes the title. If wanted the title to be "Hey! my great program!" this would be the place. This is akin to using the -title when starting up any standard X Windows application. There are more meth-
string
Look
I
at
option
ods for a MainWindow
The next Chapter
3,
starts
only what will exit.
object,
line creates a
which
will
all
"Done" and
to display the text
Finally, the last item of
told
it
to do:
If
—
will all
Chapters 12 and
13-
it.
(See
to
concern
perform the Perl is
the
command
MainLoop command. will do
and from then on the application
the user clicks
Anything else the user does
applications
later in
available configuration options.)
the event handler in motion,
we have
be covered
Button widget, sets basic properties, and packs
The Basic Button, for
The button is set up exit when pushed. This
it
on the
—minimizing,
button, the application
resizing,
changing to other
be processed by the window manager and ignored by our
application. See Figure 1-1 for a picture of the Hello
World window.
12
Chapter
Figure 1-1. Hello World
1:
Introduction to Perl/Tk
window
Using exit Versus Using destroy In
all
of the examples in this
book you
will see
sub
exit;
{
}
used to quit the
use Tk; in the own exit routine
Perl/Tk application. This works fine as long as you have done a
same file that contains the sub { exit }. Perl/Tk defines which does some cleanup and various other things that Another way to quit the Tk portion of the application
its
are important to Tk.
to call $itiw->destroy (),
is
which destroys the main window and returns to the code listed after MainLoop. The code after MainLoop will not be executed even if you use sub { exit }. Keep this in mind if you are going to be doing anything after the GUI portion is done.
Naming Conventions for Widget Types Naming conventions?
we
How
boring! Well, sometimes our programs get so large
and
$button variable was pointing to. If there are over 10 buttons in our program, we would be hard-pressed to figure out which button was $button3 without digging through a bunch of code. unwieldy
that
remember what
can't
that stupid
I'm merely going to suggest a naming convention, and If
not, either
For buttons,
come up with your own, like to
I
or
if
hope you have
you
like
a really
it,
please use
use _b, _bttn, or Button as a type of qualifier to the
able name. For instance,
I
would name my button
it!
good memory.
in the Hello
vari-
World example
$done_b, $done_bttn, or $doneButton.
A
specialized widget type
dow method.
I
always use
is
the very
$itiw
first
programs use $main or $inainwindow as Table
1-1 contains a
list
window we create with name for this. You
as the variable
the
MainWin-
will see other
well.
of widget types and
my
suggested naming conventions for
them. Replace "blah" with a sensible description of the widget's purpose exit).
If
you use
working with.
this
convention, you'll always
know
(e.g.,
what type of widget you're
Using print for Diagnostic/Debugging Purposes
Naming conventions by
Table 1-1.
Widget Type
Suggested
Button
$blah_b
13
widget type
Name
Examples $exit_b, $apply_b, $newBut-
$blah_bttn, $blah-
(or
ton
Button)
$blahCanvas
Canvas
$blah_canvas
Checkbutton
$blah_cb
Entry
$blah_e or $blahEntrY
Frame
$blah_f or $blahFrame
or
$inain_canvas, $tinyCanvas
$blahCheckbutton
or
$uppercase_cb, $lowercaseCheckbutton $name_e, $addressEntry $main_f, $left_f, $canvas-
Frame Label
$blah._l or $blahLabel
Listbox
$blah_lb
Menu
$blah_m
Radiobutton
$blah_rb
$blahListbox
or
or
$name_l, $addressLabel $teaiTis_lb,
$blahMenu
$blahRadiobutton
or
$teamsListbox
$file_irv $edit_m,
$helpMenu
$blue_rb, $grey_rb, $redRa-
diobutton
I
Scale
$blah._scale or $blahScale
$age_scale, $incoineScale
Scrollbar
$blah_scroll $blahScroll
$x_scroll, $yScroll
Text
$blah_t
(or
$blahText)
Toplevel
$blah_w
or
$blahWindow
admit
me
use
are
two
I
don't follow
just
$button
in the
honor?) to use
(or $blah._sbar) or
my own in
rules
$file_txt, $commentText
all
example code.
$main_w, $fileopenWindow the time. Throughout this book, you'll see
use $buttonl and $button2
I'll
example. Anything larger than
my own
convention.
type of widget I'm referring
I
will
just a
few
always use a
lines,
name
I
if
there
will try (scout's
that indicates
what
to.
Using print for Diagnostic/Debugging Purposes Normally, you'll run your Perl/Tk program by typing the program
command %
name
at
the
prompt:
hello world
or C:\>perl hello_world
When you printf)
is
this way, any output created by using a print (or window. Sometimes, you won't see the information
invoke the program to that terminal
actually printed until
you
quit the program. This
is
probably because you didn't
put a \n on the end of the string to be printed, which causes an automatic flushing of output. During your application processing,
print statement when you should
be,
make
sure
if
a
you think you aren't seeing a is on the print statement.
\n
14
Chapter
Introduction to Perl/Tk
1:
Designing Your Windows (A Short Lecture) Before you decide what events to handle, sketching out a few
it is worthwhile to spend some time windows on paper and deciding what should happen (from
when you
the user's perspective)
One
of the most important things to keep in
windows
tion's
A GUI
nothing happens
that
is
MainLoop
prior to the call to
a
click a button or
is
just
mind when you design your event loop
until that
\
item.
applica-
up. Everything
starts
preparation for the event loop.
makes the application look much more polished and purposeful than command-line interface does. Also, it is often much easier to manipulate many
Here are some things look
through a GUI.
to consider
when you
what the GUI should
are deciding
like:
•
Every widget should have a purpose.
•
Think about the way
•
Don't
•
Don't always
try to separate
application
so simple that one
try to
a user will use
is
on using
cation
It
should be
color, allow
intuitive
is
accordingly.
doing into one window.
everything into different windows. Sometimes the
window
it
to
lot
is all
you need.
of color-blind people out there.
be customized
via a
their job better than others do.
file
If
you
or through the appli-
Use the
right job. it
it
itself.
Some widgets do
That's
and informative.
an application and design
cram everything your application
Colors are great, but there are a insist
•
menu
often
different kinds of user input
•
invoke a
for the lecture.
Now,
get ready to learn the ropes.
right
widget for the
Geometry
Management To
on the
display widgets
must be passed
screen, they
geometry manager controls the position and
to a
geometry manager. The
size of the widgets in the display win-
dow. There are several geometry managers available with Perl/Tk: pack, place,
and grid. geometry managers are invoked as methods on the widget, but they
All three
have
their
own
gets are put
$widgetl->pack
When you ( )
it
,
( )
$widget2->place
;
( )
;
$widget3->grid
organize the widgets in your window,
is difficult
to
out grouping them in
window
inside a
We
create our
form of
the wid-
screen:
groups of widgets to get a certain look and
pack
how
methodologies and arguments to change where and
on the
all
or
first
it
feel.
( )
often necessary to separate
is
when you
For instance,
have widgets stacked both horizontally and
some
We
fashion.
group widgets by using
by using another window
window by
a toplevel widget. For
calling
more
use
vertically with-
widget
a frame
(a toplevel widget).
MainWindow. The MainWindow
detailed information
on how
a special
is
to create/config-
ure frames and toplevel widgets, see Chapter 12, Frames, and Chapter 13, Toplevel Widgets.
Because of the differences between the three geometry managers, (not entirely impossible, but definitely not
geometry manager within the same widgets, but
if I
using
start
pack
widgets contained directly in
grid
( )
gets,
we
.
Because
could use
use
a
pack
gridO
$inw.
window can ( )
to
to
( )
I
,
area. In I
recommended) our $mw,
I
to use
can display
should continue to use pack
it
is
difficult
more than one
many ( )
on
types of all
of the
wouldn't want to switch in the middle to using
contain a frame, which in turn contains other wid-
pack the frame inside the main window and then
manage
the widgets inside the frame. See Figure
we
2-1.
15
16
Chapter 2: Geometry Management
Regioni: Contains several widgets and a frame
managed by
all
pack()
Widget A Widget A Frame: Placed inside
Figure 2-1.
in it
window by pack(), but widgets managed by grid().
are
Frame within a window
that uses
a
different geometry
Although the different geometry managers have
most commonly used
their
manager
own
and weak-
strengths
pack so I'll discuss it first and in the most detail. The gridO geometry manager was under development as I was writing this book, grid has been improved greatly with the release of Tk 8.0 and subsequent porting to Perl. The place geometry manager is the most tedious to use nesses, the
is
(
( )
,
)
because you have to determine exact coordinates for every single widget.
Pack Remember when you were the puzzle had exactly laps allowed 'With the
between
and you had those wooden puzzles on them. Each piece
a small child
put together? They often had cute
little
pictures of animals
one place where
it
pieces.
are similar to the
because widgets cannot overlap or cover each other If
a button
is
ton (or any widget) will
our windows
will
in
could go, and there weren't any over-
pack geometry manager, our windows
Figure 2-2.
to
wooden
puzzle
(partially or completely).
See
packed in a certain space on the window, the next buthave to move around the already packed button. Luckily,
only be dealing with rectangular shapes instead of funny-shaped
puzzle pieces.
The order in which you pack your widgets is very important because it directly affects what you see on the screen. Each frame or toplevel maintains a list of items that are displayed within
it.
before widget B, then widget
This
A
go through some examples. You
dow
just
by packing the widgets
list
has an order to
it;
if
will get preference. This will
will often get a
widget
A
become
is
packed
clear as
we
very different look to your win-
in a different order.
Pack
17
Widget
A
Widget B Figure 2-2. Overlap error If you don't care what the window looks like and how the widgets are put in it, with no arguments and skip the rest of this chapter. Here it is you can use pack ( )
again:
$widget->pack
( )
To make your window look are arguments that can
arranged in
pairs.
$widget->pack(
Here
is
be sent
window
widgets and the
nicer
in this
pack method
As with anything
that will
friendly), there
change the way the
in Perl/Tk, the
arguments are
So the more sophisticated usage would be: [
option => value,
the code to create a
used
to the
looks.
Figure 2-3 shows the resulting gets
and more manageable (and user
window window
);
]
that doesn't
know we
(I
example, but hang in there,
it's
use any options to pack ( ) haven't covered
all
the wid-
pretty simple).
# /usr /bin/perl -w use Tk; !
my
$rnw =
MainWindow->new;
$inw->title "Bad Window" ; $rnw->Label (-text => "This is an example of a window that looks bad\nwhen you don't send any options to pack" ->pack; (
)
)
$mw->Checkbutton(-text => "I like it!")->pack; $mw->Checkbutton(-text -> "I hate it " ->pack; $mw->Checkbutton(-text => "I don't care" ->pack; $mw->Button(-text => "Exit", -command => sub { exit } ->pack; MainLoop; !
)
)
)
;
18
Chapter
^
2:
;
Geometry Management
**^*»!3
Bad WfcKtow
an example of a window Uiat looks bad when you don't send any options to pack
This
is
J J
J
i
1
like
it!
liiateil!
don't care Exit
Figure 2-3-
Window
managed by pack
with widgets
We
can
will
make our window look much
alter the
preceding code and add some options to the pack() nicer:
# /usr/bin/perl -w use Tk; !
my $mw
= MainWindow->new;
$inw->title "Good Window" $inw->Label (-text => "This window looks much more organized, and less (
)
;
haphazardXnbecause we used some options to make it look nice" ->pack; )
$mw->Button(-text => "Exit", -command => sub
->pack(-side => 'bottom', -expand => 1, -fill => 'x'); $mw->Checkbutton(-text => "I like it! " ->pack(-side => 'left', -expand => 1) $mw->Checkbutton(-text => "I hate it " ->pack(-side => 'left', -expand => 1 $mw->Checkbutton(-text => "I don't care" ->pack( -side => 'left', -expand => 1) MainLoop; {
exit
)
}
)
!
)
)
)
Figure 2-4 shows the
much more
organized window.
Good Window This
J;
window looks much more organized, and less haphazard because we used some options to make it look nice I
like
it!
^
I
hate
it!
_j
I
don't care
Exit
Figure 2-4.
Window
with widgets
managed by pack
using some options
calls that
Pack
19
Using pack(
allows you to control:
)
window
relative to the
window
or frame edges
•
Position in the
•
Size of widgets, relative to other widgets or absolute
•
Spacing between widgets
•
Position in the
The
options, values,
window's or frame's widget and defaults are
listed
list
and discussed
in the
following section.
Pack Options This are
list
shows
shown
in
all
when you
the options available
bold (which indicates
if
pack
call
you don't use
( )
.
The
default values
that option, you'll get the
effects of that value for that option).
-side => 'left'
|
'right'
'top'
|
'bottom'
|
Puts the widget against the specified side of the
-fill => 'none'
|
'x'
Causes the widget to
-expand =>
1
'y'
|
fill
the allocation rectangle in the specified direction
|
fill
the remaining space available in the win-
or frame
-anchor => center '
or frame
'both'
|
Causes the allocation rectangle to
dow
window
'n'
|
'ne'
|
'e'
|
'se'
|
's'
|
'sw'
|
'w'
|
'nw'
|
'
Anchors the widget inside the allocation rectangle
-after => $otherwidget Puts $widget after $otherwidget
in
-before => $otherwidget Puts $widget before $otherwidget
packing order
in
packing order
-in => $otherwindow Packs $widget inside of $othe2rwindow which is the default
rather than the parent of $widget,
-ipadx => amount Increases the size of the widget horizontally by
amount x
-ipady => amount Increases the size of the widget vertically
by amount X
-padx => amount Places padding
on the
left
and
right of the
widget
-pady => amount Places padding
on the top and bottom of the widget
2
2
))
'
20
Chapter 2: Geometry Management
Positioning Widgets Each window (or frame) has four sides to
it:
top, bottom,
left,
and
right.
packer uses these sides as points of reference for widgets. By default,
The
packO
places the widgets against the top of the toplevel or frame.
You can
control
-side =>
For example,
what
'left' if
side a widget '
right
we would
'
' |
like
is
top
placed against by using the -side option: 'bottom'
our button against the
left
edge of the window,
we
can specify -side => 'left'.
Using our Hello World example as a base,
pack our button against the
->pack
different sides.
let's
look
The only
part of the Button creation line. We'll also
string in the
$inw->title
command
to easily
show
what happens when we we will change is the change the "Hello World"
at
line
the
new
options to pack.
$itiw->Button(-text => 'Done',
-command => sub { exit ->pack(-side => 'top');
})
OR $mw->Button(-text => 'Done', -command => sub { exit }) ->pack;
$mw->Button(-text => 'Done', -command => sub { exit } ->pack(-side => 'bottom');
sp ^^We =>
bottom'
h|j
Done
$mw->Button(-text => 'Done', -command => sub { exit } ->pack(-side => 'left');
-Side
Done
«>
left'
J
21
Pack
$inw->Button(-text => 'Done', -command => siob { exit } ->pack -side => right (
'
'
)
The windows shown here have been made a bit larger to emphasize the difference that using alternative values for -side makes. Normally, the window will be only as large as required to show the button. When you are deciding which way to place widgets in a window, it is always a good idea to see what happens when you make the window both larger and smaller. Make sure the behavior you get is what you want. So
far,
packO seems
what if you want to put more than one What happens when we simply add more buttons?
pretty simple, but
button in your application?
$rnw->Button(-text => 'Donel', $I^w->Button(-text => 'Done2', $mw->Button(-text => 'Done3', $iTiw->Button(-text => 'Done4',
-coinmand => sub -coinmand => sub
-command => sub -coinmand => sub
exit } ->pack; exit } ->pack; exit })->pack; exit })->pack; )
{
)
{
{ {
-side is top, we would expect them to all be mushed up window, right? Sort of. The packer allocates space for each widget and then manipulates the widget inside that space and the space inside the window. Since the default
against the top of the
Figure 2-5 shows what the
window
with the four
next section explains why.
_.
Buttim
>
Donel
DoneZ Done3
Done4
Figure 2-5- Four buttons packed with default settings
J
Done
buttons looks
like;
the
22
Chapter 2: Geometry Management
Allocation Rectangles When tom,
given an item to pack, the packer
right,
or
to use.
left)
looks to see which side (top, bot-
first
then sets aside an invisible rectangular area across the
It
length of that side for use only
by
that widget.
empty window
In Figure 2-6, the solid-line rectangle represents our
and the dotted-line rectangle the
first
button.
window, but
It
actually
make
to
it
tall
all
set aside
as the
way across the width shown a little indented.
the
it's
by packer when using -side =>
on the
window
Our examples so
it.
is
as
wide
For the right and
the width of the button.
If
we
in
and
-side
=>
'left'
we'll call the allocation rectangle,
as the
which the
fit
both the top and
window and
left sides,
but only as wide as required to
have used buttons
far
which
or height of the
'top'
size of the requesting widget. For
sides, the allocation rectangle
the widget to be placed in as
does go
for the dotted-line box,
are calculated based
bottom
(or frame),
the rectangular area that the packer sets aside for
easier to see,
Figure 2-6. Rectangular areas
The dimensions
is
only as
tall
the allocation rectangle
as is
the widget.
text of the button
create a button with the text
"Done" on
determines it
and one
it," the second button is going to be much two buttons are placed up against either the right or left side of the window, the second button would have a wider allocation rectangle than the first. If we placed those same two buttons against the top and the bottom, the allocation rectangles would be the same height and width because the
with the text "Done, Finished, That's
wider than the
width
is
first.
When
these
determined by the window, not the widget.
After the size of the allocation rectangle
is
determined, the widget
is
placed within
the allocation rectangle according to other options passed and/or the default val-
ues of those options. cation rectangle
Once
the
first
I
will
go over those options and
how
they can affect the allo-
later.
widget has been placed
in the
able for subsequent allocation rectangles rectangle has used
some
is
window, the amount of area smaller because the
of the space (see Figure 2-7).
first
avail-
allocation
Pack
23
Buttont Allocation Rectangle
New
Allocation Rectangle
Figure 2-7. Second allocation rectangle
When more
than one button
the results will vary
is
when
default side
buttons right and
used
placed against different sides in the same window,
depending on the order used.
by placing one button along the
We'll start
'top' is
one along the bottom, and then
top,
left:
$iTTW->Button(-text => "TOP",
-command => sub
exit
{
})
->pack(-side => 'top');
$mw->Button -text => "BOTTOM", -command => sub ->pack(-side => 'bottom'); (
$mw->Button(-text => "RIGHT", -command => sub ->pack(-side -> 'right'); $mKV->Button(-text => "LEFT", ->pack(-side => 'left');
The
allocation
rectangles
for
-command => sub
this
{
{
exit
{
exit
exit
})
})
})
window would look
like
the
diagram
in
Figure 2-8.
Allocation rectangle for
1
Allocation rectangle for
TOP
1
1
Allocation rectangle
LEFT
for
i
RIGHT
Allocation rectangle for BOTTOIVI
Figure 2-8. Allocation rectangles forfour buttons
Figure 2-9
so
it's
shows what the
a bit larger.
actual
window
looks
like,
both normal size and resized
;
;
24
Chapter
gj
Btmons
''4
j
~
4aiiwii!s
-.j
TOP
yJ3i
Geometry Management
2:
rr
Jl
,
TOP LEFT
LEFT
RIGHT
1
BOTTOM
RIGHT
,
BOTTOM ' ,
,
—
,j
window
Figure 2-9- Four buttons placed around the sides of the
Filling the Allocation Rectangle Normally, the widget
is
left at
the default size, which
allocation rectangle created for resize itself to
fill
If
it.
the
usually smaller than the
is
-fill option
used, the widget will
is
the allocation rectangle according to the value given.
The
possi-
ble values are: -fill => 'none'
'x'
Using the value 'x'
'both'
'Y'
will resize the
widget
x
in the
cause the widget to resize in the y direction. Using -fill =>
way
to see exactly
what
size
'y' will
direction. Likewise,
and placement was given
'both'
is
a
good
to the allocation rectangle
both x and y directions. Using our four-button example again, we'll specify -fill => 'both'.
because 'both' resizes the widget
in
$iTiw->Button(-text => "TOP", -command => sub ->pack(-side => 'top', -fill => 'both');
exit
{
$raw->Button(-text => "BOTTOM", -command => sub ->pack(-side => 'bottom', -fill => 'both'
{
})
exit
})
)
$mw->Button(-text => "RIGHT", -command => sub ->pack(-side => 'right', -fill => 'both'
{
exit
})
)
$mw->Button(-text => "LEFT", -command => sub ->pack(-side => 'left', -fill => 'both');
{
exit
})
Figure 2-10 shows the resulting window. If
we
switch the button
Figure 2-11
we
create
was created by packing
first,
we
get a different result.
the widgets in this order:
The window
left, right,
in
top, bottom.
Figure 2-12 demonstrates yet another order, which really shows that the allocation rectangles change size depending
on what
gets
packed
first.
25
Pack
^
side and
fiU(t, b, r .1)
1
^J
TOP RIGHT
LEFT
BOTTOM Figure 2-10. Four buttons packed to each side using
side and fM
-.
(r,
1,
-fill
b)
t,
=>
j
'both
J
.
TOP RIGHT
LEFT
BOTTOM ^
Figure 2-11. Four buttons packed to each side in a different order using
d
4Buttons (U,b,l)
1
.
-fill
=>
'both
J
TOP
LEFT
RIGHT
BOTTOM Figure 2-12. Four buttons packed in order of top,
A common
use of -fill
is
on widgets with
Usually, the scrollbars are along the
box box
to
fill
more
bottom,
and left
scrollbars: listbox, canvas,
and
edge of the window, and you want the
the remaining area. See Chapter
Widget, for
right,
6,
Scrollbars,
and Chapter
7,
The
text. list-
List-
information.
Expanding the Allocation Rectangle The -expand option manipulates the allocation rectangle and not inside it. The value associated with -expand is a boolean value. -expand =>
1
the widget
.
26
Chapter 2: Geometry Management
Given a true value, the allocation rectangle left
over in the
expand
will
window depending on which
into
side the widget
any available space
was packed.
Widgets packed with side
right or left will expand in the horizontal direction. Widpacked with side top or bottom will expand in the vertical direction. If more than one widget is packed with -expand turned on, the extra space in the win-
gets
dow
is
divided evenly
among
In Figure 2-9 or 2-10,
the
window
you saw
that wasn't
add -expand =>
window
the allocation rectangles that want
all
was some space
that there
occupied by any widget.
1 to the
list
left in
we change
If
it.
the center of the code and
of pack options for each button, the result
is
the
in Figure 2-13-
1
4ButtDns
-_(
1
J
-
TOP 1
>
RIGHT
LEFT
BOTTOM 1
Figure 2-13- Four buttons using the -expand => 1
Note the
that Figure 2-13 left the
-fill option, the buttons
(which are
invisible) take
-fill =>
and
=>
-fill
'both' options
'both' option
in the code. If
we
omit
stay their original size, but the allocation rectangles
over the extra space in the
(see Figure 2-14).
|.|J
4Buttons
^i
window
TOP
LEFT
^
RIGHT
BOTTOM
Figure 2-14. Four buttons using -expand => 1
and -fill =>
'none'
In Figure 2-14, the buttons are centered in their allocation rectangles
the default value of the
-anchor
option,
which
is
'
center
'
because of
27
Pack
Anchoring a Widget in
Its Allocation
Rectangle
The anchor option manipulates the widget inside the allocation rectangle by anchoring it to the place indicated by the value passed in. It uses the points of a compass as a reference. -anchor
'e'
'n'
'w'
'ne'
's'
'nw'
'se'
'center'
'sw'
Figure 2-15 shows those locations in an example allocation rectangle.
Figure 2-15- Allocation rectangle with -anchor points labeled
center which keeps the widget in the center of its -expand option is set to a true value, this won't seem to change much of anything in the window. As seen in Figure 2-16, which shows the result of using the -expand => 1 option, it is obvious that the widget
The
default for
-anchor
is
'
'
,
allocation rectangle. Unless the
sticks to that center position
when
the
window
is
resized.
Figure 2-16. Default behavior of -anchor with -expand set to
1
other defaults are used to pack the widget, Figure 2-17 shows what -anchor => 'e' and -anchor => 'w' does.
If all
Remember is
packed
that the allocation rectangle
against, so certain
is
combinations
created based will
on which
side the widget
appear to have not had any
For example: $inw->Button(-text => "Done", -coinmand => sub ->pack(-side => 'top', -anchor -> 'n');
{
exit
})
effect.
28
Chapter 2: Geometry Management
-aichor «>
J_
'e'
1-i^
Done
Done ^
1
Figure 2-1
7.
Examples of -anchor =>
'e'
and -anchor =>
'w'
This code fragment will leave the widget exactly where
it
was
if
-anchor
the
option had not been specified because the allocation rectangle does not change size at
all.
resized, the
's'
If
the
-expand option
widget would
had been
specified,
the south side of the
also specified, then
is
when
the
window
is
resized,
when
the
window
is
-anchor => the widget would stick to
stick to the north side of the
window.
If
window.
The -anchor option is more often used to line up several widgets Figure 2-18 and Figure 2-19 show two common examples.
-^ ex|
in a row.
^i|i
Done Done Done
Figure 2-18.
Window
with three buttons all packed with -side =>
Figure 2-19. Windows with three buttons
Sometimes,
all packed with -side
when -side and -anchor
be what you would expect cation rectangle and
how
it
'left',
-anchor =>
'w'
-anchor =>
are used together, the results don't
at first glance.
affects
=>
'top',
Always keep
what you see on the
in
mind
screen.
'n'
seem
to
that invisible allo-
29
Pack
Widget Order in the
Window
Each window
that has widgets packed into it keeps track of those widgets in an The order of this list is normally determined by the order in which the widgets were packed. The last item packed is the last item in the list. Using the -after option, you can change the default order by specifying which widget should be placed after your new widget. On the opposite end, if you use the -before option, you can put the new widget before a previously packed widget:
ordered
list.
-after => $otherwidget -before => $otherwidget
As an example,
buttons
four
create
let's
$widget4) and only pack three
$widget2,
($widgetl,
to begin with.
The pack command
$widget3,
$widget4
for
might then be: $widget4->pack( -after => $widgetl)
shows two windows: one before $widget4
Figure 2-20
$widget4
is
Figure 2-20. with
If
Done4
Done2
1
On
left:
label
we want
the
J
Done3
|
window
$widget4
:
ex»n|rie
Done4
Donel
-after
1^
Done2
On
with three buttons packed in order.
was packed using
to put
—
'U
exusnirie
Donel
after
packed.
^ .
packed and one
is
Done3
right: the
J J
button
=> $widgetl
in front of
$widgetl,
we
use
this
command, and see
the results in Figure 2-21. $widget4->pack{ -before => $widgetl)
exm^
d :
Figure 2-21. Button with
Done4
Done4
Donel
label
^
A
^
DoneZ
was packed using
Done3
-before
J 1
=> Sdonel
Padding the Size of the Widget The The
final
way
first set
to force
pack
to size the
widget
is
of padding options affects the widget
size. Different
amounts can be added
in the
to use the itself
padding options.
by adding to
its
default
x and y direction, or they can be
1
30
Chapter 2: Geometry Management
To specify how much padding should occur -ipadx option:
the same. the
x direction, use
in the
-ipac3x => amount
Specify padding for the y direction like
this:
-ipady => amount
The amount is
a
number
that
a valid screen distance.
is
I'll
discuss the definition of
a valid screen distance in the next section.
Both the -ipadx and -ipady options change the allocation rectangle right
and
left
is
size of the
widget before the
-ipadx adds the amount specified to both the widget. The overall width of the widget would increase
calculated,
sides of the
X amount), -ipady adds to the top and bottom of the widget, causing the overall height of the widget to increase by (2 x amount). Figure 2-22 shows how
by
the
(2
-ipadx and -ipady options
affect a button.
1
examine
7-1
Done2
^Ij Done3
Donel
|
Figure 2-22. The Donel button was created with options: -ipadx => 10, -ipady => 10
The other kind of padding
is
between the edge of the widget and the done with the -padx and -pady options:
inserted
edge of the allocation rectangle and
is
-padx => amount -pady => amount
Using -padx and -pady does not the size of the allocation rectangle. ing
it
affect the size of the widget, It
acts as a buffer
but
it
does
affect
around the widget, protect-
from having to touch other widgets. Figure 2-23 shows the
effects of using
-padx and -pady.
—
example .._..._
_
...±\
Done3
Ji ;
Donel
Figure 2-23. The
A good way the
"i"
to
Donel button was created with
remember
options -padx => 10, -pady => 10
the difference between
-ipadx/y and -padx/y
stands for "inside the widget" or "internal padding."
is
that
Pack
31
Valid screen distances
Many
times you'll see options that require values specified in screen units (or what
The options -ipadx and -ipady are examples Always check to see what value the option actually requires.
called a valid screen distance).
is
of this type of option.
A
screen unit
no
number followed by
a
is
a designation for the unit to use. If there
designation, the units are in pixels. Table 2-1
shows
all
is
the possibilities.
Table 2-1. Valid screen units
Designator
Meaning
Examples
(none)
Pixels (default)
20, 30, "20", "40"
c
Centimeters
'3c', '4c', "3c"
i
Inches
'2i', "3i"
m
Millimeters
'4in',
P
Printer points (1/72 inch)
"72p", '40p'
To use
these designators,
necessary to use quotes (either single or double)
is
it
"4m"
around the value. Here are some examples: $button->pack( -ipadx $button->pack -ipadx $button->pack( -ipadx $button->pack -ipadx $button->pack( -ipadx $button->pack( -ipadx (
(
Remember
ommend
=> => => => => =>
#20
pixels Also 20 pixels # 1 inch # 1 millimeter # 1 pixel #20 printer points
20) '
20
#
'
"li") 'Im') 1)
"20p");
that a "p" designator
does not stand for
pixels, but printer points.
I
rec-
always using pixels as your unit of measure. Different screens display
different resolutions;
one screen might display an
and another might
actual inch
display something else.
Displaying in a Parent Other Than Your By
default,
Sometimes
when it
is
a widget
is
packed,
it
Own
packed inside the region
is
that created
it.
necessary to display a widget inside a different region. Use the -in
option to do so: -in => $otherwindow It
puts the
displays
it
new
widget
at
the
end of the packing order
for the
accordingly. All other options specified in the
pack
$otherwindow and ( )
call still
apply.
Methods Associated with Pack There are a few methods
that are
used
in conjunction
with the
pack geometry
manager. They allow the programmer to get information about either the widget that has
been packed or the parent widget
in
which other widgets are packed.
;
;
;
Chapter 2: Geometry Manageme nt
52
Unpacking a widget
To unpack
window
widget from a
a
$widget->packForget
(
or frame, use the
packForget method:
)
packForget makes it look like the widget disappears. The widget is not destroyed, but it is no longer managed by pack. The widget is removed from the packing order, so if it were repacked later, it would appear at the end of the packing order.
Retrieving pack information
To
return a
list
containing
all
the pack-configuration information about a widget,
use packinf o: ©list = $widget->packlnf o
The format of the current
( )
The first pair in the list is -in and $widget (usually also the parent). This is an information returned from packinf o:
the
list is
window
example of the
in option/value pairs.
that contains
-in MainWindow=HASH(0x818dcf4) -anchor n -expand -padx 10 -pady 10 -side left
From
this,
we
can
than a frame. Since the result
a
from packinf o
we packed
that
tell
list
-fill none -ipadx
our $widget into the main
has a "paired" quality to
it,
we
-ipady
window
rather
could easily store the
hash and reference the different option values by using
in a
key to the hash: %packinfo = $widget->packInfo; print "Side used: ", $packinfo{-side}
Disabling
and enabling automatic
,
"\n";
resizing
When you
put a widget inside a window, the window (or frame) will resize itself accommodate the widget. If you are dynamically placing widgets inside your window while the program is running, the window will seem to bounce from size to size. You can turn off this behavior by using packPropagate on the frame or to
toplevel widget:
$widget->packPropagate
(
)
'off, packPropagate changes the behavior of the widget so that it accommodate items packed inside of it. When a false value is sent to packPropagate before widgets are placed inside it, this automatic resizing doesn't happen, so you can't see any of the widgets placed inside the parent until it is manually resized. If you call packPropogate after the widgets have If set
to
or
doesn't resize to
been placed widgets.
inside
it,
the widget will ignore any size changes from
its
child
Pack
33
Listing widgets
You can determine
the widgets your frame or toplevel holds with the
packSlaves
method: @list = $parentwidget->pack;Slaves
packSlaves
returns an ordered
$parentwidget. An empty
;
of
the widgets that
all
empty
string (or
list)
is
were packed
returned
if
into the
no widgets were
$parentwidget.
packed
into
The
returned from
list
list
( )
packSlaves looks
like this:
Tk: :Button=HASH{0x81b2970) Tk: :Button=HASH(0x8116ccc) Tk: :Button=HASH(0x81bcdd4)
Each item
is
a reference to a
packed widget and can be used
to configure
it.
For
example, you can increase the size of each widget by 20 in both the x and y directions by looping through it and "packing" it with new information. Using our good
window example tine that uses
in Figure 2-4,
we
can add a button that
will contain a
subrou-
packSlaves:
$rnw->Button{-text => "Enlarge", -command => \&repack_kids) ->pack(-side => 'bottom', -anchor => center '
'
)
sub repack_kids { m/ @kids - $mM->packSlaves; f oreach @kids { $_->pack(-ipadx => 20, -ipady => 20); {
)
}
}
Figure 2-24 shows the resulting window.
i^
much more organized, and less haphazard used some options to make it look nice
This windov/ looks
because
J
1
like
we
it!
J
1
hate
it!
j
1
don't care
Exit
EtAar^e
Window
Figure 2-24.
Let's
look
at
Figure 2-25,
before pressing Enlarge button
what happens when we press the Enlarge button. As shown the widgets are
all
now
repacked with additional parameters of
-ipady => 20. These new options are in addition to any other widgets were packed with before. If an option is repeated, the last
-ipadx => 20, parameters the
in
one specified overrides the previous ones.
;
;
,
34
.
Chapter
Good
This
J
looks
we
like
Geometry Management
WMow
AA
much more organized, and less haphazard used some options to make it look nice
window because
I
2:
J
it!
I
hate
J
It!
I
don't care
Exit
Enlarge
Figure 2-25.
Window after pressing Enlarge
button
The window is suddenly huge! Subsequent presses of the Enlarge button will do nothing more to the window because all the widgets already have an -ipadx and -ipady of 20. If we wanted to always add 20 to the values of -ipadx and -ipady, we would have to request the current values and add 20 to them. Here's the code for that: sub repack_kids { my @kids - $inw->packSlaves; @kids { f oreach %packinf o = $_->packInf o $_->pack( -ipadx => 20 + $packinfo{ "-ipadx" -ipady => 20 t $packinfo{ "-ipady" (
)
( )
}
})
} }
We
use packlnfo to get the current configuration and add 20 to that value.
Grid The grid geometry manager
umns and rows sample
into a grid
composed
of col-
upper left-hand corner. Figure 2-26 shows
a
grid.
Rather than using the sides of a screen into columns and rows.
widget
window
divides the
starting at 0,0 in the
is
assigned a grid
cell
window It
as reference points,
looks a
lot like a
grid{) divides the
spreadsheet doesn't
using the options available to
grid
( )
it?
Each
Grid
35
Column
0,
RowO
Column
1,
RowO
Column
2,
RowO
Column
0,
Rowl
Column
1,
Row
1
Column
2,
Row
Column
0,
Row
2
Column
1,
Row
2
Column
2,
Row
2
Column
0,
Row
3
Column
1,
Row
3
Column
2,
Row
3
Figure 2-26. Diagram showing
The grid
method
( )
takes a
get at a time.* Here
is
$widgetl->grid(
[
A
window divided list
1
into grid
of widgets instead of operating
on only one wid-
the generic usage: $widget2,
.
7
.
/
option => value,
]
);
specific example:
$widgetl->grid($widget2, $widget3)
you can use one gridO call to display all three widgets. You can also invoke grid() on each widget independently just as Each call to grid will create another row in the window. So you can pack in our example, $widgetl, $widget2, and $widget3 will be placed in the first row. Another call to grid would create a second row. This is what happens when you do not specify any additional options to the grid call. Instead of using three separate
( )
calls,
( )
.
( )
For greater control, you can specify explicit -row and -column options for each
widget in the window.
I
will
cover these options
later.
These assumptions are made when additional options are not
The
•
first
widget
in the
grid
ple) invokes the •
All
( )
row (for example, $widgetl command.
( )
preceding exam-
command.
•
Each additional
•
Special characters can
call to
grid
( )
be used
will
to
add another row
to the display.
change the -columnspan and -rowspan of
the widget without using -columnspan or -rowspan
few examples
row, so
in the
remaining widgets for that row will be specified as arguments to the
grid
A
specified:
will
we know we
help demonstrate. Each
have two rows
call to
in the following
explicitly.
gridO
will create
another
example:
Create two rows, each with four widgets $widgetl->grid($widget2, $widget3, $widget4) $widget5->grid($widget6, $widget7, $widget8) #
*
Several people have told
not
how pack
is
me
that
normally used.
pack can
also take a
list
of widgets.
I
didn't cover this
because
it
is
)
;
36
Chapter 2: Geometry Management
we
In this example,
have created four rows and there
is
only one widget in each
row: Create four rows, each with one widget $widgetl->grid( $widget2 ->grid $widget3 ->grid $widget4->grid #
(
(
(
We
can also create widgets as
we
go:
$rnw->Button(-text => 'Buttonl', -command => $mw->Button(-text => 'Button2', $raw->Button(-text => 'Button3', $mw->Button(-text => 'Button4',
\&calll) ->grid( -command => \&call2), -command => \&call3), -command => \&call4)
)
third, and fourth calls to Button are All four of the buttons will be placed in the first row. If grid same exact command again, the new widgets would be placed in
Pay careful attention because the second, inside the call to
we
executed the
( )
.
the next row.
Special Characters There are several special characters that can be used to are gridded in the that indicates "
-
"
window. Each
what
to
do with
way
alter the
the widgets
special character serves as a type of placeholder
that position in the grid:
minus sign)
(a
Tells grid that the this
column
widget specified
as well.
get position to span.
right before this
one
To span more than one column,
A
"-"
may
in the
place a
"
should span
list
-
"
in
each wid-
not follow a "^" or an "x".
"X" Effectively leaves a blank space II
/S
where
a widget
would otherwise be
placed.
II
A
the II
x will span row x and jc + 1 when this character is placed grid command for row jc + 1 in that row/column position. The number
of
row
x.
widget in row -^
••
characters must match the
Similar to "-", but goes
The following
number
down, not
sections include
of columns the widget spans in
in
across.*
some examples
that illustrate
what the
special char-
acters do.
•
so
'"'" with Tk4.002, I got I used the special character you get this error also, check which version you have.
when if
a nasty core
dump. This
is
fixed in TkS.O,
37
Grid
Spanning columns
The following bit of code creates three rows of buttons. The first two rows are normal, and in the third, the second button spans three columns. Each "-" character adds one to the number of columns the button uses, and the default is 1. So the original column and two hyphens ("-"/•-") indicate that there are three columns to span. The -sticky option is necessary for the widgets to stick to the sides of the cells it spans. If the -sticky option had been left out, the button would be centered across the three cells it spans. $mw->Button(-text => ($mw->Button(-text $mw->Button(-text $mw->Button(-text
"Buttonl", -command => => "Button2", -command => "ButtonS", -command => "Button4", -command
sub
$mw->Button(-text => ($mw->Button(-text $mw->Button(-text $mw->Button(-text
"ButtonS", -command => => "Button6", -command => "Button?", -command => "ButtonS", -command
sub { exit } ->grid => sub { exit }), => sub { exit }), => sub { exit }));
exit } ->grid exit }), { exit }), { exit } { )
{
=> sub => sub => sub
)
)
)
$mw->Button(-text => "Button9", -command => sub { exit } ->grid $raw->Button -text => "ButtonlO", -command => sub { exit }), "-", "-", -sticky => "nsew"); )
(
(
The
resulting
window
is
shown
in Figure 2-27.
Buttonl
Buttons
Buttons
1
ButtonZ
Button3
Button4
Buttons
Button?
ButtonB
"nsew", -padx => 10, -pad/ => (
(
sub { exit })->grid => sub { exit }), => sub { exit }), => sub { exit }), 10);
$mw->Button(-text => "Buttons ", -conmand -> S"J3 exit crid $mw->Button -text => "ButtonS", -command => sub { exit }), $inw->Button(-text => "Button?", -comnand => sub { exit > ) $mw->Button(-text -> "ButtonS", -command => s^ib " exit } ) -sticky> "nsew" •;
(
(
)
^
€Mf Buttonl
ButtonZ
Buttons
^tton€
E)Biimite
,
Hi J
Buttons
BultWl4
Button?
Buttona 1
Figure 2-32. grid -padx
and -pady example
Specifying a Different Parent The -in option works the same way it does in pack(). The $widgec wiii be placed in $ot±ierwindow and not in the default parent of $widget. Here is the usage: -in => $otherwindow
Configuring Columns
and Rows
As with any of the geometry managers, grid has a few methods ated with
it.
Each method
screen by using
group of
is
Sometimes it grid makes up your grid.
cells that
( )
.
that are associ-
invoked via a widget that has been placed on the is
necessary to change the options of the
Grid
43
control resizing and the minimum size of a cell with the gridColumnconfigure and gridRowconfigure methods. Each takes a column or a row number as its first argument and then takes some optional arguments that will change the configuration of that column or row.
You can
Both gridColuranconfigure and gridRowconfigure work very similar to the
configure method used with
configure method used with and command. The options you gridRowconfigure cannot be used with the grid can use with gridColiomnconfigure and gridRowconfigure are -weight, widgets. Unlike the
widgets, however, the options you can specif}^ with gridCol\jinnconf igure ( )
-ininsize, and -pad. If
you send only
a
row
or
column number, an
array
is
returned with the current
options and their values for that method: @column_configs = $mw->gridColuiTinconf igure(O) @row_configs = $inw->gridRowconfigure(0) In this example,
and the
first
are getting the options
and
their values for the
first
row. The results of using the default values would look like
-minsize -minsize
You can
we
;
-pad -pad
column
this:
-weight -weight
get the value of only
one of the options by sending
that option as the
second argument: print $inw->gridColiiiTinconfigure(0, -weight), "\n"; print $rnw->gridRowconfigure(0, -weight), "\n";
The
results
To change
would
be:
the value of the options, use the option and then the value
associated with
it
immediately
after the option; for
-weight => $inw->gridRowconfigure(0, -weight => 1) $rnw->gridColuinnconfigure(0,
You can
also specify multiple options in
1)
you want
example:
;
;
one
call:
-weight => 1, -pad => 10); $inw->gridRowconfigure(0, -weight => 1, -pad => 10); $ir[w->gridColuitinconfigvire(0,
Now
that
we need
we know how to call gridColuranconfigure and gridRowconfigure, know what the three different options do.
to
Weight
The -weight option
when
the
window
is
sets
how much
divided into
space
cells.
is
to
be allocated to
Remember
to use
that
column or row
-sticky => "nsew"
in
)
;
;
;
;
44
Chapter 2: Geometry Management
grid command if you want the widget to resize when the cell does. The -weight is 0, which causes the column width or row height to be dictated by the largest widget in the column. Each -weight value has a relationship to the your
( )
default
other
-weights
in the
rows or columns.
column or row has a -weight of 2, it is twice has a -weight of 1. Columns or rows of -weight want all your widgets to resize in proportion to the your code before you call MainLoop: If
a
($columns, $rows) = $mw->gridSize() for ($i = 0; $i < $col\ainns; $i++) { $iiw->gridColuninconfigure($i, -weight =>
1)
column or row
as big as a
don't get resized at
all. If
window, add
size of the
that
you
this to
;
}
for ($i = 0; $i < $rows; $i++) { $mw->gridRowconfig\ire ($i, -weight => 1); }
-weight of 1 to every single row and column in the grid, is. Of course, this method only works if you want to each row and each column, but you get the idea.
This code will assign the
no matter what assign the same Here
size the grid size to
an example of
is
how
the
-weight
option works (Figure 2-33 shows the
result):
$inw->Button(-text => "Buttonl", -coinmand => ($iTiw->Button(-text => "Button2", -coinmand $inw->Button(-text => "Button3", -command $mw->Button(-text => "Button4", -command -sticky => "nsew"
sub { exit } ->grid => sub { exit }), => sub { exit }), => sub { exit }), )
)
$inw->Button(-text => "Button5", \
-coitiraand
=> sub
{
X $mw->Button -text -> "ButtonV", -command => s\ib $mw->Button -text => "Buttons", -command => sub -sticky => "nsew"
exit
}
)
->gr
,
(
(
exit }), exit }),
{ {
;
$mw->gridColumnconfigure(l, -weight => $mw->gridRowconfigure(l, -weight => 1)
By
giving
1
and column
1
a weight of
1
(whereas
all
weight), they take over any extra available space
have
dow
row
1)
other rows and columns
when
and 3 are only to draw the buttons and their text, but column 1 has filled same effect happens for row with a weight of and row 1.
is
(The
increased. Notice that
window
columns
0, 2,
as
the size of the win-
wide
as
is
necessary
in the extra space. 1
with a
new
The
weight of
has been resized larger to demonstrate the effects of -weight.)
45
Grid
GrtdExanf^ite
S3J'^
Buttoni
Buttons
Figure 2-33- gridRowconfigure
Minimum
J
1'
ButtonZ
Buttons
Button4
Button?
Buttona
and gridColumnconfigure example
cell size
The option -minsize sets the smallest width for the column or the smallest height for each row. The -minsize option takes a valid screen distance as a value. In this example, the minimum size of the cells in row and column is set to 10 pixels:
-minsize => 10); $inw->gridRowconfigure(0, -minsize => 10); $iTiw->gridColuiTinconfigure(0,
column or row was normally forced to be at least that large. If
the
less
than 10 pixels wide, then
it
would be
Padding
You can add padding around the widget and to the widget by using the -padx/y and -ipadx/y options. You can also add a similar type of padding by using the -pad option with the gridColumnconfigure and gridRowconfigure methods. The padding is added around the widget, not to the widget itself. When you call gridColumnconfigure, the -pad option will add padding to the left and right of the widget. Calling gridRowconfigure with -pad will add padding to the top and bottom of the widget. Here are two examples: $mw->gridColumnconfigure(0, -pad => 10); $mw->gridRowconfigure(0, -pad => 10);
Bounding box
To
find out
how
($xoffset,
large a cell
is,
you can use the gridBbox method:
$yoffset, $width,
$height) = $master->gridBbox(0, 2);
This example gets the bounding box for column
returned are in pixels.
The bounding box
will
and row
change as you
2.
All
resize the
the values
window. The
four values returned represent the x offset, the y offset, the cell width, and the cell
height (offsets are relative to the
window
or frame
where the widget
is
gridded).
; ;
;
;
;
46
Chapter 2: Geometry Management
Removing a Widget Like
packForget, gridForget causes the widget(s)
the screen. This the size of
may
or
may
not cause the
$widget and where
$rnw->gridForget
)
(
it
was on #
;
$widget->gridForget $widget->gridForget ($widgetl) $widget->gridForget $wl $w3); ( )
(
The widgets
are
,
undrawn from
#
# #
window
the
to
be removed from view on
to resize
window. Here
itself;
are
it
depends on
some examples:
Nothing happens $widget goes away $widget and $widgetl go away $widget, $wl, $w3 go away
the screen, but the cells they occupied remain.
Getting Information The gridlnfo method returns information about the $widget in a list format. Just as with packinf o, the first two elements indicate where the widget was placed: @list = $widget->gridlnf o
Here are some sample
(
)
from gridlnfo:
results
-in Tk: :Frame=HASH(0x81abc44) -column -row -coluninspan -ipadx -ipady -padx -pady -sticky nesw
1
-rowspan
2
Widget Location The gridLocation method
returns the
column and row of the widget nearest
the given (x, y) coordinates: ($column,
$row)
= $inaster->gridLocation($x,
Both $x and $y are ples, $inw).
$y)
in screen units relative to the
For locations above or to the
When
given the arguments
which
indicates the cell at
(0, 0),
left
master
of the grid,
our application returned
column
and row
window
-1 is
(in
our exam-
returned.
this:
0.
Propagation There
is
a
gridPropagate method
$master->gridPropagate
When
(
that
is
similar to
packPropagate:
)
given a false value, gridPropagate turns off geometry propagation, mean-
ing size information
propagation
is
rent value
returned.
is
is
not sent upward to the parent of $master. By default,
turned on.
If
gridPropagate
is
not given an argument, the cur-
47
Place
How Many Columns and Rows? To
find out
how
large the grid has
you can use gridSize
become
after placing
numerous widgets
in
it,
back the number of columns and the number of
to get
rows: ($coluiTins,
The
list
many
$rows)
= $inaster->gridSize
returned contains the
number
)
;
number of rows. In was four columns by two
of columns and then the
we had
of the earlier examples,
(
a grid size that
rows. ($c, It
$r)
= $f->gridSize();
#$c
=4,
$r =
2
not necessary for a widget to be placed in a column/row for
is
sidered a valid column/row.
If
-row=>5, -column=>4 and then
gridSize
you place
and
will return 5
a widget in
the only other widget
it
to
be con-
column 4 and row 5 using in row and column 0,
is
6.
Grid Slaves There are two ways to find out which widgets have been put frame. Use
gridSlaves without any arguments
to get the full
list
in a
window
or specify a
or
row
and column. Here are examples of both: ©slaves = $mw->gridSlaves print "@slaves\n"
( )
The preceding code would have printed
this:
Tk: :Button=HASH(0x81b6fb8) Tk: :Button=HASH(0x81ba454) Tk: :Button=HASH(0x81ba4cc) Tk: :Button=HASH(0x81ba538) Tk: :Button=HASH(0x81b6fa0) Tk: :Button=HASH(0x81ba5e0) Tk: :Button=HASH(0x81ba6dc) Tk: :Button=HASH(0x81ba748)
We
could have specified the widget in column
0,
row
0:
$widget = $niw->gridSlaves -row => 0, -column => print "$widget\n" # Would print this: Tk: :Button=HASH(0x81b6fb8) (
If
)
;
you specify only the -row option, you'll get a list containing only the widgets in The same goes for only specifying a -coluinn; your list will contain only
that row.
the widgets in that column.
Place The place
( )
geometry manager
is
different than
grid
( )
or
pack
( )
.
Rather than
referencing against a cell location or a window's side, most of the time you'll be
'
.
Chapter 2: Geometry Management
'^8
You can also grid
using a relative form of x and y coordinates. lap portions of widgets,
Invoking place
$widget->place
The options
[
(
isn't
allowed
in either
similar to calling the other
is
( )
which
specified
option => value,
when you
.
.
place
call
]
.
( )
use place or
pack
( )
to over-
( )
geometry managers: );
affect
( )
how
the widgets are put
on
the screen.
Place Options -anchor => center
'n'
|
'ne'
'e'
|
|
'se'
|
's'
'sw'
|
'w'
|
|
'nw'
|
'
Sets the position in the
widget that
-bordermode => 'Inside'
|
will
be placed
'outside'
at
the specified coordinates.
'ignore'
|
Determines whether or not the border portion of the widget
is
included in the
coordinate system.
-height => amount Sets the absolute height of the widget.
-in => $window Indicates that the child widget will
parent that created
it.
Any
be packed inside $window instead of
relative coordinates or sizes will
still
in the
refer to the
parent.
-relheight =>
ratio
Indicates that the height of the widget relates to the parent widget's height
by
ratio.
-relwidth =>
ratio
Indicates that the width of the widget relates to the parent widget's width ratio.
-relx => xratio Indicates that the widget will be placed relative to
its
parent by xratio.
its
parent by yratio.
-rely => yratio Indicates that the widget will be placed relative to
-width => amount Indicates that the width of the widget will
be amount.
-X => X Indicates that the widget will be placed at
x x is
any valid screen distance.
-y =>y Indicates that the widget will be placed at y.
y is any
valid screen distance.
by
49
Place
Absolute Coordinates The parent window
(or frame) has a standard coordinate system
the upper-left comer. as
The x values increase
you go down. See Figure
where
0,0
is
in
and the y values increase
2-34.
Figure 2-34. Coordinate system ofparent
To use
to the right,
window when
absolute coordinates to specify
where
absolute coordinates are used
to place the widget,
we would
use
options -X and -y: -X => X, -y =>
y
x and y are valid screen distances (for example, 5, which is in pixThe widget will have its anchor position (controlled by -anchor) placed at X and y coordinates. The default anchor is "nw"; the upper-left corner of the
Valid values for els).
the
widget.
Another major difference between place
() and the other geometry managers is two arguments are required when place () is invoked. There are no default values for the -x and -y options You will get an error if you try to invoke place with no arguments (for example, $widget->place()).
that at least
.
The simplest example of using -x and -y $mw->Button(-text -> "Exit", -command => sub
{
is
exit })->place(-x =>
As you would expect, the widget ends up as
shown
positioned
widget
0,
at 0,0:
-y =>
0)
in the upper-left corner of the
No matter what size Even when the window
in Figure 2-35. at (0,0).
to place a
the is
window, our widget
window
will
move.
widget
will not
Here
an example of using -x and -y to create some overlapping widgets:
is
$mw->Button(-text => -command $mw->Button(-text => -command
"Exit", => sub
{
exit })->place(-x => 10, -y => 10);
"Exit", => sub
{
exit })->place(-x => 20, -y => 20);
Figure 2-36 shows the resulting window.
remain
resized as small as possible, the
50
Chapter
2:
Geometry Management
1
^
Place
^,HI
Exaii^
Exit
1
Figure 2-35- Button placed using -x =>
-i
.
-y
0,
=>
Race Example
1^ Ji
Exit
Figure 2-36. Overlapping buttons with placeO
Relative Coordinates In
place
( )
,
there
is
an additional coordinate system defined for the parent wid-
get that allows relative placement within
it.
This coordinate system
is
shown
in
Figure 2-37.
x=
0.0
y=
0.0
"
child widget
nw
n
ne
w
center
e
sw
s
se
x=1.0 y=1.U Figure 2-3 7. The relative coordinate system
The
upper-left corner has the coordinates (0.0,0.0).
coordinates are (1.0,
1.0).
The middle of
the
The lower-right
window would be
coordinates are specified in floating point form to allow size
window. This allows the widget to remain no matter how the window is resized.
instance)
at that
place
( )
corner's
(0.5, 0.5).
to handle
The any
position (in the center, for
51
Place
It
valid to specify coordinates both smaller than 0.0
is
ever,
your widget most
you use
likely
out-of- range coordinates.
shown
in Figure 2-38:
$b = $rnw->Button(-text => "Exit", -command => sub $b->place(-relx => 0.5, -rely => 0.5);
Figure 2-38. Using place with -relx =>
Although the button
0.5, -rely
in Figure 2-38
is
window ril
instead of the center.
discuss shortly.
middle of the
window
If
we
{
exit
}
)
=> 0.5
placed in the middle of the screen,
off-center because the upper-left corner of the widget
the
Howwindow when
larger than 1.0.
won't be completely visible in the
This code snippet produces the button
which
and
You can change
resize this
was placed
this
in the
it
looks
middle of
with the -anchor option,
window, the button
still
stays in the
(see Figure 2-39).
-
^
Race Exanf^
J
Exit
Figure 2-39- -relx =>
0.5, -rely
=> 0.5 window resized larger
This next example creates two buttons, both placed in the
window
with relative
coordinates:
No
$mw->Button(-text -> "Exit", -command => siib
{
exit
}
$mw->Button(-text => "Exit", -command => sub
{
exit
}
matter what two buttons will
size the
window
is
or
)
)
->place -relx => 0.2, -rely => 0.2); (
->place(-relx => 0.5, -rely => 0.5)
where other widgets
are in the screen, the
stay in those relative locations (see Figure 2-40).
52
Chapter
Figure 2-40.
The ated. it
left
It
relative to the parent
window in Figure 2-40 right window is what smaller. Notice that
does so because
we
are
is
also
window
the default size of the
still
maintaining the ordered
window; the second Exit button (placed above the other button.
You can
Geometry Management
window when it was creit looks like after the window was resized to make the second button placed in the window remains on
The
much
top.
Two buttons placed
2:
at 0.5,0.5) is
list
drawn
of widgets in the
so
last,
it's
drawn
combine the absolute and
using both in the argument
relative coordinate systems simply by The relative coordinate system is considered first, added to that position. The options -relx => 0.5,
list.
and then the x or y value is -X => -10 means to place the widget 10 pixels
to the left of the
middle of the
window.
Anchoring the Widget Think of the child widget as a piece of paper tin
board (the board
is
that
you want
You have a You can put
the parent widget).
use to keep the paper up on the board.
to put
tack that
on your
you
bulle-
are going to
the tack right through the
comer The point where the tack is going to stick the paper to the board is the -anchor point. The -anchor point on the widget is "tacked" to the coordinates given by -x, -y or -relx, -rely. The default -anchor is "nw". Figure 2-37 shows these -anchor points within the child widget. center of the paper, in the upper-left corner ("nw"), or in the lower-right
("se").
It
is
important to
know where
the widget within the parent.
the
-anchor
is
because
it
will affect
how we
see
53
Place
^
Fface EK^npqple
^jj
-I
Flace Examtrie
^^
^
Exit
Exit
Figure 2-41. Different -anchor values affect where the widget In Figure 2-41, almost identical place
is
placed in the window
commands were used
in the window, but the -anchor value was changed. The was created with this command:
$inw->Button(-text => "Exit", -coinmand => sub
The window on the
exit
right in Figure 2-41
$rnw->Button(-text
}
)
left
->place(-relx => 0.5, -rely => 0.5)
used
this
window's button
;
command:
"Exit",
==>
-command =>
As with
{
to put the Exit button
siib
packO and gridO,
{
exit
}
)
->place(-relx => 0.5, -anchor => " center " -rely => 0.5)
the possible values for
-anchor
are:
'center', 'nw', 'sw', 'ne', and 'se'. However, the value
'w',
'n', 'e', 's',
now
applies to
the child widget instead of the position within the allocation rectangle.
Width and Height When you
use place
( )
,
you can specify the width and height of the widget
in
one of three ways:
own
•
Allow the widget
•
Specify width and/or height in absolute measurements.
•
to determine
its
size.
Specify width and/or height in relative measurements (relative to the parent widget).
To
let
the widgets determine their
own
other ways involve the options -width,
no options are specified at all. The -height and -relwidth, -relheight
size,
respectively.
The -width and -height options allow you of the widget in a screen distance: -width => amount, -height => amount
to specify the exact
width or height
;
54
Chapter 2: Geometry Management
Each amount
is
a valid screen distance (discussed eariier in this chapter
pack). The widget will be these sizes even
played in
it.
Our button looks
quite
silly
if it
under
cuts off edges of the items dis-
on the screen when we use
a
-width of
40 pixels (see Figure 2-42). $iTiw->Button(-text => "This Button Will Cause the Program to Exit", -command => sub { exit })->place(-x => 0, -y => 0, -width => 40)
Figure 2-42. Using -width with placeO
The other two
options,
-relwidth and -relheight, determine
the widget in
relation to the parent widget.
-relwidth => ratio, -relheight => ratio
The
A
ratio
is
number (similar to that specified by -relx or -rely). make the widget as wide (or as tall) as the parent widget. A make the widget half as wide as the parent (see Figure 2-43).
a floating point
value of 1.0 will
value of 0.5 will
f^i^e
Exan^iie
j
Hace Example
j]
Exit
Exit
Figure 2-43- Example of the
H-f
same window
The options -width and -relwidth -height and -relheight.
resized with -relwidth => 0.5, -relheight => 0.5
are additive
when used
together,
and so are
Border Options Normally, the border of the widget
is
used as the edge of the possible space
window, which means any widgets placed with
in the
either the absolute or relative
55
Place
coordinate system will be placed inside the border. This can be changed by using the
-bordermode
option:
-bordermode => 'inside'
'outside'
'
ignore
Using 'outside' will allow the coordinate system to use the space occupied by the border as well.
A
value of 'ignore' will have the coordinate system use the
space designated as the
X
official
area. Overall, this option
can see from the difference each makes on our example
is
pretty useless, as
you
in Figure 2-44.
Figure 2-44. -bordermode examples
If
you look very
closely (get out your magnifying glass),
'outside' version
is
'inside' version. This
two is
pixels higher
because on
and two
you can see
pixels to the
my window manager
(fvwni),
left
my
that the
than the
border
is
defined as 2 pixels.
Methods Associated with Place The methods
for
place
( )
are simple
and don't allow much manipulation of the
widgets.
Removing
the widget
As with pack and grid, there $widget->placeForget If
you use
the screen.
this It is
is
a
place
version of the
Forget method:
{ )
method on the widget, the widget will be removed from view on also removed from the list maintained by the parent widget.
Place information
The placeinf o method
returns a
@info = $widget->placelnf o print "@info"; ## Produced these results
-X
-relx
-y
-rely
list
of information related to the widget:
( )
(there are blanks where there are no values) -relwidth -height -relheight -anchor nw
-width
Place slaves @widgets = $parent->placeSlaves
( )
56
Chapter
2:
Geometry Management
placeSlaves returns a list of the slave widgets that are within $parent. The list looks the same as it does when it is returned from packSlaves or gridSlaves .X ( )
( )
Geometry Management Summary You now know more about the three need to know to write a successful hints •
different
( )
is
good
for general
you'll ever
some
Perl/Tk application. Here are
on deciding which geometry manager
pack
geometry managers than
helpful
to use:
purpose use and
will
be your choice around 95%
of the time. •
gridO
is
perfect for those situations in
columnar layout •
place
( )
size that it
•
is is
that
is
which you would
like to create a
similar to a spreadsheet.
most useful when you want your widgets relative to the
widget that created them.
to stay in a position or
When
it is
used
correctly,
can be very powerful.
No matter which manager you use, take the time to get the widgets on your window where they belong (or more likely, where you want them). There's nothing more unsettling than a button that looks like the
it
just doesn't
belong
in
window.
As you read through
this
book, you'll notice that some of the option names for the
geometry managers are also option names when you are creating or configuring
a
widget type. For example, you can specify the -width of a button without using
place
( )
.
Always keep
in
mind the context
times the functional difference
is
very subtle.
in
which the option
is
used.
Some-
The Basic Button
The Button Widget -^1^'
*^
..-
.
\.
Button Wfdget
S
Of
of the wideets available with Perl/Tk, the button
all
^, ,
,
the most commonly used. Geometry Management When the button _-.»™_™,-_.,-«™™™J
Just see
,
,
the examples
(as in
The button
one of 2,
our Hello World example) to
beginning a longer series of operations such as opening a process.
is
Chapter
in
pressed, something happens. That
is
something can vary from exiting the program
„ all
typically displays a short text string:
or starting another
file
Done, Apply, Save, Ok,
Exit.
Other widgets are also
as
classified
checkbuttons, and
radiobuttons,
buttons:
menubuttons. This chapter covers the traditional button. Chapter
and Radiobuttons, and Chapter
11
Menus,
,
will
4,
Checkbuttons
cover the other types because they
look different on the screen and behave differently as well.
We
cover the button widget
on the
screen.
affect
it
same
options. Usually,
will also
first
Many if
because
the option
be the same (more or
it
is
way
easy to see the
different options
of the other widgets included in Perl/Tk utilize the
name
is
the same, the change to the widget
less).
Creating a Button The
basic usage to create a button
is
$button = $parentwidget->Button
We
(
as follows: I
option => value,
have already seen examples of buttons
Chapter
1,
and
in all the
examples, a button
is
in
.
on the screen with
$niw->Button(-text => "Done" -coinmand => sub ,
{
.
]
);
our Hello World program
geometry management examples
created and placed
.
in
Chapter
a
command
2.
in
In these
like this:
exit })->pack;
57
58
Chapter 3' The Basic Button
You can
save a reference to the button like
this:
$button = $nw->Button(-text => "Done" -coinmand => sub ,
we
In Hello World,
need
didn't
ated
assume
exit })->pack;
to refer to the button again later, so
have made sense to save a reference ter will
{
to
wouldn't
it
But most of the examples for
it.
this
we've saved a reference to the button widget when
that
chap-
we
cre-
it.
Button Options The
chapter covers the options available to change the look of the but-
rest of this
ton and
how
to
make
it
do what you want.
-activebackground => Sets the color the
button.
A
color
is
color
background should be when the mouse cursor
-activeforeground => Sets the color the text
-anchor => center '
'n'
|
over the
color
should be
'ne'
|
'e'
when |
the
'se'
mouse |
cursor
's'
is
'sw'
\
over the button. |
'w'
|
'nw'
|
'
Causes the text to
-background => Sets the
is
a text string such as "red".
stick to the specified position in the button.
color
background of the button
to color.
-bitmap => 'bitmapname' Sets default
bitmap or the location of a bitmap
(with @ in front of path).
file
-borderwidth => amount Changes the width of the edge drawn around the button. (Emphasizes the -relief.) -command => callback Indicates a pointer to a function that will
-cursor => 'cursomame' Indicates that the mouse cursor
will
be called when the button
change
to
'
cursomame
the button.
-disabledforeground =>
color
Sets the color the text should
-font => 'fontname' Changes the font of
-foreground => Changes the
all
be when the button
the text
color
text color to color.
on the
button.
is
disabled.
'
is
pressed.
when over
59
The Button Widget
-height => amount Sets the height of the button in characters
distance
if
an image or bitmap
-highlightbackground =>
if
text
is
displayed,
and the screen
displayed.
is
color
behind the focus rectangle (shows
Sets the color of the area
when widget
does not have focus).
-highlightcolor =>
color
Sets the color of the focus rectangle.
-highlight thickness => amount Sets the thickness of the black box around
the button; indicates focus.
-image => $imgptr $ imgptr
is
a pointer to an
Image object
that
was made with
a
PPM/PGM
GIF or
file.
-justify => 'left'
'right'
|
-padx => amount Adds extra space
to the
left
'center'
|
Sets the side of the button against
which
and
multiline text will justify
itself.
right side of the button inside the button
edge.
-pady => amount Adds extra space
to the top
-relief => 'flat' Changes the
and bottom of the button inside the button edge.
'groove' 'raised' 'ridge' type of edges drawn around the button |
|
-state => 'normal'
'disabled'
|
|
|
'sunken'
|
'solid'
'active'
Indicates the button's state of responsiveness.
If set to
"disabled", the
but-
ton does not respond.
-takefocus =>
|
1
|
undef
Indicates that the button will never get focus (0), always get focus (1), or let
the application decide (undef).
-text => 'text' Sets the text string displayed
on the
button.
-textvariable => \$variable Pointer to a variable containing text to be displayed in button. Button text will
change as $variable does.
-underline => n Underlines the wth character in the text character
when
button has the focus.
string.
Allows keyboard input via that
60
Chapter 3' The Basic Button
-width => amount Sets the
width of the button
distance
if
in characters
an image or bitmap
is
if
text
is
displayed and as a screen
displayed.
-wraplength => amount
maximum amount
Sets the screen distance for the
of text displayed
on one
line. Default: 0.
Displaying Text know what
For the user to
when
the button does
cate the function of the button with
its
pressed, you need to indiThe option that does this is
it's
text string.
-text: -text => 'text'
When you the key.
come up with a descriptive text string, short and simple is want your button to take over the whole window with a long
are trying to
You
don't
text string.
The
string
can be anything: alphanumeric, newline(s), or variables. Just
other string in Perl, ble quotes,
the option
is
it
is
if it is
put in single quotes,
interpolated.
parsed).
If
The
it
is
interpolation only
taken
literally,
happens once (the
the variable changes later in the program,
like
any
and with dou-
it
first
time
has no effect
on the text in the button. The only way the text in the button can be changed after it has been created is by using the configure method to reset it (e.g., $button-> configure (-text => "newtext" or by using the -textvariable option. )
There
is
no
-text
is
not specified.
default for the
-text
; )
option; the button will simply have
no
text
if
The other way to display text on the button is by using the -textvariable option. The -textvariable option allows a scalar variable to be associated with the button; anything in the variable will be displayed on the button. Specify the scalar variable as follows:
-textvariable => \$variable
This
means the
change.
When
text of the button will
change as the contents of $variable
the text within the button changes, the button
or smaller, and the entire This piece of code
window may change
may become
size.
shows how the -textvariable option
is
used:
$count = 0; $mw->Button(-text -> "Add 1", -coinmand => sub { $count++ } ->pack(-side => 'left'); $mw->Button( -textvariable => \$count) ->pack(-side => 'left'); $inw->Button(-text => "Exit", -command => sub { exit } ->pack(-side => 'left'); )
)
larger
The Button Widget
61
shows two windows. The first window shows how it looks when it is first created, and the second window shows what it looks like after clicking on the "Add 1" button many times. Figure 3-1
1
.^
Biittori
Addl
Exani|^B|§ 1
1
-i Ghitton
Addl
Exit
1
Example IS
^
J
Exit
j
1
Figure 3-1- Example of using -textvariable
Displaying an Image or Bitmap Instead of Text Instead of displaying a text string
on the
button,
you can use the -image option
to
display an image: -image => $imgptr
GIF and images
PPM/PGM
module (Tk::JPEG), which
CPAN. Other types of images are are being developed. Check CPAN
When
JPEG download from more modules like Tk::JPEG
formats are valid image types. Support
in a separate
is
also supported as to see
what
is
is
available for
available for
currently available.
using an image, only the image will be displayed because the button can dis-
To create an $imgptr variable, use the Photo method (and supply the name and path if the image is not in the current directory) of the image fUe. The $imgptr is passed in as a value to the -image option: play only a text string or an image, not both.
$arrow = $niw->Photo(-file => "Xcamel.gif " $iitw->Button(-text => 'Exit', -command => sub -image => $ arrow) ->pack; )
;
{
exit
Figure 3-2 shows an example of a button with a GIF
_J Pf
J
file
},
on
it.*
J
Figure 3-2. Button with image instead of text
Use the -bit:map option
to allow a button to display a
bitmap specified
in a text
string:
-bitmap =>
*
'
hitmapnaiae'
When I tried this example under the Windows 95 OS, didn't get a good colonnap of the GIF file. Tlie probmy video card or video driver for Windows 95, so might look better on your machine.
lem may have been
I
it
,
62
Chapter 3: The Basic Button
There are several default bitmaps: error, grayl2, gray25, graySO, gray75, hourglass, info, questhead, question, and warning (see Figure 3-3). They are specified in the option by placing single quotes around the bitmap name: $rnw->Button( -bitmap => 'error',
To
specify a bitmap from a
file,
$iTiw->Button( -bitmap =>
-command => \&handle_error) ->pack;
you need
an ©
to put
in front of the path.
@/usr/nwalsh/mybitmap' -command => sub { exit })->pack;
Note (e.g.,
'
you use double quotes, you have "\@/usr/nwalsh/mybitimap")-
that, if
Figure 3-3-
Window showing
all the default
to escape the @ with a backslash,
bitmaps
Assigning a Callback In addition to the
-text
option, the
-command option
is
almost always used to
do something when pressed, we have to associ-command option. The callback happens when mouse button 1 is released over the button.' If you click down on the button but move the cursor away from the button before releasing, nothing happens because the mouse-click was aborted. create a button. For the button to
ate a callback with the button via the
In the Hello
World program, we used the exit routine
$mw->Button(-text => "Done", -command => sub
{
There are several ways to associate a subroutine or ton. This discussion will will see this
apply to
all
as our callback:
exit })->pack; set of
commands with
the but-
widgets that have a -command option, so you
option referred to often.
Defining a
-command Callback
There are several ways the callback can be defined: •
Anonymous
•
Reference to a subroutine:
•
Anonymous list
subroutine:
list
with the
e.g.,
sub
e.g.,
first
.
.
do something
.
.
}
\&rnysub
element as a subroutine pointer, and the
as arguments to the subroutine:
Mou.se button 1 is the Icftmo.st mou.sc buttcjn, button 3 is the rightmost moLise button. •
{
[
\&mysub, $argO, $argl,
mouse button
2
is
the middle
mouse
rest
of the
\@arg2
button,
.
.
.
]
and mouse
The Button Widget
63
The button we created in our Hello World program used an anonymous subroutine. Here is the code again: $mw->Button(-text => "Done", -command => sub
We
also could
})->pack;
exit;
have created the anonymous subroutine prior to the button
and sent the reference
ation
{
to
it
instead:
exit } { $mw->Button(-text => "Done", -command => $inysubref = s\ib
;
$rrr/s\ibref )
->pack;
This is useful when our anonymous subroutine does some fancy would look awkward shoved into the list of arguments.
We
things
could also create a regular subroutine to handle the exit and then
reference to
cre-
just
and
it
pass a
it:
do_exit { &do_something_else
Slab
exit; }
$mw->Button(-text => "Done", -command => \&do_exit )->pack; It
a
is
good
idea to use a subroutine like this
exit the application.
menu, If
a button, or the
we need
mous
list
to pass
if
you have more than one way
to
For instance, you could set up your application to exit via a
window manager
Close
arguments to our do_exit
command. ( )
routine
we would
use the anony-
form:
sub do_exit
{
my ($argl, $arg2)
= @_;
&do_something_else if ($argl = 12); exit; }
$mw->Button(-text => "Done", -command => \&do_exit, $argl, $arg2 [
It is
important to remember
scope and which
variables
how
the different
you can
ways
)
]
->pack;
to specify a callback affect the
access.
Anonymous subroutines Anonymous
subroutines merely get "set aside" to be called later from within
MainLoop. The commands inside the anonymous subroutine are not parsed then.
Any
variables
f oreach
you use
will not
©names { $mw->Button(-text => $_, -command => sub
}
(
be evaluated
until that time.
)
{
print "$_ was pressed! \n"; })->pack;
until
;
64
Chapter 3: The Basic Button
we are using the $_ variable in the for each loop. The be set as expected because the $_ is evaluated when the However, the $_ that is inside the scope of the anonymous sub-
In the preceding code, button's text string will
button
is
created.
routine doesn't get evaluated until the button
could be undefined and errors
start printing
is
actually pressed. At that point,
$_
out every time you click the button.
Subroutine references: arguments or no arguments
The subroutine reference and
the
anonymous
are very similar except the
list
list
allows additional arguments (especially ones from within the current scope) to be sent to the subroutine: f oreach
©names { $inw->Button(-text => $_, -coitmand => (
)
\&print_name, $_
[
]
)
->pack;
}
sub print_naine { print "$_[0] was pressed! \n" }
The anonymous that
$_
in the
set to the
list
gets created during the call to create the button. This
means
evaluated within the context of the f oreach loop and will be
list is
same value
-text option
as the
uses.
Those of you who are comfortable with creating anonymous subroutines on the fly can also do it this way: f oreach
©names { $mw->Button(-text => $_, -command => {
)
sub
[
$_
print "$_[0] was pressed! \n";
{ )
]
},
->pack;
}
The anonymous subroutine
is
the
first
item in the
list
list is the argument $_. Keep in more than a single print statement in the subroutine, and makes sense to put it in a named subroutine.
the second item in the
want
a lot
ity, it
This
-command option, and mind that sometimes you'll
to the
is
Perl/Tk.
for readabil-
meant to be a brief overview of anonymous subroutines as it relates to The Camel Book* has all the information you would ever want and more.
Disabling a Button When
a button
The button
will
is
created,
assigned callback
when
-state => "normal"
Technically
it
shows up on the screen by
default,
change colors when the mouse passes over
known
as
pushed. I
You can change
"disabled"
Programming
I
this
it
and
ready for action. will
perform the
by using the -state option:
"active"
Perl, also available
from O'Reilly
&
Associates, Inc.
The Button Widget
65
is when the mouse The "disabled" state is when the button appears grayed out (or with whatever colors have been specified by -disabledforeground and -disabledbackground) and will not respond to the mouse at all.
The "normal" cursor
A
is
state
was
described.
just
physically over the button
and
The "active"
is
used
button should not be available for selecting unless for example, a button that disables another
tion;
would look
state
internally.
it
makes sense
when
it
is
in the applica-
pressed.
The code
like this:
$niw->Button(-text => 'Exit', -cornmand => sub { exit } ->pack; $var = "Disable Exit"; $inw->Button(-textvariable => \$var, -conmand => sub { itr/ $state = $exit_b->configure -state) if ($state eq "disabled") { $exit_b->configure( -state => 'normal'); $var = "Disable Exit";
my $exit_b
=
)
(
;
else { $exit_b->configure( -state => 'disabled'); $var = "Enable Exit"; }})->pack; }
In this example, a reference to the Exit button
used
later to
change the
the scope of the
state of the button. Also,
anonymous
is
saved because
subroutine. This will only
the global scope of the entire program so that
it
note that $exit_b
$exit_b
work will
if
needs to be is
used inside
$exit_b
is left
in
be defined when the
anonymous subroutine is executed. Be careful to not set $exit_b to something else; if you do, when the anonymous subroutine is invoked, it will refer to the new value in $exit_b, not the one you wanted. Figure 3-4
shows the window
after
we have
clicked
on
the Disable Exit button
once.
Figure 3-4.
Window with
The configure worry about
By
how
it
disabled button (Exit)
method is explained works just yet.
disabling widgets
when
and normal button
later in this chapter;
you don't need
to
they can't do anything, you can give users visual hints
about what they can and cannot do
in the application.
;
66
Chapter 3' The Basic Button
Manipulating the Text In addition to displaying text in the button, tion of the text within the button.
-font option
to
change the
you can
appearance and loca-
alter the
The simplest thing you can do
is
to use the
font:
-font => 'fontname'
There are several ways to specify the
font. If you are using Tk4 (which is the current book is being written) you should follow the directions in the followparagraphs. If you are using the newest version of Perl/Tk, which includes TkS.O,*
version as the ing
you should see Appendix
The new
the
is
it
covers the
new methods
to use with fonts.
specified as a text string that contains a font name. There
way you
is
a differ-
Win32 systems and Unix systems. Valid fonts your Unix system can be obtained by using the xlsfonts command or by using Tk:: Fonts module. The default font for the button widget on my Unix system ist:
ence for
font
C, Fonts;
in the
specify fonts for
"-Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*"
Although
on a Win32 system, you need to send the -font option. Here's an example:
you'll see this default
type of string as the value to
a different
-font => "{Times New Roman} 12 {normal}"
You can look
in the Control Panel
under Fonts
to see
which
fonts are available.
window that shows the font in the differname of the font as it's listed in the Fonts directory for name between the curly braces. The number after the font
Double-clicking on them will bring up a ent sizes available. Use the the
first
name ally
is
part of the font
the size of the font in points.
normal,
italic,
The
third part
is
the type of the font, usu-
or bold.
There can only be a single font for each button, so the
text string
cannot change
font in the middle of a word. Each button (or widget) in an application can have a different font.
default font
Here
is
an example of two buttons
and the other with "lucidasans-14"
$mw->Button{-text => "Exit", -command => sub
(a
in a
window, one with the
Unix font) as
its
font:
->pack(-side => 'left', -fill => 'both', -expand =>
1)
$mw->Button(-text => "Exit", -font => "lucidasans-14", -command => sub { exit } ->pack(-side => 'left', -fill => 'both', -expand =>
1)
{
exit
)
}
,•
)
Figure 3-5
•
shows the
The numbering system 5, 6, and 7.
resulting
window.
for Perl/Tk follows the Tcl/Tk version
numbers.
I
have no idea
why
they
skipped
Not lowing
t
all
fonts are available
command
on every system, although your system's default should work. Use the folyour system: @config = $button->configure(-font)
to get the default font for
print "@config\n";
;
67
The Button Widget
~>
Button
Exit
J
1
-J
Exit
^
J .
Figure 3-5. Buttons with various fonts
you can also move the text around within word processing document, you can change where
In addition to changing the font,
button. As
you can
text will adjust
itself.
in a
The option
-justify => 'left'
The
default for
'
-justify
right is
that controls this '
'
|
center
is
the
the
-justify:
'
'center'. Normally, the text displayed
in a
button
is
a quick one- or two-word statement; for example, Exit, Done, Yes, No, or Cancel. The justification of the text isn't too obvious unless multiple lines of text are used. By default, the button will only display multiple lines if a \n is included in the string. You can have the program help decide when to wrap by using the -wraplength option:
-wraplength => amount
The amount Chapter will
This
indicates the
1). If
maximum
the length of the text string in the button exceeds this amount, the text
be wrapped around to the next an example
is
length of the line as a valid screen distance (see
that uses
line.
The
default for
-wraplength
is 0.
both the -justify and -wraplength options:
foreach (qw(left center right)) { $b = $inw->Button -text =>"This button will be justified $_" -command => sub { exit } -wraplength => 53, -justify => $_) ->pack(-side => 'left', -fill => 'both' -expand => 1) (
}
Figure 3-6
show
it,
it
shows the is
results of the three buttons.
possible for the text to be
-
J
ijQH
'blue'
and
J
-foreground => white'
-foreground and -background
options in conjunction with a
bitmap, the bitmap foreground and background will change to the specified colors.
The
effect of the colors
Figure 3-1
7.
'error'
depends on the bitmap. See Figure
bitmap with -foreground =>
when the
it
is
in the
'normal'
state.
When
and -background =>
'white'
The -foreground and -backgroimd options
These colors are
different
color,
-activeforeground =>
because
we want
mouse
cursor over
is it,
colors are used:
color
users to have
can press the button. By having the colors change
'black'
what color the button
control
the button has the
-activebackground and -active foreground -activebackground =>
3-17.
some
slightly
know that the button can be -activebackground is a slightly darker
visual clues that they
when
the
mouse
cursor
is
over the button, users
pressed to do something. The
default for
gray color ("#ececec")-
The
final color option,
button's state
is
-disabledforeground,
the color of the text
when
the
'disabled'.
-disabledforeground =>
When
is
color
it will not respond when the mouse cursor The default for the color of the text (or bitmap) is "#a3a3a3". Figure 3-18 shows the difference between the text colors with one disabled button and one normal button. (We also saw this example in Figure 3-4. Look there for the code that created this window.)
is
the button
over
it,
or
if it
is
is
in a disabled state,
pressed.
The Button Widget
75
Figure 3-18. -disabledforeground example
Changing the Mouse Cursor The mouse cursor normally looks like an arrow.* This can be changed on a widget-by-widget basis with the -cursor option: => cursomame
-cursor
When
the mouse is over the button, the cursor will change to the one specified. The cursor change will happen whether the button is disabled or not. There is a large set of available cursors. Following is a list of cursors, and Figure 3-19 shows what they look like.
X_cursor
arrow
based_arrow_down
based_arrow_up
boat
bogosity
bottom_left_corner
bottom_right_corner
bottom_side
bottom_tee
box_spiral
center_ptr
circle
clock
coffee_mug
cross
cross_reverse
crosshair
diamond_cross
dot
dotbox
double_arrow
draft_large
draft_small
draped_box
exchange
fleur
gobbler
gumby
handl
hand2
heart
icon
iron_cross
left_ptr
left_side
left_tee
leftbutton
ll_angle
lr_angle
man
middlebutton
mouse
pencil
pirate
plus
question_arrow
right_ptr
right_side
right_tee
rightbutton
rtl_logo
sailboat
sb_down_arrow
sb_h_double_arrow
sb_left_arrow
sb_right_arrow
sb_up_arrow
sb_v_double_arrow
shuttle
sizing
spider
spraycan
star
target
tcross
top_left_arrow
top_left_corner
top_right_corner
top_side
top_tee
trek
ul_angle
umbrella
ur_angle
watch
xterm
*
is
What
cursor
an arrow.
is
displayed
is
dependent on the window manager you are using, but most of the time
it
;
;
76
;
Chapter 3: The Basic Button
X ^ ±
J-
m
H-
^
D
SB
T
H
-
t
::3-
t
o
L^
ilTll
©
1J
^
/^
^ ^ ^ ^ ^
Q?
^\7
•
\new; $inw->Button(-text => "Exit", -command => sub { exit
)
}
->pack(-side => "bottom", -fill => "X")
$scroll = $mw->Scrollbar; $lb = $mw->Listbox{-selectmode => 'single', -yscrollcommand => [set => $scroll] $scroll->configure( -command => [yview => $lb]
)
)
$scroll->pack(-side => 'right', -fill => 'y'); $lb->pack{-side => 'left', -fill => 'both'); ## Open file that contains all available cursors ## Might have to change this if your cursorfont.h is elsewhere ## On Win32 systems look in C:\Perl\lib\site\Tk\Xll\cursorfont.h
open (FH, "/usr/XllR6/include/Xll/cursorfont.h" die "Couldn't open cursor file.Xn";
)
||
The Button Widget
while ()
77_
{
push((acursors,
if
$1)
(/\#define XC_(\w+)
/);
}
close (FH)
$lb->insert 'end' sort ©cursors) $lb->bind( '' sub { $ir[w->configure( -cursor => $lb->get ($lb->curselection) (
,
)
} )
;
;
MainLoop;
program might seem a
Although
this
a look at
how
does
Keep reading
okay. until
it
it
starts to
for a
sink
in.
box Widget, and bind
bit
complicated
at this
point in the book, take
you don't completely understand it right away, it's few chapters and then come back and look at it again
things. If
For reference, listboxes are covered in Chapter
is
covered
in
Chapter
7,
The
List-
Binding Events.
14,
Focus Options In an application,
you can tab between widgets
from the keyboard. The application indicates board input by drawing an outline around rectangle; see Figure 3-20).
If
the focus of the application. a specific
a
widget has
it
make them
available for input
widget
available for key-
in black (this
this outline
is
is
around
called the highlight it,
it is
(You can force the focus of an application
$widget->focus;
widget by using
to
that a
.)
Once
can use the spacebar on your keyboard to activate
1
it
said to
have
to start with
a button has the focus,
you
instead of using the mouse.
Exit
Exit
Figure 3-20. The first button has the input focus.
You can focus
force the application to not allow your button to receive the keyboard
at all
by using the -takef ecus option:
-takefocus =>
|
1
The -takefocus option
|
undef is
normally set to an empty string (undef), which allows
the application to dynamically decide
has
its
state set to
'disabled',
it
will
if
the widget will accept focus.
To have the application always through, use -takefocus => 0. To have the the widget, use -takefocus => 1. the widgets.
If
a widget
be skipped over when users tab through ignore the widget
when
all
tabbing
application always allow focus to
78
Chapter 3' The Basic Button
Altering the Highlight Rectangle The
highlight rectangle*
normally displayed with a thickness of 2 pixels. This
is
can be changed by using the -highlightthickness option: -highlightthickness => amount
The amount specified is any valid screen distance. In Figure 3-21, on the right has a -highlightthickness of 10 and has the focus.
Exit
i
the Exit button
Pi 1
Exit
Figure 3-21 Example of -highlightthickness => 10 .
When
the button doesn't have the keyboard focus, a small space
If this
extra space bothers you,
space won't display even
-highlightthickness The color of this:
if
to
you can
that if
is left
-highlightthickness to It is bad style also setting -takef ecus to 0.
set
widget has the focus.
you
aren't
the highlight rectangle can also be changed. There are
the color of the highlight rectangle
and the color of the highlight rectangle
-highlightcolor
when when
it.
and the to set the
two values
for
the button does not have the focus it
does have the focus. The option
the color of the highlight rectangle
is
around
when
the button does
have focus: -highlightcolor =>
color
shows the right button with the focus and with -highlightcolor 'yellow'. Compare it to the picture in Figure 3-21 to see the difference.
Figure 3-22 to
set
Exit
Exit
Figure 3-22. Example of button with -highlightcolor => 'yellow'
To change
the color of the space
focus, use the option
-highlightbackground =>
•
On Win32
left
around the button when
it
doesn't have the
-highlight±>ackground: color
system.s, the highlight rectangle
i.s
drawn
as a
dashed
line within the widget.
The Button Widget
79
Normally, the highlight rectangle
dow, which allows
it
to
blend in
same color as the background of the winwith the background of the window or frame that is
the
contains the button. Figure 3-23
shows an example where both buttons have the following
configuration:
-highlightcolor => 'blue', -highlightbackground => 'yellow'
The
right button
is
the
one
that has the focus.
Figure 3-25- Example of button with -highlightcolor => 'blue'
and -highlightbackground =>
'yellow'
Configuring a Button After creating the widget it
is
possible to use
and saving
methods on
a reference to
it
(such as $button),
in a scalar
that button.
There are two methods available to configure a button configuration information back:
after
it
is
configure and cget. They
created and to get are generic to
widgets and are covered in Appendix A, Configuring Widgets with configure cget.
common examples
Here are some
to get
you
started:
$state = $button->cget (-state) # Get the current $state = $button->configure -state) # Get the current $button->configure(-text => "New Text"); # Change the text $text = $button->cget (-text) # Get the current ©all = $button->conf igure # Get info on all (
( )
all
and
value for -state value for -state text value options for button
Flashing the Button The flash method will cause the button to appear to be "flashing" on the screen. It changes back and forth from the normal state colors to the active state colors: $button->flash()
Invoking the Button The invoke method invokes the subroutine to which the -command option points. Once you use -command to assign the callback, then anytime you need to perform that same task, you can use invoke ( )
$but ton- > invoke
( )
;
80
Chapter 3' The Basic Button
Some Fun Things One
to Try
of the best ways to figure out
how
Perl/Tk works
is
to try
it.
Once you under-
stand the basics, you'll spend most of your time tweaking options and callbacks to
do the •
correct thing.
Create a different
•
Create a
Here are some ways
window with three when clicked on.
to learn about the button widget:
buttons in
it.
Have each button
print
something
window with three buttons. Have the first two buttons change each when pressed. The last button should allow you to exit the program.
other's text •
Make some window.
really big buttons
and some
really tiny buttons all in the
same
Checkbuttons and Radiobuttons This chapter discusses both checkbutton and radiobutton widgets. Although they are very similar, they are used for different purposes.
Checkbuttons are useful as a
a
shopping
choice between Ql
when you want
to select as
many
items as you want, such
Radiobuttons are used in group situations
list.
items,
when you must make
such as on a multiple-choice exam:
What year did Columbus discover America?
:
1400 B) 1470 C) 1472 D) 1492
A)
E)
none of the above
Because radiobuttons are grouped together, you are forced to
one choice
in that group. If the default choice
would be automatically unclicked
is
always
select
A and you
one and only click
on D, A
(or unselected).
The two sections in this chapter cover how set them up and configure them.
to use
both widget types and ways to
The Checkbutton Widget \
_ Pi
In Chapter f
Checkbutton Widget
considered a type of button (and the
The Basic Button, you learned the options y f
3, ^'
^
associated with the button widget.
i
way
it
is
used
in
it
uses
an application
is
many
different
of the
same
A
checkbutton
options),
is
also
even though
from the way a standard button
is
used.
Instead of clicking ately,
you use
it
on
a checkbutton
to indicate a yes or
and expecting something
no answer.
If
to
happen immedi-
the checkbutton
is
checked
it
81
82
Chapter
means
unchecked means
yes;
The
no.
You might use
4:
Checkbuttons
and Radiobuttons
a checkbutton to
list
options for
on the checkbuttons might say Print Header Page, Even Pages Only, Odd Pages Only, and Number Pages. At the bottom of the window there would be a Print button, and when you clicked on it, the program would find out which checkbuttons were selected and submit the print job accordprinting a document.
text
ingly.
A window
buttons to ask the user job
name
run (like a batch job controller) might use check-
listing several jobs to if
each job should be run.
selected, the job will
is
be run.
If
the checkbutton next to the
the checkbutton
If
is
unselected, then the
job will be skipped this time around.
Each time a checkbutton
no
or
is
used, the application
question. Checkbuttons that
make up
is
button don't have
A
square on the
similar to a button;
it
side of the widget.
By
3D
left)
relief like a
left
mouse
same way
in the
button.
A
the indicator will look as If
if
it
a standard
like
it
is off, it
has
look
will
state of the
checkbutton
with color,
we
say
it
is
it
is
like a tiny
itself. If
checkbutton
window and
filled
is
on,
with a
gray button. is
the indicator's sta-
the checkbutton looks like
off (Figure 4-1; left checkbutton). If
on (Figure
it
own -relief (the way the been pushed down whereas a
state of the indicator. If the
a tiny raised button without color, then in
lit-
button does; you click on
has been pushed into the
the checkbutton
and the
also has an
its
Sometimes the terminology becomes confusing because there tus (or value)
it
edges of the check-
default, the outside
button will change
checkbutton will only change the darker color.'
displays a text string, but
standard button does, but the indicator (that
edges of the button are drawn) to look
is filled
each check-
does.
checkbutton operates
with the
to
independent of any other widgets or checkbuttons on the screen.
The checkbutton is indicator on the left tle
typically related (as in our
have to be because the answer
print job example), but they don't
button
asking the user to answer a yes
is
group are
a
4-1; right
it
checkbutton). The state of
the entire checkbutton (including the indicator) can be normal, active, or disabled. Both checkbuttons in Figure 4-1 have a state of normal.
J A
Figure 4-1.
*
Some
checkbutton that
operating
indicator to
show
m
Checkbutton Widget
.sy.stem.s
is
off and
actually put a
the state as on.
one that
checkmark
is
Checkbutton \Mdget
on
(t^) into the
little
box. Others
u.se a tiny "x" in
the
The Checkbutton Widget
83^
As when creating any widget, the checkbutton
created using a
is
method named
widget name, Checkbutton, invoked from the
after the capitalized version of the
parent widget. The basic usage looks like $cb = $parentwidget->Checkbutton(
this:
...
option => value,
[
)->pack;
7
In addition to having an indicator with a status, the checkbutton also can have a
callback that uses the -coitnnand option associated with is
it.
clicked (regardless of the indicator's status), the callback
When is
the checkbutton
invoked. However,
it
always necessary to associate a callback for radiobuttons and checkbuttons
isn't
since
you can
just
check the
status of the radiobutton or
checkbutton
later
on
in
the program.
The boolean status of the checkbutton is stored in a variable that you give via -variable option when it is created. Each checkbutton should have its own tus stored in is
its
own
When
unique variable.
the checkbutton
the sta-
clicked, the status
is
updated. In addition, any callback associated with the -coinmand option
invoked (regardless of the
change
new
status
The options
of the checkbutton).
a checkbutton's behavior are listed
below and explained
is
that
in greater detail
afterwards.
Checkbutton Options The following checkbutton options work exactly the same as a standard button, so I won't go over them in detail again. Refer to Chapter 3, for complete descriptions of these options: -activebackground, -activeforeground, -anchor, -background, -borderwidth, -cursor, -disabledforeground, -font, -foreground, -height, -highlightbackground, -highlightcolor, -highlightthickness, -justify, -padx, -pady, -state, -takefocus, -text, -textvariable, -underline, -width, and -wraplength. The
rest of the
options behave a
little
differently or are exclusive to the checkbut-
ton widget. They are covered in the following
Some
list.
options deal with only
-select image). Remember that the -state option refers to the entire checkbutton widget, and the status of the indicator is governed by the options -onvalue, -of fvalue, -indicatoron, and -variable. the indicator (such as
-activebackground =>
color
Sets the color the widget's
-activeforeground =>
background should be when the mouse
'n'
|
over
it.
color
Sets the color the widget's text
-anchor =>
is
'ne'
|
'e'
should be |
'se'
when j
'
mouse
the
s'
\
'sw'
over
is
|
'w'
it.
|
'nw'
|
'center' Sets the position of the text within the widget.
get
is
resized larger.
Most noticeable when the wid-
84
Chapter
Checkbuttons and Radiobuttons
4:
-backgroiand => color Sets the color of the
widget background (behind the
text).
-bitmap => bitmap Displays this bitmap instead of
text.
-borderwidth => amount Sets the
edge thickness of the widget. Also changes the thickness of the
cator. Default
indi-
is 2.
-coinmand => callback Associates a subroutine to the button. Called
when
button
is
clicked.
-cursor => cursomame Sets the cursor to
change
to
-disabledforeground => Sets the color of the text
cursomame when
it is
over the widget.
color
when -state
'disabled'.
is
-font => fontname
when
Sets the font to use
-foreground =>
displaying text in the widget.
color
Sets the color of the text.
-height => amount Sets the height of the button;
-highlightbackground =>
amount is
a valid screen distance.
color
around the widget should be when the
Sets the color the highlight rectangle
widget does not have focus.
-highlightcolor =>
color
Sets the color the highlight rectangle
around the window should be when the
widget does have focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle.
-image => imgptr Displays image instead of
-indicatoron =>
text.
1
|
Determines whether to display the indicator.
-justify => 'left'
|
'right'
|
'center'
Sets the justification of the text within the widget.
-offvalue => newvalue Sets the value
used when the button
is off.
Must be
a scalar. Default
is 0.
-onvalue => newvalue Sets the value
used when the button
is
on. Must
be a
scalar. Default is 1.
The Checkbutton Widget
85^
-padx => amount Sets the amount of space
between
left
and
text/indicator
left/right
edges of
widget.
-pady => amount Sets the amount of space
between
left
and top/bottom edges of
text/indicator
widget.
-relief => 'flat' 'groove' 'raised' Changes the look of the widget edges. |
|
-selectcolor =>
|
'ridge'
|
'sunken'
|
'solid'
color
when
Sets the color of the indicator
on.
-selectimage => imgptr Indicates the image to display instead of text
-image -state =>
is '
when
button
is
on. Ignored
if
not used.
normal
' ' |
disabled
'
' |
Sets the state of the widget. If disabled,
-takefocus => Determines
if
1
|
|
active it
will not
respond to any input.
\ixidef
the widget
is
available for focus or not.
-text => "text" Sets the text displayed in the widget.
-textvariable => \$variable Indicates that text in $variable
is
displayed as text in widget.
-underline => n Underlines the nxh character in the text
string.
-variable => \$value Associates the on/off value of indicator with $variable.
-width => amount Sets the
widget to
this width.
Can be any
valid screen distance.
-wraplength => amount Indicates that the text will
wrap when
it
exceeds
this
amount.
Storing the Indicator's Status The option -variable
will associate a variable with the status of the indicator
sending a reference as the value. To use the scalar $value, you would add the option
list
of the
Checkbutton
by
this to
call:
-variable => \$value Just as the
-textvariable option
sets the variable that
is
associated with the text
of the checkbutton, this option sets the variable associated with the indicator.
86
Chapter
When
is
clicked,
$value
cator (the value placed in
$value
is
the checkbutton
default are
1
and
now
will
Checkbuttons
mouse
$value
directly. If
contain the status of the indi-
defined by -onvalue and -of fvalue and
to
change the
status,
you can
You can
$value
specify
checkbutton, which will draw the checkbutton for the If
you change the value
=
your code contains $value
indicator will be turned on.
on.
in
$value
subroutine associated with -coinmand
Utilizing
on the
at
is
(if
any time
also
change the con-
some
there
1 before creating the
first
time with the indicator
after
one)
is
point, the
=
you
create the checkbut-
new
value.
not invoked
is
when
The the
changed.
-variable
is
usually the easiest
Here
is
an example
button.
by-
1 at
ton in your program, the checkbutton will change to reflect the
value of $value
and Radiobuttons
respectively).
In addition to using the tents of
4:
way
that has
to
check the
two buttons
status of the indicator
that
change the value
in
$cb_value: $cb_value = 0; $cb - $inw->C3ieckbutton(-text => "Checkbutton", -variable => \$cb_value, -command => sub { print "Clicked! $cb_value\n" ->pack(-side => 'top');
}
)
$mw->Button(-text => -command $mw->Button(-text => -command
"CB on", => sub { $cb_value = "CB off", => sub { $cb_value =
1
})
->pack(-side => 'left');
})
->pack(-side => 'left');
See Figure 4-2 for the resulting window.
iQiBcklmttoil -|_j
H
Checkbutton
CBoff
i
CBon
Figure 4-2. Buttons changing the value of a checkbutton
The value stored
in
$cb_value can be changed
checkbutton, clicking on the "CB
Only when you in the shell
click
off" button,
in three
or clicking
ways: clicking on the
on the "CB on"
on the checkbutton will you see the word it was run.
button.
"Clicked!" written
window from which
There are other ways to change the value associated with the checkbutton. See invoke, select, deselect, and toggle chapter.
in
"Checkbutton Methods"
later in this
87
The Checkbutton Widget
Assigning a Callback The -command option works
just like
it
does for a standard button, but usually the
function associated with a checkbutton's callback does something less obvious.
Many
times, there
is
no
important information
checkbutton was
One
callback at
all
associated with the checkbutton because the
the status of the checkbutton rather than whether the
is
just clicked.
of the things a checkbutton might
The checkbutton might look something
do
is
alter the
like the
one
appearance of the window.
in Figure 4-3-
l^iect'dbuttiro^T^
Show
all
widgets
Figure 4-5- Checkbutton that will display other widgets on the screen
When
the user clicks
changes to look
on the checkbutton
on, our
it
clicked
window
like Figure 4-4.
if
Show
ButtonZ
Buttoni
Window after clicking
Here's the code that
^31
ChecklHitton
...
Figure 4-4.
to turn
when
makes
all
widgets
Buttons
Button4
the checkbutton
the magic happen:
#! /usr /bin/perl -w use Tk; $ir[w = MainWindow->new; $mw->title "Checkbutton" (
)
## Create other widgets, but don't pack them yet! for ($i =1; $i Button(-text => "Button$i" }
$ir[w->Checkbutton(-text => "Show all widgets", -variable => \$cb_value, -command => sub { if
($cb_value)
{
foreach (©buttons) { $_->pack(-side => 'left'); } }
else { foreach (©buttons)
{
)
)
Buttons
magically
;
88
Chapter
$_->pack
forget
( '
'
)
;
'
)
4:
Checkbuttons and Radiobuttons
} } )
}
->pack -side => (
'
top
MainLoop;
So
we
can display some widgets
later
on
in the
program,
we
create
them ahead of
time and store references to them in the ©buttons array. The buttons in this
example
because they don't even have a -command associated
aren't very useful
with them. Normally, they would each have a specific task they would perform
when
pressed; however, for our example,
Then we
indicator),
its
it
just
When
magic checkbutton.
create our
the status of
we
want them
the button
is
to exist.
clicked (regardless of
pointed to by -command. Our
will call the subroutine
shows the buttons if it is on, changed before this subroutine is called. When our checkbutton is clicked again, the extra buttons will be removed from the window and the window will shrink back to the size it was presubroutine looks
and hides them
the current value of $cb_value,
at
if it is off.
The value
in
$cb_value
is
viously.
great when you want to keep a basic window uncluttered but show more widgets if the user can handle the advanced functions of the extra widgets. For example, you can create a Find window that has a place to enter some text, a button to start the find, and an Advanced Search checkbutton. Clicking on Advanced Search would add some more widgets to the bottom of the window allowing you to match case, use regular expressions, and use
This type of setup
want the
is
ability to
other fancy search mechanisms.
On and If
Off Values
you don't
change
like the default
-onvalue => newvalue
The same
is
These options
you would it
long as
hashes It
If
1,
you can use the -onvalue option
to
will
like the
if
is
## Default is
change the values stored checkbutton
makes sense it
## Default is 1
true of the off value:
-offvalue => newvalue
times
on value of
it:
to use different values.
a scalar value. This
you
really
want
in
$variable. Depending on
to interact with the rest of
means
that
how
your application, some-
The newvalue could be anything, as you can use references to arrays and
to.
good practice to keep the meaning of -onvalue the opposite of -offvalue. -onvalue is now the string "ON", logically -offvalue should be "OFF". Of
is
89
The Checkbutton Widget
course,
if
the purpose of this checkbutton
is
to use a
more accurate value of
7C,
then -onvalue could be "3.14159265359", and -offvalue could be "3.14".
Be
careful
when you
use unusual values for -onvalue and -offvalue.
the variable to something that doesn't equal either
If you set one of them, the checkbutton
even though the value of the $variable will not equal the -offvalue value. For instance, if you set -onvalue => 1, -offvalue => 0, and
will
be considered
you
set
off,
$variable
to
3,
then the checkbutton will be considered
off.
Indicator Color You can use the -selectcolor option when the checkbutton is selected: -selectcolor =>
to alter the color that
fills
in the indicator
color
The default value is "#b03060" (a dark pink color). Changing the value for -selectcolor will also change the background of the button when the button is selected and -indicatoron => .
Hiding the Indicator One
of the ways a checkbutton
different
Use the -indicatoron option
tor.
square button
at
we
(i.e.,
to
from a standard button
|
have seen from the previous examples, the default for -indicatoron
show
the indicator).
If
we change
this
-indicatoron
look almost like a normal button (without quite as though). Even though
it
looks a
Note
Figure 4-5). is
that
lot like a
which
clicked (to turn the indicator,
-indicatoron
the
is
Figure 4-5- Checkbutton with -indicatoron => checked.
is 1
checkbutton
much space around the its behavior when it
hidden, to on) is
is
completely different
ignored completely
when
set to 0.
js^^^^HEZG ifj^^^«^
Checkbutton NMdgetl
is
to 0, the
regular button,
-relief option
C2ieckiHJtton
right
little
1
text,
(see
the indica-
Perl/Tk not to draw that funny
tell
will
is
is
all:
-indicatoron =>
As
is
0.
Window on
left is
unchecked.
Window on
;
;
90
Chapter
4:
Checkbuttons and Radiobuttons
background on the checked button is the -selectcolor, not the -backgroundcolor. You might want to use the nonindicator configuration if you change the text of the button to reflect the new state of In this example, the color for the
the checkbutton. For instance, change Logging Enabled to Logging Disabled.
Displaying a Picture Instead of Text As you can with image
a
normal button, you can use the -image option to display an
in place of the text
on
available to display a different
-image => $imgptr
a checkbutton.
Another option, -selectimage,
image when the checkbutton has been
-selectiinage => $imgptr
[
The usage statement shows -selectimage if -image is not used.
is
clicked:
]
as optional because
it
will
be ignored
The imgptrs can be created by using the same methods as those used in Chapters with a button's -image option: $arrow = $mw->Photo(-file => "nextart gif " )
.
The image
be put
will
in place of the text
precedence over the -text option, so
-text option
will
if
on the checkbutton. These options have both -text and -image are listed, the
be ignored.
Which image is displayed depends on whether the button is on or off. If only the -image option is specified, this image will be displayed no matter what. If -selectimage is also specified, the image associated with it will be displayed when the button is checked. Figure ^-d shows an example that uses both options.
~i C3l
J
-.
J
-.Ch -.jj
\
Exit
Figure 4-6. The
same window
X Exit
with the checkbutton unchecked (on the
left)
and checked (on
the right)
The checkbuttons
in Figure 4-6
were created with
this
code snippet:
$imgl = $raw->Bitmap(-file => "/usr/XllRe/include/Xll/bitinaps/lineOp.xtm") $iing2 = $mw->Bitmap(-file => "/usr/XllR6/include/Xll/bit:inaps/xlogo32")
$rnw->Checkbutton(-text => "Checkbutton", -image => $imgl, -selectimage => $img2, -variable => \$cb_value) ->pack(-side => 'top');
;
The Checkbutton Widget
9J_
Using two different images to indicate whether the checkbutton
make more sense you want
if
you
is
off or
on might
-indicatoron and set it to 0. For instance, if document is locked (read-only) or unlocked you could -image and a picture of a lock with a line through it for
also use
to indicate that a
use a picture of a lock for
-selectimage. For
this
example,
I
chose to use bitmap
files
as our images. Instead of using the
-image option to display a bitmap, you could use the -bitmap option directly. The -bitmap option is exactly the same as the standard button -bitmap option; it replaces the text of the button with the specified bitmap (see Figure 4-7).
Figure 4-7. Checkbutton with -bitmap => 'warning'
Unlike -image and -selectimage, using -bitimap will not change the image
when
the button
You might
is
clicked
on or
off.
would make your application understand. However, if you use too many
think that using images instead of text
easier for non-English speakers to
A few
checkbuttons with images, you might confuse people even more.
easily
understood icons are better than a large collection of vague icons.
Checkbutton
Style
Although the button and checkbutton both share the -relief and options,
and they mean the exact same
ton, the effects are visually different
thing,
when
because of the
-borderwidth
they are used with a checkbut-
indicator.
As a reminder, the
possi-
ble values are:
-relief => 'flat' 'groove' -borderwidth => amount |
|
'raised'
|
when
Figure 4-8 shows the different relief types used.
The
default for a checkbutton
is
'
'ridge'
flat
'
|
'sunken'
a default
|
'solid'
-borderwidth value
because the
relief
edge of the checkbutton doesn't change when the checkbutton
is
is
of the outside
clicked; only the
shows that the edges of the checkbutton are to the text; the -padx and -pady default values are smaller than the button. The -relief option does not affect the indicator.
indicator changes. Figure 4-8 also
much
closer
default for a
The -borderwidth option
affects
both the outside edge of the checkbutton and
the indicator inside the checkbutton.
The
indicator itself stays the
same
size
no
92
Chapter
4:
Checkbuttons and Radiobuttons
'^
\4^
:
groove
flat
raised
sunken
ridge
Figure 4-8. Example of all possible -relief types
matter what the borderwidth of the widget width.
When you
shown
in Figure 4-9.
is,
but the indicator's edges change in
use a large -borderwidth, you get some interesting
QiecHbutton
-J
^
results, as
J J
:
J
groove
flat
raised
ridge
{
ijt
sunken
Figure 4-9. Example using -borderwidth => 4
We
used a -borderwidth of
thicker, is
much
in the
4, and you can see that the outside edges got a bit and so did the edges of the indicator. With a larger -borderwidth, there
less
room
to
middle of those
show
the indicator's color
when
is
it
on
(see the tiny square
indicators?).
!
QiecktHJtton
'-J
groove
flat
raised
J •
iB
,
sunken
ridge
Figure 4-10. Example using -borderwidth => 10
In Figure 4-10,
We
we
When
at all,
10.
Notice the remarkable difference!
even though there
these checkbuttons are checked or unchecked, there
the current state I
used a -borderwidth of
can no longer see the indicator
highly
it
is
because the indicator
recommend
that
is
is still is
space
no way
to
for
left tell
it.
what
essentially invisible.
you do not use the -borderwidth option associated
with a checkbutton because of
this interesting side effect.
Configuring a Checkbutton methods
Like the button widget, the checkbutton has is
created.
ated,
These methods can be invoked
even before
it
is
at
any time
that
after the
it
checkbutton
after is
it
cre-
displayed on the screen.
You can use both configure and cget methods with These methods are explained
and cget.
can manipulate
in
Appendix
a checkbutton as well.
A, Configuring Widgets with configure
The Radiobutton Widget
93
Turning a Cbeckbutton
On and
You can
go from on
force the checkbutton to
Off to off or vice versa using the
dese-
lect and select methods.
The deselect method will always set the indicator to the able assigned by -variable to the value in -of fvalue: $cb->deselect
vari-
the indicator to be set to the
on
the -onvalue:
)
(
Both methods are ignored
You can
and the
( )
The opposite of deselect, select will cause state and the variable assigned by -variable to $cb->select
off state
if
-state
also toggle the indicator
is
'disabled'.
from on to
off or vice versa using the
toggle
method: $cb->toggle Calling to
be
{ )
toggle does not cause
the subroutine associated with the
-command value
called.
Flashing the Checkbutton You can make ors
by
the indicator flash with the
-background and -foreground
col-
calling flash:
$cb->flash();
Invoking the Checkbutton To perform ton, call
the
$cb->invoke It
will
same
action as clicking the checkbutton with the
mouse
left
but-
invoke: { )
cause any callback associated with -command to be called;
the state of the indicator from
on
it
will also switch
to off or vice versa.
The Radiobutton Widget A
radiobutton looks similar to a checkbutton because
it
also has
Radiobutton
an indicator on the
mond,
rather than a square.
left side.
The radiobutton
Both look 3D and are
slightly raised
indicator
when
is
a dia-
unselected.
94
Chapter
The main
difference
between
A
serve in an application.
a radiobutton
radiobutton
and
a
checkbutton
used to
is
Checkbuttons and Radiobuttons
4:
select
the function they
is
one of several
different
choices: •
In a multiple choice
•
Which version of
•
Your income
•
Which type
the answers A, B, C, D, or E
test,
you would
a tool
like to
use
range: 0-20,000; 20,001-30,000; 30,001^0,000; 40,000
you
of entree
In each example, only
prefer: beef, chicken, or vegetarian
one answer
is
appropriate. For instance,
sense to have a salary of both $18,000 and $33,000. multiple-choice gives
you
test,
credit.
you
can't select
You have
all
it
wouldn't
And when you
the answers and
hope
make
are taking a
that the teacher
to pick only one.
Because radiobuttons are used always create
and up
at least two.*
It
to decide
doesn't
between several choices, you should
make sense
to ask a question at
there
all if
is
only one choice. Radiobuttons should always be created in groups of two or more.
Creating Radiobuttons So
far,
always
you have learned in a group,
we
to create
one widget
at a time.
Because radiobuttons are
more than one at quickly and painlessly
generally need to create
and create all the widgets as show you some quick ways to make up a group of radiobuttons. can be
efficient
(To show you
how
of widget creation and that
more complicated. By now, you should know
how
an option works exactly
ter for a
more complete
as possible,
I'll
advantage of the widgets in the best way, the exam-
to take
ples will start to get a bit
So you
a time.
to specify options during the creation. like
did with widget
it
X and
refer
you
I'll
the basics often say
to that chap-
discussion.)
Radiobuttons are similar to checkbuttons; they also have a $variable associated with the state of the indicator (using the option -variable).
group of radiobuttons, use the same $variable group.
The value put
radiobutton the
is
new group
selected.
into
To
the
$variable
create a
will
new group
When you
create a
for every radiobutton in the
change according
to
which
of radiobuttons, simply associate
with a different $variable.
Because each radiobutton
in a
group points
to the
same $variable,
there
isn't
a
concept of onvalue and offvalue. The offvalue would be whatever the other radiobutton wanted
it
to be.
To accomplish
this,
radiobuttons use the option
-value instead of -onvalue and -offvalue.
•
If
with
create only one radiobutton, it would stan out un.sclcctcd (unlcs.s the variable you a.s.sociated contained the on value). Once that radiobutton wa.s .selected, you would never be able to deselect it.
you did it
95
The Radiobutton Widget
For our
first
example, we'll create a group of radiobuttons that indicate the back-
ground color of our window. We need configure -background => color) (
work, so
we
will
for creating a radiobutton
$rb = $parentwidget->Radiobutton(
Here
is
command. Simple
names
color
usually
use red, yellow, green, blue, and gray.
As always, the basic usage
ground
to use colors that are valid to the $inw->
[
is
as follows:
option => value,
...
7
)->pack;
the code that will create the radiobutton group that controls the backcolor:
setup the default value we would like $rb_value = "red"; $mw->configure -background => $rb_value) #
(
create the radiobuttons that will let us change it foreach (qw(red yellow green blue grey)) { $niw->Radiobutton(-text => $_, -value => $_, -variable => \$rb_value, -cornmand => \&set_bg) ->pack -side =>
#
(
'
left
'
)
;
}
function to change the background color using $rb_value set_bg { print "Background value is now: $rb_value\n" $inw->configure( -background => $rb_value)
#
s\ib
;
}
We
are storing the status of our radiobutton
initial
ing.
group
value of "red", which happens to match the
When
in
We
$rb_value.
first
radiobutton
set
we
it
to
an
are creat-
any of the radiobuttons are clicked, including the one currently
selected, the subroutine
set_bg
will
be
called. This subroutine will print the
window
value of $rb_value and then change the background of our main
new
to that
color.
One
thing to note: Although
"red", that doesn't
mean
we
set the default
that the
value of our radiobutton group to
background of the window has been
set to
red
We
do this by calling the configure command and sending it the value in $rb_value. We could also do it by an explicit call to the set_bg routine, or we could have done it when we created the Main Window. as well.
The window we have created looks
Radiobutton
ii •
^
like Figure 4-11.
red
v- yellow
green
^
bUje
grey
J
Exit
j .
1
Figure 4-11. Radiobuttons that will change the background color of the
window
96
Chapter
The run
way
best
on each radiobutton,
change
window works is to type in the code and shown in this book. When you strip of the window at the top and bottom
this
you'll see a
color. You'll only see this small strip
because
ground of $mw, not of each radiobutton or the
Now
Checkbuttons and Radiobuttons
This will be true for a lot of the examples
it.
click
how
to understand
4:
we
exit button.
we've seen a basic application of radiobuttons,
that
only changed the back-
we
can go over each of
the options.
Radiobutton Options As with the checkbutton, the following options are the same
any of the three
for
types of buttons: -activebackground, -activeforeground, -anchor, -back-
ground, -borderwidth, -cursor, -disabledforeground, -font, -foreground,
-height, -highlightbackground, -highlightcolor, -highlightthickness, -padx, -pady, -state, -takefocus, -text, -textvariable, -underline, and
-width.
same between checkbutton and radiobutton: -command, -indicatoron, -image, -selectimage, -bitmap, -wraplength, -justify, and -selectcolor. In
The
rest
text in
I
following
the
addition,
bit differently
-activeforeground =>
background should be when mouse
'n'
|
'ne'
|
'e'
should be |
'se'
when
over
it.
|
mouse
the
's'
|
'sw'
over
is
|
'w'
it.
|
'nw'
|
'
Sets the position of the text within the widget. is
is
color
Sets the color the widget's text
get
because of the con-
color
Sets the color the widget's
'
the
are using them.
-activebackground =>
-anchor => center
are
because they behave a
will discuss
which we
options
Most noticeable when the wid-
resized larger.
-background =>
color
Sets the color of the
widget background (behind the
text).
-bit:map => bitmapname Displays this bitmap instead of
text.
-borderwidth => amount Sets the
edge thickness of the widget. Also changes the thickness of the
cator. Default
is 2.
-command => callback Associates a subroutine to the button. Called
when
the button
is
clicked.
indi-
97
The Radiobutton Widget
-cursor => cursomame
cursomame when
Indicates that the cursor will change to
it
is
over the
widget.
-disabledforeground =>
color
Sets the color of the text
when -state
is
'
disabled'
-font => fontname
when
Sets the font to use
-foreground =>
displaying text in the widget.
color
Sets the color of the text.
-height => amount Sets the height of the button;
-highlightbackground =>
amount is
a valid screen distance.
color
around the widget should be when the
Sets the color the highlight rectangle
widget does not have focus.
-highlightcolor =>
color
Sets the color the highlight rectangle
around the window should be when the
widget does have focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle.
-image => imgptr Indicates that an
image
-indicatoron =>
|
is
displayed instead of
1
means
Indicates the status of the indicator;
-justify => 'center'
text.
|
'left'
|
indicator
not displayed.
is
'right'
Sets the justification of the text within the widget.
-padx => amount Sets the amount of space
left
between
text/indicator
and
left/right
edges of the
widget.
-pady => amount Sets the amount of space
left
between
text/indicator
and top/bottom edges of
widget.
-relief => 'flat' 'groove' 'raised' Changes the look of the widget edges. |
|
-selectcolor =>
|
'ridge'
color
Sets the color the indicator should
be when on.
|
'sunken'
|
'solid'
98
Chapter
Checkbuttons and Radiobuttons
4:
-selectimage => imgptr image should be displayed instead of
Indicates that an on. Ignored
if
-image
-state => 'normal'
is
'active'
|
Sets the state of the widget.
-takefocus =>
|
1
|
|
when
the button
is
'disabled'
disabled,
If
it
will not
respond to any input.
xixidef
Determines whether the widget
-text =>
text
not used.
is
available for focus or not.
textstring
Sets the text displayed in the widget.
-textvariable => \$variable Indicates that the text in $variable
displayed as text in the widget.
is
-underline => n Underlines the nth character in the text
string.
-value => newvalue Sets the value assigned to
radiobutton
is
$variable
selected (default
(set
with -variable option)
when
this
is 1).
-variable => \$variable Sets the variable to use
when
this
radiobutton
is
clicked.
-width => amount Sets the
width of the widget. Can be any valid screen distance.
-wraplength => amount Indicates that the text will
wrap when
it
exceeds
this
amount.
Using the -variable Option The -variable option will look the same in each radiobutton creation command, except logically, we are using it differently. We should have several radiobuttons sharing the same $variable instead of each one having their own distinct $variable. The example for Figure 4-11 shows how this works.
Setting the Value With checkbuttons,
had
we
to
we had two
worry about the
state of
options,
-onvalue and -of fvalue, because we
each individual checkbutton. With radiobuttons,
only care about the state of the whole group. Each radiobutton should have a
different
-value
to
it,
so a glance
at
$variable
will tell us
which radiobutton
is
selected.
The default -value is 1. (Remember: When you use one radiobutton, that one is always checked.)
a
group
that consists of only
99
The Radiobutton Widget
To make sure you understand the difference between the -value option, let's walk through a short example.
the
-variable option and
$inw->Radiobutton(-text => "Beef", -value => "Beef", -variable => \$entree) $ir[w->Radiobutton(-text => "Chicken", -value => "Chicken", -variable => \$entree) $rnw->Radiobutton(-text => "Vegetarian", -value => "Vegetarian", -variable => \$entree)
Here
we
have created three radiobuttons
that
their values in. If the user selects Beef, then
"Beef".
If
the user selects Chicken, then
"Chicken". Later printer,
we
can
in
just
the
all
use the variable $ entree to store
$entree will contain the value of $entree will contain the value of
program when we build the physical menu
check to see what
is
in
$entree
to find out
what
for the
that user
wants for dinner.
Radiobutton
Style
Okay, so the -relief option does the same thing is
it
does
worthwhile to show a screen shot of what happens
in a checkbutton.
when
But
it
different relief types
are used (see Figure 4-12).
_Jjj J
RadMbutton
,_, _
flat
»
groove
?
raised
«
ridge
sunken
Figure 4-12. Different relief types for a radiobutton
As with the checkbutton, changing -borderwidth can cause the radiobutton to look drastically different (see Figure 4-13).
^itoto5Hr~~""~Ta flat
groove
raised
ridge
sunken
Figure 4-13- Radiobuttons with -borderwidth of 4
Remember how the indicator completely disappeared in a checkbutton when we used a -borderwidth of 10? Well, in a radiobutton, it makes it look kind of like a kite (see Figure 4-14). You still won't be able to tell which radiobutton is checked or not, so I don't recommend using the -borderwidth option.
;
;
100
Chapter
4:
Checkbuttons and Radiobuttons
p(-— '
flash()
colors off
;
Invoking a Radiobutton To programmatically $rb->invoke It
select a radiobutton, use the
invoke method:
( )
causes the radiobutton to be selected and will also invoke any callback associ-
ated with the radiobutton via the thing
it
would do
if
-command
option. Essentially,
it
you clicked on the radiobutton with the mouse.
does the same
Fun Things
101
to Try
Fun Things Create a all
to Try
bunch of checkbuttons and
a
Go
button that will report the status of
the checkbuttons.
Make up
a survey that uses checkbuttons for questions that have
one or more
options and radiobuttons with only one appropriate choice. Create three different groups of checkbuttons: Favorite Color, Favorite Song,
and Shoe
Size.
Then
use.
The curwhich checkbuttons the user can see and
create a radiobutton to represent each group.
rently selected radiobutton dictates
;
;
Label and Entry Widgets There are times
want users
you'll
name, address, or even entry widgets.
the user
You can use
in the entry.
Most
often, you'll see the label
entry combination used multiple times in a database entry-type there are
many
such as
their
use
this is to
widget with an entry to clearly communicate to
a label
what should be typed
to type in specific information
number. The simplest way to do
a serial
different pieces of information the user
must
and
window where
enter.
The Label Widget So
far, all
buttons.
the screen?
anything.
It
The
we
What
label widget
does
label
can show
if
we
widget
is
it)
and
want
A
text,
have a different
both
a button
font,
have
102
some
like a
informative text
on
button that doesn't do
does nothing when you It is
click
on
it.
similar to a button in that
it
relief (default is flat), display multiple lines of
and so on. Figure
label, created
is
and by default cannot have the keyboard it
with
this
5-1
)
shows
a simple
code:
use Tk; $mw = MainWindow->new() $inw->Label -text => "Label Widget " ->pack $rnw->Button(-text => "Exit", -command => sijb MainLoop (
to put
label
probably the simplest widget.
text (or a bitmap),
and
just
just that.
a noninteractive widget
is
focus (meaning you can't tab to
The
have talked about are buttons, buttons, and more
( )
;
{
exit })->pack();
window, with
103
The Label Widget
Label
¥1 1
1^4
ahel Wid get Exit
a-
Figure 5-1-
A
simple
Here are some •
with label
and
button
typical uses for a label:
Put a label to the is
•
window
left
of an entry widget so the user
knows what type
of data
expected.
Put a label above a group of radiobuttons, making their purpose more clear (e.g.,
"Background
Color:").
You can do
the
same thing 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. All the other widgets
would have
a
mapping
that displays a string containing information
about
that widget.
Creating a Label The command
to create a label
$label = $parent->Label
[
(
is,
of course. Label. Here's the basic usage:
option => value
.
.
.
)->pack();
]
Hopefully, you are starting to see a trend in the creation
when you create a label, you can appearance and how it behaves.
expect,
command. As you might
specify options that will change
its
Label Options The following
-anchor => center '
list is
'n'
a
|
comprehensive 'ne'
'e'
|
of options for labels:
'se'
|
's'
|
'sw'
|
'w'
|
'nw' |
'
Causes the text to
stick to that position in the label widget. This
ous unless the label
-background => Sets the
|
list
is
forced to be larger than standard
color
background color of the
label to color.
-bitmap => bitmap Displays the bitmap contained in bitmap instead of
text.
size.
won't be obvi-
Chapter 5: Label and Entry Widgets
104
-bordeirwidth => amount
Changes the width of the edges of the
label.
-cursor => cursomame Changes the cursor to cursomame when
the
mouse
is
over
this
widget.
-font => fontname be displayed with fontname.
Indicates that the text in the widget will
-foreground => Changes the
color
text of the button (or the
bitmap) to be color
color.
-height => amount Sets the height of the label to
-highlightbackground =>
amount; amount
a valid screen distance.
color
Sets the color of the focus rectangle
-highlightcolor =>
is
when
the widget
when
the widget has focus to color.
is
not in focus to color.
color
Sets the color of the focus rectangle
-highlightthiclcness => amount Sets the
width of the focus rectangle. Default
for the label.
is
-image => imgptr Displays the image to which imgptr points instead of
-justify => 'left'
'right'
|
Sets the side of the label against
|
text.
'center'
which
multi-line text will justify.
-padx => amount Adds extra space
inside the
edge
to the left
and
-pady => amount Adds extra space
inside the
edge
to the top
and bottom of the
'groove' 'raised' -relief => 'flat' Changes the type of edges drawn around the |
|
-takefocus => Changes the -text =>
|
1
|
|
right of the label.
'ridge'
|
label.
'sunken'
button.
undef
ability of the label to
have the focus or
not.
text
Displays in the label a text string.
-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).
105
The Label Widget
-width => amount Causes the label to be width amount.
-wraplength => amount Indicates that the text in the label will
This
list
briefly describes
wrap when
each option and what
different defaults for the label
we
widget than
type widgets, causing the label to behave a
How a Label Differs from
it
it
does.
gets longer than
Some
amount.
of the options have
are used to seeing with the button-
bit differently.
Other Widgets
When we
created button-type widgets, we could either click them with the mouse them and then use the keyboard to cause the button to be pressed. A label widget, on the other hand, does not interact with the user. It is there for informational purposes only, so there is no -coitimand option. We also can't tab to a label widget because nothing would happen. or tab to
-takefocus option is 0, making the label noninteractive. 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 -highlight thickness option in a label widget is 0. You can make a rectangle appear around a label by setting -highlight thickness to something greater than 0, and setting -highlightbackground to a color such as blue or red. The
default value for the
The
label
widget also doesn't have a -state option. Since
click a label,
we
should never have to disable
we
shouldn't be able to
it.
Relief In Figure 5-2,
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 conby the -padx and -pady options). Normally, you want the label widget to
trolled sit
right next to the
_. flat
widget (or widgets)
Label
j\ sunken '
groove raised ridge
it
is
describing.
Label
-A flat
flEd!
*
Figure 5-2. Labels with different relief values.
You'll notice that
I
like
Window on
right
rals«tli
s
_jj PSHf sftiMcen
has a -borderwidth of 10.
seeing what widgets look like with the different
relief values.
This sometimes helps determine where the widget ends, especially with widgets that
;
106
Chapter 5: Label and Entry Widgets
have a default value of
make and
sure
I
Also,
often change the relief of different widgets to
I
widgets are where on the screen. After creating 10 entries
labels with less than creative variable
ing the borderwidth relief
program
anyone
to
bound
is
to
make
else to run! Color
Status Message
names,
that
and borderwidth back
change the
I
"flat".
know which
is
it's
easy to lose track. Also, chang-
one widget stand
to something
good way
also a
out.
Of
course,
non-obnoxious before to
do
I
I
always
give the
a diagnostic message.
Example
often use the groove or ridge relief
when
making a help or
I'm
status label
along the
bottom of my window. I make a label that is packed with -side => 'bottom' and -fill => 'x'. There are two different ways you can use a status label: •
Set the variable associated with
announcing •
to the user that
Have the help application
it
is
it
so
label give information
when
it
changes as your program progresses,
it
busy, or something
is
happening.
on each of the different widgets bind command.
in
your
gets the focus, using the
Both types are demonstrated
in the following
This code shows the "What I'm doing
sample code.
now" type
of help label:
$rnw->Label (-textvariable => \$message, -borderwidth => 2, -relief => 'groove' ->pack( -fill => 'x', )
$inw->Text
{)
-side => 'bottom'); ->pack(-side => 'top', -expand => 1, -fill => 'both')
$inessage = "Loading file index html ..." .
;
$message = "Done";
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 will get lower priority if the window runs out of room). As the program executes (represented by the. .), it changes the label accordingly. .
This code
shows an example of using
a widget-helper help label:
$mw->title( "Help Label Example");
$mw->Label (-textvariable => \$message) ->pack(-side => 'bottom', -fill => 'x'); $b = $mw->Button(-text => "Exit", -command => \&exit) ->pack(-side => 'left'); &bind_message($b, "Press to quit the application");
107
The Label Widget $b2 = $inw->Button(-text => "Do Nothing" ->pack( -side => lef t &bind_message($b2, "This button does absolutely nothing!"); )
'
$b3 = $mw->Button(-text => "Something", -coinmand => sub { print "something\n"
&bind_inessage $b3 (
siib
bind_message
"
,
Prints the text
}) ->pack(-side something "
=>
;
)
'
'
)
left
'
)
;
{
my ($widget, $msg) $widget->bind $widget->bind
'
'
( '
( '
= @_;
sub { $message = $_[1] sub { $message = " " } [
'
;
'
;
$msg
},
]
)
)
}
This example
method get
we
is
is
a bit longer because
explained
create,
in
we want
more
detail in
we
are using the
Chapter
to associate a help
14,
bind method
Binding
message with
(the
it.
We
do
this
bind
each wid-
Events). For
by adding
bindings to each widget that change the variable $inessage to a specified string
when
the
widget.
mouse
We
enters the widget,
and
to
an empty
string
if
the
mouse
used a subroutine to avoid writing the same two bind
over again. Figure 5-3 shows what our
window
looks like with the
leaves the
lines
over and
mouse over
the
center button.
Exit
Do Nothing
Something
This button does absolutely nothing!
Figure 5-3-
Window
J
with label across the bottom
Container Frames In Figure 5-3,
When text
you can see
that the
example
text
is
centered within the label widget.
when you fill the widget across the screen, the even if you add the -justify => left option. You can
using non-multiple line labels,
remains centered,
get around this
by
'
'
creating a container frame, giving
frame across the screen (instead of the
label),
the frame: $f = $mw->Frame( -relief =>
'groove',
it
the desired
and placing the
relief, filling
label
the
widget within
;
108
Chapter
-bd =>
5:
Label
and Entry Widgets
->pack(-side => 'bottom', -fill => 'X') $f->Label (-textvariable => \$message, ->pack(-side => 'left'); 2)
)
grow and shrink within
This allows the label to
you've typed
text sticks to the left side. If
with the strings will resize itself
bound
tell
the
fairly
is
is
window
to not resize
in
and played
that the
window
too long to display in the label.
small to begin with. There are
you can always use
to deal with this: First,
ond, you can
$message
your window
if
example
each widget, you might have noticed
the text assigned to
if
This can get annoying
ways
to
the frame as necessary, while the
this short little
when
really short text strings,
and
two sec-
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 make really short sen-
make
tences that
though
—
it
is
sense, great. Telling the
accomplished by adding one
$inw->packPropagate
(
Using packPropagate placed inside the
)
right
will
your widgets
in
it,
first
You can
figuring out a
$inw->geometry( 512'^) to request gets, for info
to not resize
is
almost as easy,
your program:
window
when
a widget
is
talked about packPropagate in Chapter
2,
cause your
window (we away.
line to
;
Geometry Management). This means your widgets
window
that
to not resize
your window might not be showing
deal with this by keeping
good
starting size for
that size initially. (See
it
on
until
you get
all all
your window and using Chapter
13,
Toplevel Wid-
on the geometry method.)
Label Configuration two methods available to change on it: cget and configure. Both methods work for Label the same way they work for the Button widget. Please refer to Appendix A for the details on arguments and return values. Label
is
a pretty boring widget, so there are only
or get information
The Entry Widget Until
now, the only input
we know how
to get
from the
[entry widget is
a
mouseclick on a button widget (Button, Check-
which
is
handled via the -command option. Getting input
user button, or Radiobutton),
from a mouseclick
is
useful, but
it's
also limiting.
type in text that can then be used in any
The
way by
entry widget will
let
the user
the application. Here are a
few
examples of where you might use an entry widget: •
In a database
form
that requires
one entry per
field (e.g..
Name,
Address) •
In a software registration
window
that requires a serial
number
Last
name,
109
The Entry Widget
window
•
In a login
•
In a configuration
•
In
an
Open
we
File
that requires a
window
window
usemame and password name
to get the
of a printer
that requires the path
and name of
a
file
what users type
in an entry widget until they are done happen "after the fact" when a user clicks some sort of Go button. You could get fancy and process each character as it's typed by but it is probably more trouble than it is worth. setting up a complicated bind
Normally,
don't care
and any processing
typing,
will
—
The user can type anything decide
if
from an
some
the text entered
entry,
we
an entry widget.
into
valid or not.
is
When
should do some error checking.
we
alphabetic characters,
is
It
up
programmer
to the
to
preparing to use the information
we want
If
an integer and get
should issue a warning or error message to the
user.
An
entry widget
entry widget
is
a
is
much more complex widget
than
it
appears to be. The
first
simplified one-line text editor. Text can be typed
really a
selected with the mouse, deleted, middle-of-the-line widget.
It's
and added.
I
would
more complicated than
classify
in,
an entry widget as a
a button, but
much
less
com-
plicated than the text or canvas widgets.
Creating the Entry Widget No
surprises here:
$entry = $parent->Entry
When
the entry widget
cursor
(if
is
option => value
[
(
created,
it
is
.
.
is
]
)->pack;
empty of any
initially
the entry had the keyboard focus)
.
at
the
text,
and the
insert
far-left side.
Entry Options The following
list
contains a short description of each option available for config-
uring an entry widget. Several of
them
are discussed in
more
detail later in this
chapter.
-backgroimd => Sets the
color
background color of the entry widget. This
is
the area behind the text.
-borderwidth => amount Changes the width of the outside edge of the widget. Default value
-cursor => cursomame Changes the cursor to cursomame when
-exportselection => If
|
is
over the widget.
1
the Boolean value specified
windowing system's
it
is 2.
clipboard.
is
true,
any
text selected will
be exported to the
.
|
Chapter 5: Label and Entry Widgets
110
-font => fontname Changes the font displayed
-foreground =>
fontname.
in the entry to
color
Changes the color of the
-highlightbackground =>
text.
color
Sets the color the highlight rectangle should
be when the widget does not
have the keyboard focus.
-highlightcolor =>
color
Sets the color the highlight rectangle should
be when the widget does have
the keyboard focus.
-highlightthickness => amount around the widget. Default
Sets the thickness of the highlight rectangle
-insertbackground =>
is 2.
color
Sets the color of the insert cursor.
-insertborderwidth => amount Normally used
Sets the width of the insert cursor's border.
-ipadx and -ipady options
for the
in conjunction
with
geometry manager.
-insertofftime => milliseconds Sets the amount of time the insert cursor
is
off in the entry widget.
-insertontime => milliseconds Sets the amount of time the insert cursor
is
on
in the entry widget.
-insertwidth => amount Sets the
width of the
-justify => 'left'
insert cursor. Default
|
'right'
is 2.
'center'
|
The
Sets the justification of the text in the entry widget.
-relief => 'flat'
|
'groove'
Sets the relief of the outside
-selectbackground => Sets the
|
'raised'
|
'ridge'
default
is left.
'sunken'
|
'solid'
edges of the entry widget.
color
background color of any selected
text in the entry widget.
-selectborderwidth => amount Sets the width of the selection highlight's border.
-selectforeground => Sets the text color of
color
any selected
text in the entry widget.
-show => char Sets the character that should
-state => 'normal'
|
be displayed instead of the actual
'disabled'
|
Indicates the state of the entry. Default
'active' is
'
normal
'
text typed.
111
The Entry Widget
-takefocus =>
|
1
Allows or disallows
|
this
xxndef
widget to have the keyboard focus.
-textvariable => \$variable Sets the variable associated with the information
typed
in the entry widget.
-width => amount width of the entry in characters.
Sets the
-xscrollcoinmand => callback Assigns a callback to use
when
scrolling
back and
forth.
The following options behave as we expect them to, and aren't worth further discussion: -background, -cursor, -font, -highlightbackgroimd, -highlightcolor, -highlightthickness, -foreground, -justify, -takefocus, and -state. For more detailed information on these how these options affect a widget,
see Chapter
3.
Assigning the Entry's Contents to a Variable The -textvariable option
lets
you know what the user typed
in the
entry
widget: -textvariable => \$varia]Dle
By now, you should be familiar with this option from several of our button examples. Any text input into the entry widget will get assigned into $variable. The reverse also applies. Any string that gets assigned to $variable will show up in the entry widget. It is
important to remember that no matter what the user enters,
to this variable. This (e.g.,
"314"),
means
that
it
will
be assigned
even though you are expecting numeric input
like "3sl4" if the user accidentally (or on wrong key(s). Before using any information from an entry good idea to do some error checking to make sure it's the informa-
you might get something
purpose!) presses the widget,
it's
a
you expect or, at the very least, in the correct format. Trying an equation would most likely produce undesired results.
tion
The other way you can
find out
what
is
in the entry
widget
is
to use "3sl4" in
by using the get
method: $stuf f = $entrY->get
You can
( )
use get whether or not you have used the -textvariable option.
.
Chapter 5: Label and Entry Widgets
112
Relief all the widgets, you can change the way the edges -relief and/or -borderwidth options:
As with
-relief => 'flat' 'groove' -borderwidth => amount
'raised'
|
The
default for an entry
seen so
far.
is
drawn by using the
'sunken'
'ridge'
'sunken', which
is
are
change from what we've
also a
Figure 5-4 shows the different relief types at different
values incrementing from the default,
2,
-borderwidth
to 4, to 10.
J
Bitry Entry
MjI
Entry
1^ Jl
flat
flat
flat
groove
groove
igroove
j
j
raised
raised
!
iridge
raised
i
iridge
fsunken
sunken Exit
sunken
Exit
Exit
Figure 5-4. Different relief types for
This
is
name
entry widget: -borderwidth of 2 (the default),
an
4,
and 10
the code snippet that created the five entry widgets and used the relief
as the entry widget's text:
foreach (qw/flat groove raised ridge sunken/) { $e = $inw->Entry (-relief => $_) ->pack(- expand => 1) $e->insert 'end' # put some text in the entry $_) ;
(
,
;
}
Entry Indexes In order to manipulate the text in the entry widget, tify
specific portions or positions within the text.
The
you need some way last
example
actually
to iden-
used an
The line $e->insert 'end' $_) uses the index 'end' Just like the insert method (covered later in the chapter), all of the methods that require information about a position will ask for an index (or two, if the method requires a range of characters). This index can be as simple as 0, meaning the very beginning of the text, or something more complicated like insert index
in
it.
(
.
,
'
'
The Entry Widget
Here are the
1J3
different
forms of index specification and what they mean:
n (any integer)
A
numerical character position.
is
the
first
character in the string.
If
the entry
mother hit your mother right on the nose" and we used an index of 12, the character pointed to would be the "t" in the word "hit." contains the string "My
'
insert Indicates the character directly following the insertion cursor.
cursor get
clicking '
that funny-looking
is
when
text
on
is
little
insertion
bar thing that shows up inside the entry wid-
You can move
typed.
The
it
around with the arrow keys or by
a different location in the entry widget.
sel first .
The first character in the selection string. This will produce an error if there is no selection. The selection string is the string created by using the mouse or shift-arrow. The selected text is slightly raised from the background of the entry. If
our selected
were the word "nose"
text
in this string
(shown here
in bold)
My mother hit your mother right on the nose '
'
sel first .
'
would
sel last .
The character
just after
produce an error example, '
indicate the "n".
if
the
there
is
would mean
this
last
character in the selection string. This will also
no
selection in the entry widget. In the preceding
the space after the "e" in nose.
anchor The 'anchor' index changes depending on what has happened with the selection in the entry widget. By default, it starts at the far left of the entry: 0. It will change if you click anywhere in the entry widget with the mouse. The new value will be at the index you clicked on. The anchor index will also change when a new selection is made either with the mouse (which means the anchor will be wherever you clicked with the mouse) or by Shift-clicking and anchor will be set to where the selection starts. Mostly, this index is used internally, and you'll rarely find a case where it would be useful in an '
'
—
'
'
—
'
'
application.
•end' This indicates the character just after the is
the
index.
same
as
if
last
one
in the text string. This
you specified the length of the
entire string as
value
an integer
Chapter 5: Label and Entry Widgets
114
'&x'
This form uses an x coordinate in the entry widget. tains this
X coordinate
be used.
will
acter in the entry widget. This
The
character that con-
"(iO" indicates the leftmost (or first) char-
form of index specification
is
also
one
you'll
rarely use.
Text Selection Options You can
an entry widget, and several things happen. The indices
select the text in
'sel. first' and 'sel.last' point to the beginning and end of the selected
You can
text respectively.
on
a
make
also
the selected text available
on the clipboard
Unix system by using the -exportselection option:
-exportselection =>
|
1
The -exportselection option
indicates
whether or not any selected
text in the
entry will be also be put in the selection buffer in addition to being stored internal to the entry as a selection.
By leaving
this
option in
its
default value,
you can
paste selected text into other applications.
The
selected text also has
some
color options associated with
it:
-selectback-
ground, -selectforeground, and -selectborderwidth: -selectbackground => color -selectforeground => color -selectborderwidth => amount
The -selectbackgroimd and -selectforeground options change the color of the text and the area behind the text when that text is highlighted. In Figure 5-5, the word "text" is selected.
-\ ,
Entry
Select the word
^
in this
,
j
Ji
entry
Exit 1
Figure 5-5. Entry with -selectbackground =>
'red'
and -selectforeground =>
You can change
the width of the edge of that selection
borderwidth.
you
If
see the effects of
it.
left
The
'yellow'
box by using -selectyou wouldn't
the size of the entry widget unchanged,
To actually see -selectborderwidth value use the -selectborcommand and the -ipadx and -ipady in the geom-
entry widget cuts off the selection box.
the results of increasing the
derwidth option in the entry etry management command.
115
The Entry Widget
'^^t-
Enfry
iSelectthe word te^lln
'^^^'^iii
this entry
Exit
Figure 5-6. Entry widget with -selectborderwidth =>
You might want extra space
5
change the -selectborderwidth option
to
around your
text or
if
you
want
really
to
if
you
like a little
emphasize the selected
text.
Here's the code that generated the entry widget in Figure 5-6: $e = $inw->Entry (-selectborderwidth => 10) ->pack(- expand => 1, -fill => 'X', -ipadx => 10,
$e->insert 'end' {
,
-ipady => 10) "Select the word text in this entry");
Notice the -ipadx and -ipady options in the
pack command.
The Insert Cursor The
insert cursor
entry widget
is
when
that funny-looking it
widget actually has the keyboard focus.
board focus, the insertion cursor insertion cursor
is
little
has the keyboard focus.
immediately
is still
after the
If
bar that blinks on and off inside the It
will
only
show up when
the entry
another widget (or none) has the key-
there, but
second "n"
it
is
invisible. In Figure 5-7, the
in the
word
"Insertion."
Figure 5-7. Default insertion cursor
You can change
the thickness, border width,
and width of the
insertion cursor
by
using these options: -insertbackground => color -insertborderwidth => amount -insertwidth => amount
The -insertwidth option simply changes the width of the cursor so it looks fatter. The -insertbackground option changes the overall color of the insertion cursor. Figure 5-8 shows an example.
J 116
Chapter 5: Label and Entry Widgets
jsj»^^
mm T
111!
Entry II
|
-|^
imwtTmwwwnTwJmiMJiiB
'
Insertion Cursor
Exit
Figure 5-8. Insertion cursor with -insertbackground => 'green'
No two
how wide
matter
characters.
The
the cursor,
it
and
-insertwidtb
always centered over the position between
is
insertion cursor in Figure 5-8
is
in the
same
it was in them unneces-
location
Figure 5-7. This can look distracting to users and might just confuse sarily,
=> 10
so you most likely won't change the -insertwidth option.
You can
give the insertion cursor a
Figure 5-9).
Like the
doesn't have
much
3D
-insertwidth
look by using -insertborderwidth (as in option, the
-insert±)orderwidth option
practical use.
aW
Entry
Insertion Cursor
—
Exit
1
.
1
Figure 5-9. Insertion cursor with -insertborderwidth => -insertwidth
You can
5,
-insertbackground => green
'
and
=> 10
also
change the amount of time the cursor blinks on and
off
by using
these options: -insertof ftime => time -insertontime => time
The default value for -insertof ftime is 300 milliseconds. The default for -insertontime is 600 milliseconds. The default values make the cursor's blink stay on twice as long as it is off. Any value specified for these options must be nonnegative.
For a really frantic-looking cursor, change both values to something For a relaxed and mellow cursor, double the default times.
-insertof ftime
blinking cursor, change
If
much
smaller.
you don't
like a
to 0.
Password Entries There are times
when
displayed on the screen.
use the -show option: -show => char
that shouldn't
be
display something other than the actual text typed
in,
you'll request information
To
from the user
The Entry Widget
The char is
a single character that will
be displayed instead of the typed-in charac-
For a password entry, you might use asterisks (see Figure 5-10).
ters.
ify a string, just is
117_
the
character of that string will be used.
first
By
If
you spec-
default, this value
undefined, and whatever the user actually typed will show.
fs\j.
ilj^-^^'^^BWIf^*^
Exit
Figure 5-10. Entry displaying a password
When
using the
-show
option, the information stored in the associated
$variable
will contain the real information, not the asterisks. If
you use
this feature, the
user can't cut and paste the password (regardless of the
value of -exportselection).
saw on the screen
user
information behind
If
(the asterisks, for
You might
it.
and pasted
cut
is
it
example)
think that
if
widget such as $entry->conf igure (-show =>
would suddenly appear. Luckily, this berish) show up instead. Any variable associated with the entry will
an $entrY->get well.
( )
still
to another screen,
isn't true.
is
you did " "
)
;
,
actually pasted, not the
on the entry words the user entered
a configure
the
A bunch
what the
of \xOs (essentially gib-
-textvariable option and is If you perform
that uses the
contain the correct information.
the correct (nongibberish) information will be returned as
,
The get method
is
described later in
this chapter.
Using a Scrollbar If
the information requested from the user could get lengthy, the user can use the
arrow keys to manually
scroll
through the
To make
text.
assign a horizontal scrollbar to the entry widget
it
easier,
we
can create and
by using the -xscroll command
option: -xscrollcoinmand =>
For now, I'm going to entry widget. For
To
more
'
[
set
'
=> $scrollbar
show you details
and associate
create a scrollbar
the
on the it
]
most basic way to assign
a scrollbar to the
scrollbar see Chapter 6, Scrollbars.
with an entry widget, do
this:
$scroll = $itiw->Scrollbar (-orient => "horizontal"); # create scrollbar -> $e = $inw->Entry (-xscrollcoinmand => 'set' => $scroll pack(-expand => 1, -fill => 'x'); # create entry $scroll->pack( -expand => 1, -fill -> 'x'); $scroll->configure(-coinmand => $e => 'xview' # link them $e->insert 'end' "Really really really long text string"); ]
[
[
(
,
]
)
;
)
;
.
Chapter 5: Label and Entry Widgets
118
Figure 5-11 shows the resulting
looked
way
when
it
was
window
in
and on the
created,
two
right,
states:
how
on the
the
left,
window
looks after scrolling
it
all
as
it
the
to the right.
Entry
^
j
jReally really really long
Entry jally really
t
Exit
Figure 5-11. Scrollbar and
an
.
\
j
long text string
Exit
entry widget
want to use a scrollbar with an entry widget. The scrollbar douamount of space taken, and you can get the same functionality without it
You'll very rarely bles the
by simply using the arrow keys when the entry widget has the needs to enter multiple Chapter
8,
lines of text,
you should use
focus.
If
the user
a text widget instead. See
The Text Widget, for more information on what
it
can do.
Configuring an Entry Widget Both cget and configure are the same for the entry widget as they are of the other widgets.
Appendix
The
default options for the
A, Configuring Widgets with configure
for
any
entry widget are listed in
and cget.
Deleting Text You can use
the
delete method when you want
from the entry widget.
You can
characters or a single index to
remove one
$entry->delete (firstind€yc,
To remove all of the the -textvariable variable to an
empty
text,
/"
remove some or all of the text remove two or more
character: ])
you can use $entry->delete(0,
you can also $variable =
Here are some other examples of $entry->delete(0) $entry->delete 1 (
lastindex
option, string:
to
specify a range of indices to
# #
)
how
delete method:
Remove only the first character Remove the second character
,
;
#
Remove selected text present
# if
).
If
you use
by reassigning the
"
to use the
'sel.last') $entry->delete( 'sel. first if $entry->selectionPresent '
delete the contents "
'end'
119
The Entry Widget
Getting the Contents of an Entry Widget There are two ways to determine the contents of the entry widget: the get method or the variable associated with the
-textvariable
$entry_text = $entry->get
will assign the entire contents of the entry
get into
( )
find out the content
the information.
If
you only need
into a database,
it
a variable. Simply use the
would be
appropriate).
initially store
Moving
it
depends on what you are going
to reference
it
once
in
order to write
it
do with to a
file
doesn't
the information in the entry widget
If
to
number
is
going to be a
easy access
in a variable for
fre-
it
makes
insert took
place.
for a mathematical calculation, then later.
the Insertion Cursor
The icursor method $entrY->icursor
By To
wid-
make sense to waste memory by storing it in get method in the print statement (or wherever it
it
quently used value such as a
sense to
get method,
$entry_text.
Which way you or insert
option. Using the
(
will place the cursor at the specified index.
index)
;
wherever the
default, the insertion cursor starts out
force the insertion cursor to
show up
last
elsewhere, you could do something like
this:
$e_txt = "Entry Text"; $e = $rnw->EntrY{ -textvariable => \$e_txt) ->pack() $e->focus; $e->icursor (1) # put cursor at this index
;
;
We
focus method (which
use the
generic to widget.
Then we place and
acters (indices for
the insertion cursor
1) in the entry.
start
it's
with the focus on our entry
between the first and second char16, Methods for Any Widget,
See Chapter
more information on focus.
You might want
to
move
$e->icursor
Getting a
( '
end'
For instance, set $e_txt
=
if
)
Numeric Index Value
The index method
will convert a
named index
$nuinindex = $entry->index (index)
One
you are starting the "http://" and then do
the starting position of your cursor
text with a specific string.
get:
not specific to the entry widget;
is
widgets) to have the application
all
into a
numeric one:
;
of the uses of index is to find out how many characters are $length = $entry->index 'end' Of course, if we used (
)
.
in the entry
the
wid-
-textvari-
;
;
120
Chapter 5: Label and Entry Widgets
able
option,
we
could get the same result by using $length = length ($vari-
able).
As an example of using index this
where
to find out
$startindex = $entry->selectionPresent $entry->index( 'sel. first' (
We
the current selection
starts,
use
code:
discuss
selectionPresent
)
? )
:
-1;
later in the chapter.
Inserting Text The insert function $entrY->insert
(
will let
index,
you
string)
insert
any
text string at the specified index:
;
Here's a simple application that uses insert: # /usr/bin/perl use Tk; $n!W = MainWindow->new; $mw->title "Entry" !
(
)
$e_txt = "Entry Text"; # Create entry with initial text $e = $inw->Entry(-textvariable => \$e_txt) ->pack(- expand => 1, -fill => 'X') $inw->Button(-text => "Exit", -command => s\ib { exit } ->pack(-side => 'bottom'); )
#
Create a Button that will insert a counter at the ciirsor
$i = 1;
$mw->Button(-text => "Insert #", -command => sub { if ($e->selectionPresent { $e->insert( 'sel. last' "$i"); $i++; )
,
} )
}
->pack;
MainLoop;
We
the entry widget with "Entry Text" as a default. Then we create two butThe first one is the obvious Exit button that will allow us to quit the application. The second one is a bit more complicated. When pressed, it will check to see if any text is selected in the entry $e. If text is selected, it will insert a number that keeps track of the number of times we have pressed the Insert # button. fill
tons.
In Figure 5-12,
we
first
selected the
button four times. Each time
it
was
word
pressed,
"sel. last". This index didn't change
we
are counting backward!
"Entry"
in
it
and then pressed the
inserted a
between button
number
presses, so
Insert
at the it
*
index
looks as
if
121
The Entry Widget
m
,
g^,g,^_^»^
J
|Entry4.321 Text
Insert* „,.
.„:„™.
1
...J
Exit
Figure 5-12. Using the insert method
Scanning Text Both scanMark and scanDragto are used within the entry widget. They allow within the entry widget.
fast scrolling
coordinate passed
in for
$entrY->scanMark(.r)
$entrY->scaiiDragto
use
later
A
call to
scariMark simply records the x
with scanDragto.
It
returns an
empty
string.
;
(x)
;
The companion function to scanMark is scanDragto, which also takes an x coordinate. The new coordinate is compared to the scanMark x coordinate. The view within the entry widget is adjusted by 10 times the difference between the coordinates.
Working with the Selection The selection method has several possible argument web-page documentation, you'll see that you can use: $entry->selectionAdjust
You might 'adjust'
also see the
the
is
(
w^fer)
If
you look
at
the
.
where same thing as you
form $entry->selection( 'adjust'
argument. Be aware that they
first
lists.
mean
the
,
index),
read code written by other people.
You can
adjust the selection to a specified index
$entrY->selectionAdjust
The
To
selected text
is
(
index)
by using selectionAdjust:
;
extended toward the index (from whichever end
is
closest).
clear out the selection:
$entrY->selectionClear
Any
( )
selection indicator will be
removed from the entry widget, and the indices now undefined. The selected text remains.
'sel. first' and 'sel.last' are
To
reset the
'
anchor index '
to the specified index, use
$ent2r/->selectionFrom( index)
;
selectionFrom:
;
Chapter 5: Label and Entry Widgets
122
This does not affect any currently selected text or the indexes 'sel. first' and
'sel.last'.
The only way to check selectionPresent:
to see
if
($entrY->selectionPresent
if
there
( )
)
a selection in the entry widget
is
is
to use
{
}
It
returns a
1
there
if
a selection,
is
which means
'sel. first' and 'sel.last' indices printed
when you
there
no
is
there
(if
you can
isn't a selection,
selectionPresent
refer to either index).
safely use the
an error
will
will return a
be if
current selection.
You can change
the selection range
by
calling
selectioriRange:
$entry->selectionRange (startindex, endindex)
The two
that
;
where you would like the selection to cover. If startsame or greater than endindex, then the selection is cleared, causing sel first and sel last to be undefined. Otherwise sel first and 'sel.last' are defined to be the same as startindex 2Lnd endindex respeciively.
index '
indices indicate
the
is
.
'
'
.
'
'
The selectionTo method will cause the new anchor point to the specified index: '
(
index)
Changing the View xview
is
passed
in.
a
method
With no arguments,
set
from the current
;
in the Entry Widget
that will
change
will return a
it
purpose based on what arguments are
its
two-element
These two numbers define what currently
number .3,
be
'
$entry->selectionTo
1.
selection to
'
.
then
indicates
30%
how much
of the text
how much
returned
is
plus the
amount
that
When
$right)
=
of the text
list
off to the
is
is
containing numbers from
to
The first left and not visible. If it were widget. The second number
visible in the entry widget.
to the left of the entry
of the text
not visible on the
left
visible in the widget. In this case,
is
ally visible in the entry
($left,
is
is
side of the entry widget
50%
of the text
is
actu-
widget (see Figure 5-13)-
$entry->xview()
passing an index value to xview, the text in the entry widget will
tion so that the text at the specified index $entry->xview(/npack(-side => 'right', -fill => 'y'); $lb->pack(-side => 'left', -fill => 'both');
show
a
129
The Scrollbar Widget
Creating the scrollbar
we
create the listbox,
with the scrollbar vertical,
is
we want
pretty simple;
have to
when
up
set
a callback so the listbox can
(if
it
it
is
communicate
move around. Our scrollbar is set command and our scrollbar
horizontal, use -xscrollcoitimand).
by the user without using the by invoking $scrollbar->set (...).
listbox are scrolled
scrollbar
As we
it.
the contents of the listbox
so the -yscrollcommand option has the
assigned to
the default options for
all
When
the contents of the
scrollbar, the listbox will alert the
$scrollbar->configure( -command => 'yview' => $lb] does almost the opposite; it configures the scrollbar to communicate with the listbox. When the user clicks on the scrollbar, the scrollbar will invoke $lb->yview( The
line
[
)
.
to
tell
of the
how to change the view of the contents. We view command because this is a vertical scrollbar. the listbox
.
.
use the "y" version
yview in "How the Scrollbar Communicates with Other Widgets," later in this chapter. The last two lines in this example pack the scrollbar and the listbox in the window so that the scrollbar is the
There
is
more information on the
same height
as the listbox
Always pack your scrollbars to
and
scrollbars
remain
visible
details of
lies to
within the
first
when
the right of the listbox.
window or frame. This window smaller.
the user resizes the
resize the listbox (or other widget) but leave the scrollbars visible
allows the It
will
then
on the edges of
the screen.
Now set
that
we've seen a complete example of
up the widget
it
we
will scroll,
how
and how
to create a scrollbar
can go over the options with an idea of
to
how
they are used.
Scrollbar Options This
list
contains the options available with a scrollbar, and their quick definitions.
The important options
are discussed in
-activebackground =>
=>
detail later in this chapter.
color
Sets the color the scrollbar
-activerelief
more
'flat'
when
the
'groove'
|
should be |
mouse
pointer
'raised'
is
|
over
it.
'ridge'
|
'sunken'
The -activerelief option determines how active elements elements in question are arrowl, arrow2, and the slider.
-background => Sets the
are drawn.
The
color
background color of the
scrollbar (not the trough color).
-borderwidth => amount Sets the
width of the edges of the scrollbar and the arrowl, arrow2, and
slider elements.
|
130
Chapter
6:
Scrollbars
-command => callback Sets the callback that
invoked
when
displayed
when
is
the scrollbar
is
clicked.
-cursor => cursomame Sets the cursor that
is
the
mouse
pointer
is
over the scrollbar.
-elementborderwidth => amount Sets the
width of the borders of the arrowl, arrow2, and slider elements.
-highlightbackground =>
color
around the scrollbar widget should be
Sets the color the highlight rectangle
when
it
does not have the keyboard focus.
-highlightcolor =>
color
Sets the color the highlight rectangle
around the scrollbar should be when
it
does have the keyboard focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle. Default
-juitp =>
is 2.
1 I
jump
Indicates whether or not the scrollbar will
-orient => "horizontal"
|
scroll.
"vertical"
Sets the orientation of the scrollbar.
-relief => 'flat' 'groove' 'raised' Changes the edges of the widget. |
|
-repeatdelay => time Sets the number of milliseconds required auto-repeat. Default
is
1
|
1
'ridge'
to hold
'sunken'
down an arrow
|
'solid'
before
it
will
300 ms.
-repeatinterval => time Sets the number of milliseconds -takefocus =>
|
in
between
auto-repeats. Default
is
100 ms.
\indef
Controls whether the scrollbar can obtain the keyboard focus.
-troughcolor =>
color
Changes the color of the trough (both troughl and trough2).
-width => amount Sets the width of the scrollbar.
Scrollbar Colors Within the scrollbar, trough gets
its
own
we
have a
new
part of the widget called a trough. This
coloring through the
-troughcolor
considered the part behind the arrows and slider. Figure 6-6
The trough shows an example.
option.
is
ne Scrollbar Widget
131
-trou9hcok)r-> 'p»9n'
i
-3
:
"*' '
Figure 6-6. Scrollbar with -trough color set to 'green'
The background of tion
the scrollbar consists of the arrows, the slider, and a small por-
around the outside of the trough. You change the color of the background by
The -activebackground option controls the mouse cursor is over one of the arrows or the slider. Figure 6-7 shows two examples of -background; the second window uses both -background and -troughcolor. using the
color that
->!
-background
is
displayed
option.
when
-backpTMiiti => 'gremi'
the
rrii ~'
'
PI
-.j-lig=> 'green', -tnn^tocMn- ==> 'yefiow'
jqr
3 Xif
Figure 6-7. Examples of -background option
Scrollbar Style The -relief and -borderwidth options affect both the outside edges of the scrollbar and the arrowl, arrow2, and slider elements. This is similar to how the checkbutton and radiobutton widgets are affected by the -relief and -borderwidth options. See Figure 6-8 for a screen shot of different values for these two options.
dt
,
-JU -^1
a
,^,,
I^H
Scrrtlbar
^ ::^A
^A ^i W^ '^
Figure 6-8. First row shows different relief values; second row different relief values with -borderwidth => 4
—
The -activerelief option affects the decoration of three elements arrowl, arrow2, and the slider when the mouse cursor is over them. The -elementborderwidth also affects the same three elements: arrowl, arrow2, and the slider. The width of the edges of these elements can be changed with this option. The -borderwidth option also changes the width of these elements but
—
also
changes the width of the edges of the widget. Notice
edges of the scrollbar remain
at a
width of
2.
in Figure 6-9
how
the
152
Chapter
-eienwntbCMnterwMtti «>
-J
4
j
h
6: Scrollbars
^j ^^..1
-^
Figure 6-9- Example of -elementborderwidth set to 4
The -width of
the scrollbar
is
the distance across the skinny part of the scrollbar,
not including the borders. Figure 6-10 demonstrates
when you
how
the scrollbar changes
-width.
alter the
1
-^omentteittefWRitti »>
1
4
J
-
•
•
\^l
,''' '
Figure 6-10. Top scrollbar has default width of 15, bottom scrollbar has width of 20
Scrollbar Orientation As mentioned scrollbar
is
$scrollbar
You could
earlier, a scrollbar
can be
'vertical'. To change = $inw->Scrollbar
also use
this,
vertical or horizontal.
The
default for a
use the -orient option:
(-orient => 'horizontal');
-orient =>
'vertical', but since
this is the default,
it
is
not necessary.
Using the Arrows and Slider When you
on one of the arrows in a scrollbar, you cause the slider to move unit. If you continue to hold the mouse button down, after a bit of a delay, the slider will auto-repeat that movement. The amount of time you must wait before the auto-repeat kicks in is determined by the -repeatdelay option. The default is 300 milliseconds. click
in that direction
by one
Once you have held there
is
trolled
the
a short delay
mouse button down long enough
between each time
it
to start auto-repeating,
repeats the action. This delay
by the -repeatinterval option. The default
for
con-
is
-repeatinterval
is
100
milliseconds.
when you click on the slider and move around, the data within the move accordingly. This is because the scrollbar is updating the widget will only continuously as you move the slider. To change the scrollbar so that update the widget when you let go of the slider, use the -juirp option and set Normally,
widget
it
will
it
it
to
1.
The
default for -juirp
is 0.
You would most
likely
want
to use -juirp
=> 1
The Scrollbar Widget
when your
133
scrolled widget contains a large
screen to update while you slide through
amount of data, and waiting for the would make the application seem
it
slow.
Assigning a Callback when you list
create a scrollbar,
you
tell
it
which widget
to talk to
and which method
by using the -coinmand option with an anonymous list. The contains the name of the method to call and the widget from which that
in that
widget to
call
method should be invoked. In this code snippet, we can see the yview command to scroll the widget $lb (a listbox):
that
we want
to use
$scrollbar->configure( -coinmand => ['yview' => $lb]
Now when
on by the user, it will invoke $lb->Yview. $lb is vertical because it uses the yview command. For a horizontal scrollbar, use xview. Both yview and xview tell the widget to move the widget contents an amount that is determined by where the user clicked in the scrollbar. The yview and xview methods are cov-
We know
the scrollbar gets clicked
that the scrollbar associated with
ered in the next section.
How the Scrollbar Communicates with
Other
Widgets earlier, you use the -coinmand option with the scrollbar so it knows which widget and method to use when the scrollbar is clicked. The command
As described
should be xview for horizontal scrollbars and yview for
can
call
vertical scrollbars.
these methods yourself, but most of the time you won't want
You
to.
Both xview and yview take the same type of arguments. Where the user clicked in the scrollbar
determines the value used, but the value will always be sent as
one of the following forms:
$widget->xvievyMoveto fraction) # or $widget->yvievMoveto( fraction) This form is used when the user clicks on the slider, moves drops it again. The argument is a fraction, a real number from (
;
;
resents the
moved
first
part of the data to
the slider
all
the
way
the slider
to 1 that repIf
the user
to the top or left of the scrollbar, the very
were moved
;
to the center of the scrollbar, the
$widget->xviev\Moveto (0.5)
;
first
be seen on the screen. This means the
0:
$widget->xvievayioveto(0) If
around, and
be shown within the widget.
part of the data in the widget should
argument should be
it
argument
is 0.5:
;
;
134
Chapter
$widget->xviewScroll(^zwmfoer,
$widget->yviewScroll number, (
This form
is
used
when
Scrollbars
"units"); # or "units " )
the user clicks
The widget should move
scrollbar.
6:
data
its
number of
;
on one of
the arrow elements in the
up/down
or left/right unit by unit.
number means that the next unit of data on the bottom or right of the widget becomes visible (scrolling one unit of data off the left or top). A value of -1 means that a previous unit of data will become visible in the top or right of the widget (one The
first
argument
the
is
can be any number, but
bottom or
unit will scroll off the
1
A
or -1.
right of the widget).
The value value of
for
1
For example, every time
on the down in a vertical scrollbar associated with new line shows up at the bottom of the listbox. arrow
the user clicks
box, a
units to scroll by.
typically either
it's
The second argument
is
the string "\jnits".
widget. In a listbox, a unit
would be one
would mean one
What
a unit
line of text. In
is
a
list-
depends on the
an entry widget,
it
character.
Here are some example
calls:
User clicked down arrow $listbox->yviewScroll (1, "units") #
User clicked up arrow $listbox->yviewScroll (-1,
#
"units")
User clicked right arrow $entry->xviewScroll (1, "units");
#
$widget->xviewScroll (;7wm^er, $widget->yviewScroll number, (
This form
is
"page"); # or
"page "
exactly like our previous
instead of "units".
(between the
slider
When
)
;
one except the
last
argument
is
"page"
users click in the trough area of the scrollbar
and arrows), they expect
to see the data
move by an
entire page.
The type of page is defined by the widget being scrolled. For example, a listbox would page up/down by the number of lines shown in the listbox. It would page right/left by the width of the listbox.
Scrollbar Configuration get and set any of the options available with a scrollbar by using cget and configure. See Appendix A, Configuring Widgets with configure and cget,
You can for
complete
details
on these methods.
I
The Scrollbar Widget
Defining
135
What We Can See
The set method, which we tell the scrolled widget about when we create it, defines what is visible. In our first example, we created a listbox and told it to use our scrollbar and the set method: $scrollbar = $inw->Scrollbar # Vertical scrollbar $lb = $mw->Listbox(-yscrollcommand => ['set' => $scrollbar ;
( )
When
the widget invokes the
set command,
it
]
)
sends two fractions
and
lasi)
The arguments
first
the position of the
first
(first
as the arguments:
$scrollbar->set (first, last);
This will change the position in the data that
and
last are real
numbers between
and
1
.
we
are seeing.
They represent
we can see and the position of the last data item we can see, respecIf we can see all of the data in our widget, they would be and 1. 1^\\q first
data item tively.
value gets larger as more data smaller as
more data
case in which to
is
is
scrolled off the top,
scrolled off the bottom.
call set yourself,
so
You
just try to get
and the
will
last
value gets
probably never find a
an idea of what
it
does behind
the scenes.
complete data
"first"
item
line
1
line
2 item 1,2
line
3
line
4
1
10%
into data
view of data
80%
"lastline
20
line
21
tfirougti
widget
into data
Figure 6-11. View of data through widget by set method (assumes vertical scrollbar)
document that we are viewing with a vertically The dashed rectangle represents the view of what we can cur-
Figure 6-11 shows a hypothetical scrolled widget.
rently see within the widget.
When
the widget calls set,
it
determines
how
far into
document the first viewable item is and sends this as the first argument. In Figure 6-11, this would be 10%, or 0.10. The second argument to set{) is how far into the document the last viewable item is. From our example, this would be the
80%, or
0.80.
)
;
;
136
Chapter
6: Scrollbars
Getting the Current View The get method
returns in a
$last)
{$first,
list
whatever the
$scrollbar->get
=
This data can change
if
(
latest
arguments to set were:
)
the widget requests a change in position of the data or
if
the scrollbar requests a change.
Activating Elements in a Scrollbar To determine which
part of the scrollbar
is
you can use the activate
active,
method: $elem
=
$scrollbar->activate(
The value returned active) or the
name
)
an empty
is
(which means no element
string
of the currently active element.
is
currently
The possible elements
are
"arrowl", "arrow2", or "slider".
you send an element name as the argument to activate, that element will to the color and relief specified by the -activebackground and -activerelief options. The element will continue to display that color and relief
If
change until
an event (such as the mouse cursor passing over the element) causes
it
to
change. Contrary to what you might believe, using activate does not invoke that element. Here are
some examples:
$scrollbar->activate "arrowl " $scrollbar->activate "arrow2 " $scrollbar->activate( "slider" (
(
no activate when the mouse is over There
is
for
"trough" because the trough doesn't change color
it.
Calculating Change from Pixels The number returned by delta
move
indicates
how much
the slider deltax pixels for horizontal scrollbars
scrollbars.
(The inapplicable argument
$ainount = $scrollbar->delta((i(?/itoc,
The amount returned can be
is
the scrollbar must change to
and deltay
pixels for vertical
ignored for each type of scrollbar).
deltay)
positive or negative.
Locating a Point in the Trough Given
a point at (x,y),
cating
where
fraction
that coordinate point
$loc = $scrollbar->fraction(.Y,
will return a real
would v)
;
fall in
number between
and
the trough of the scrollbar:
1
indi-
Examples
137
The point
(x,y)
must be
relative to the scrollbar. Figure 6-12
three possible results from fraction: 0.0, 0.5
and
shows
the location of
1.0.
Figure 6-12. Example of values returned by the fraction method
Identifying Elements The identify method
returns a string containing the
name
of the element located
at the x,y coordinate:
$elem If
x,y
is
-
$scrollbar->identify (x,j')
;
not in any element, the string will be empty. Both
coordinates relative to the scrollbar. The possible element
x and y must be names
pixel
are "arrowl",
"arrow2", "trough", and "slider".
Examples These examples are included use scrollbars in the ble;
we
then
we do
the
Each example uses the Scrolled method
same thing manually.
are using here, but
we
up any confusion about how
to hopefully clear
real world.
aren't
We
haven't covered
all
doing anything fancy with them
an option or method you don't recognize,
just
if
to
possi-
the widget types either. If
you see
see the appropriate chapter for that
widget to learn more.
Entry Widget The
line of text at most,
so a vertical scrollbar
create a scrolled entry widget $inw->Scrolled( "Entry" If
The entry can only contain one would do nothing. Using Scrolled to
entry widget can only be scrolled horizontally.
you want
requires
it,
to
make
,
is
easy:
-scrollbars => "s", -width => 30)->pack();
the scrollbar only
use -scrollbars
=>
show when
"os". Using the
the data in the entry widget
Scrollbar method
more work: $scrollbar = $niw->Scrollbar (-orient => 'horizontal'); $entry = $mw->Entry (-width => 30, -xscrollcommand => $scrollbar] set $scrollbar->configure( -command => ['xview', $entry] $scrollbar->pack(-side => 'bottom', -fill => 'x'); $entry->pack(-side => 'bottom', -fill => 'x'); [
'
'
,
)
)
Both
will create
an entry
that looks similar to the
one
in Figure 6-13-
is
a bit
;
)
,
138
Chapter
^j
Entry
j
.
iReally really really long
N
Scrollbars
6:
t
^
1
Exit
Figure 6-13- Entry widget with a scrollbar
Listbox, Text,
A
and Canvas Widgets
widget can be scrolled both horizontally and
listbox
might not always want to use both options. going to be and the
Our
essary.
first
If
window can accommodate
although you
vertically,
you know how wide your data it,
a horizontal scrollbar
example uses the Scrolled method and creates two
is
unnec-
is
scrollbars:
$mw->Scrolled( "Listbox" -scrollbars => "se", -width => 50, -height => 12)->pack(); ,
same thing manually, we need to use Scrollbar bars and configure them to work with the widget:
To do
the
$f = $inw->Frame() ->pack(-side => 'top', expand => 1, $xscroll = $f->Scrollbar (-orient => 'horizontal');
to create
two
scroll-
-fill => 'both');
$yscroll - $f->Scrollbar() $lb = $f->Listbox{ -width => 50, -height => 12, -yscrollcommand => ['set', $yscroll] -xscrollcoinmand => ['set', $xscroll] $xscroll->configure( -command => ['xview', $lb] $yscroll->configure( -command => ['yview', $lb] $xscroll->pack(-side -> 'bottom', -fill => 'x') $yscroll->pack{-side => 'right', -fill => 'y'); $lb->pack(-side => 'bottom', -fill => 'both', -expand => 1); )
Scrolled saves a lot of extra work. with two scrollbars, one on the south and one on
As you can a listbox
see, using
was created using Scrolled. There is a open space where the two scrollbars meet ate the scrollbars ourselves,
packed
first
Scrolled text
widget
One
is
takes
In Figure 6-14,
the east. This
we
see
window
subtle difference: the small square of in the southeast
comer.
When we
cre-
don't get that small space (whichever scrollbar gets
it).
and canvas widgets are created the same exact way a scrolled we won't bother repeating the same code again.
listbox
created, so
Scrollbar, Multiple Widgets
There are times
When
we
;
when you want
the user clicks
direction at the
same
on the
to use
scrollbar,
one it
more than one widget. the widgets in the same
scrollbar with
should
time. For this example,
scroll all
we
will create three listboxes,
each
Examples
139
J
ScrcMed Ustbox
->]
# Conversion from Tk4.0 scrollbar.tcl competed,
package Tk::Scronbar; require IK;
use AutoLoader;
@ISA =
qwCrX::Widget);
Construct Tk::W!dget 'Scrollbar'; bootstrap Tk::Scrollbar $Tk::VERSION;
sub Tk_cmd '
{
\8(Tk::scro[lbar }
R
/ i
'
\
Figure 6-14.
A
listbox with
two scrollbars
with eleven items. There will be one scrollbar that will scroll
all
on it. When the user tabs to the listboxes and scrolls by using the arrow keys or the pageup/pagedown keys, the other also scrolled. Figure 6-15 shows what the window looks like. the user clicks
—
cine Scfiiiiatf!iiir»3 five
^
when up and down
three
five
;SlX
six
six
jseven
seven
seven
eight
eight
eight
rane
nine
nine
ten
ten
ten
The code
A window
j
with three listboxes all controlled by the
for Figure 6-15
is
same scrollbar
as follows:
use Tk; MainWindow->new() Scrollbar /Three Listboxes"); $rnw->Button(-text => "Exit", -concnand => sub { exit } ->pack(-side => 'bottom');
$inw -
;
$iTiw->title( "One
)
$scroll = $mw->Scrollbar() # Anonymous array of the three listboxes $listboxes = $mw->Listbox $mw->Listbox( [
( )
,
listboxes are
"JUnH
Usttox£»
five
Exit
Figure 6-15.
lists
)
,
$mw->Listbox()
];
;
140
Chapter
6: Scrollbars
This method is called when one listbox is scrolled with the keyboard makes the scrollbar reflect the change, and scrolls the other lists sub scroll_listboxes { my ($sb, $scrolled, $lbs, @args) = @_; $sb->set (@args) # tell the scrollbar what to display my ($top, $bottom) = $scrolled->yview( foreach $list (@$lbs) { $list->yvievMoveto($top) # adjust each lb #
# It
;
)
;
}
}
Configure each listbox to call &scroll_listboxes foreach $list (@$listboxes) { $list->configure{-yscrollcommand => \&scroll_listboxes, $scroll, $list, $listboxes ]);
#
[
}
Configure the scrollbar to scroll each listbox $scroll->configure(-comaTiand => sub { foreach $list (@$listboxes) $list->yview(@_)
#
{
;
}});
Pack the scrollbar and listboxes $scroll->pack(-side ~> 'left', -fill => 'y'); foreach $list (@$listboxes) { $list->pack(-side => 'left'); $list->insert 'end' "one", "two", "three", "four", #
(
,
"seven",
"eight",
"nine",
"five",
"ten",
"six",
"eleven");
}
MainLoop; In order to connect multiple widgets to
command for
to create the scrollbar.
each of the listboxes
array so that
all
is
scrollbar,
we
use the Scrollbar
first
to configure
easily).
The other
each listbox to
part
subroutine
three listboxes in addition to adjusting the scrollbar. Normally,
all
-yscrollcoiranand would only have ['set',
$lb] assigned to
set from within
Fun Things
call
scrollbars for the
method you
it.
Instead,
we
that subroutine.
to Try
Create two of each scrollable widget type,
own
it
call a special
use a callback to \ScScroll_listboxes and
your
calls yview anonymous that makes the
the scrollbar so
are scrolling (the listboxes are kept in an
methods can reference them
listboxes truly connected that scrolls
we
one
Then we configure
make one Scrolled, and create will show you which
second of each type. This
prefer to use.
Create two scrollbars and attach them to the
same widget
(the opposite of our
one scrollbar/multiple widgets example). For instance, create a listbox with a scrollbar on the left and one on the right, both of which will scroll the listbox vertically.
The Listbox Widget
A
listbox widget
per
line.
box
is
designed to
You can then
list
strings of text,
one
select a line or multiple lines
text string
from the
list-
perform other operations on. Some examples of things to
to
place inside a listbox:
•
An
•
A
alphabetized
list
of
cities.
of servers to log in
list
password
into
some
to.
name and then
Select a server
entry widgets. Click the
OK
enter a
button to log
name and
in.
•
A
list
of operating systems.
•
A
list
of payment options: MasterCard, American Express, Visa, Check, Cash.
A
listbox
is
numerous
ideal for replacing radiobuttons or
checkboxes
that
have become too
on the screen. Usually 3 or 4 checkbuttons or radiobuttons if you had to try to display 10 at a time, the window could get a little crowded. A group of radiobuttons can be replaced by a listbox that limits the number of selections to one and has a default selection. A bunch of checkbuttons can be replaced by a listbox that allows multiple selections. to display
aren't a big deal, but
Creating To
and Filling a
create a listbox widget, use the $lb = $parent->Listbox(
The Listbox method can
now
use
this
[
Listbox
Listbox method on
options .. .]
the parent of the listbox:
)->pack;
returns a reference to the listbox that has
been
created.
You
reference to configure the listbox, insert items into the listbox.
141
; ;
;
,
142
;
Chapter
and so on. The most common thing insert method to insert items into it: $lb->insert{ 'end'
,
@listbox_i terns)
,
$iteinl,
to
do
after creating a
7:
The Listbox Widget
Hstbox
is
to use the
# or...
$lb->insert( 'end'
$item3);
$item2,
The insert method takes an index value arguments
will
be considered items
to
as the
be put
argument; the
first
rest
of the
into the listbox. Listbox indexes are
similar to the entry widget indexes except they refer to lines instead of individual
characters.
We
could use a listbox instead of radiobuttons to select our
color (see Chapter
The
ple).
listbox
Checkbuttons
4,
code looks
and
window background
Radiobuttons, for the radiobutton exam-
like this:
$lb = $rnw->Listbox(-selectmode => "single" ->pack() $lb->insert 'end' qw/red yellow green blue grey/); $lb->bind( '' sub { $lb->configure( -background => $lb->get $lb->curselection )
{
,
(
( )
)
)
});
The -selectimode option limits the number of selections to one. "We insert some colors to choose from. There is no -command option for a listbox, so we use bind (see Chapter 14, Binding Events) to have something happen when the user clicks on an item with the left mouse button. Using the listbox methods get and curselection, we determine which item the user clicked on and then set the background of the here;
listbox to that color.
There are only
you can use more colors and add
can add a scrollbar by changing the
line
five colors in
a scrollbar to
make
with Listbox in
it
more
our example useful.
You
it:
$lb = $mw->Scrolled{ "Listbox" -scrollbars => "e", -selectmode => "single") ->pack() ,
All the other lines in the
adding and
an example,
we want
program remain unchanged. For more information about
utilizing scrollbars, let's
see Chapter
6,
Scrollbars.
go over the options and methods
Now
that let us
that
we've looked
use the listbox the
at
way
to.
Listbox Options As with any of the widgets, you can configure the listbox using options. The
stan-
dard widget options are -cursor, -font, -height, -highlightbackground,
-highlightcolor, -highlightthickness, -takefocus, -width, -xscrollThe options that behave the same for each widget will only be listed in the following list. Those options specific to listbox coramand, and -yscrollcommand.
widgets will be discussed
later in this chapter.
143
Listbox Options
-background =>
color
Sets the color of the area
behind the
text.
-borderwidth => amount Sets the
width of the edges of the widget. Default
is 2.
-cursor => cursomame Sets the cursor to display
-exportselection => Determines tion as well.
the
same
when
the
mouse
is
to
If set
1,
listbox.
1
|
the current listbox selection
if
over the
is
made
available for the
X
selec-
prevents two listboxes from both having selections
at
time.
-font => fontname Sets the font of any
-foreground =>
text displayed within the listbox.
color
Sets the color of nonselected text displayed in the listbox.
-height => amount Sets the height of the listbox.
-highlightbackground =>
color
Sets the color the highlight rectangle should
be when the
listbox
does not
have the keyboard focus.
-highlightcolor =>
color
Sets the color the highlight rectangle
should be
when
the listbox does have
the keyboard focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle. Default
-relief => 'flat'
'groove'
|
Sets the relief of the
'raised'
edges of the
-selectbackground => Sets the color
|
|
is 2.
'sunken'
'ridge'
|
'solid'
listbox.
color
behind any selected
text.
-selectborderwidth => amount Sets the
width of the border around any selected
-selectforeground =>
color
Sets the color of the text in
-selectmode => "single" Affects
how many
text.
|
any selected
"browse"
items can be selected
items.
at
once; also
bindings for the listbox (such as Shift-select). Default
-setgrid =>
|
1
Turns gridding off or on for the
"extended" affects some key/mouse
"multiple"
|
listbox. Default
is 0.
is
|
"browse".
144
Chapter
-takefocus => never,
1
1
|
Determines the
7:
The Listbox Widget
undef
|
ability of the
widget to get the keyboard focus or not.
means always, undef means dynamic
means
decision.
-width => amount Sets the
width of the listbox in characters.
made
wide
as
If
amount
is
or
less,
the listbox
is
as the longest item.
-xscrollcoinmand => callback Assigns horizontal scrollbar to widget. See Chapter
6.
-yscrollcoramand => callback Assigns vertical scrollbar to widget. See Chapter
Selection As part of the
6.
Modes
listbox widget,
select items in the listbox.
you
are given several choices in the
You can have
selected (emulating radiobuttons), or
it
so only one item
you can have many
at a
way you can time can be
different contiguous or
noncontiguous items selected (emulating checkbuttons). You control
this
behavior
with the -selectimode option.
The
possible
select
modes
are
"extended". The default mode
is
"browse",
"single",
"multiple",
or
"browse".
browse & single The "browse" and "single" modes are similar in that only one item can be selected at a time; clicking on any item will deselect any other selection in the listbox. The browse mode has a slight difference: when the mouse is held down and moving around, the selection moves with the mouse. For bind purposes, a "" bind will be invoked when you first click down. If you want to catch the event when the mouse is released, define a ButtonRelease binding (binding events to widgets is discussed in Chapter 14). extended The "extended" mode lets you select more than one item at a time. You can click on a single item with the left mouse button, but it will deselect any other selection. To select more than one item, you must Shift-click or Control-click more items. Shift-clicking (holding down the Shift key while pressing a mouse button) will extend the selection from the already selected item to the newly selected item. Control-clicking (holding
mouse alter
button) will
any of the other
button, hold
down
select them. This
is
down
the Control key while pressing a
add the item being clicked on to the selection, but selections.
it
won't
You can also click an item with the mouse move the pointer over other items to
the button, and then
what
for very fast selection of
I
call a click-drag
many
motion. Using "extended" allows
different items in the listbox.
145
Colors
multiple The "multiple" mode
you to select more than one item. Instead you have to select items one at a time. select it, and selecting an already selected
also allows
of Shift-clicking or Control-clicking, Selecting an unselected item will
item will unselect
it.
Operating System Differences when
-selectmode feature, I discovered that Windows 95 does not allow the "multiple" selection mode to behave properly. It behaves the same as "single" mode on Windows 95 only. On Unix and Windows NT, "multiple" mode works correctly. testing the
When you tion
select
an item
in a listbox,
(meaning you can cut and paste
by default
it
any
X
it
like
made
is
available as an
X
selec-
any window). Even
selection in
do anything with the clipboard on Win32 systems, it still affects the selection in multiple listboxes. Items can be selected in only one listbox at a time, even if you have more than one listbox. The option -exportselection controls this. Use -exportselection => to allow items to be though
this
selected in
doesn't
more than one
listbox at the
same
time.
Colors In
most widgets there
those,
we
also
is
a
-background and
a
-foreground
color. In addition to
have the -selectbackground and the -selectf oreground color
options in a listbox.
When
a listbox entry
is
selected,
it
appears in a different
color.
Although you can change the color of the selected color.
You cannot make
text,
you can only use one
different lines in the listbox different colors.
U$$toK
E
p
one
Ustbox
•tH^al
one
two
two
three
three
four
four
/
five
Figure
7-1.
Examples of -foreground, -background,
In Figure 7-1, the listbox
on the
ground
=>
'red',
-selectbackgroimd =>
left
-selectforeground,
has -foreground
'green'. The listbox on the
right
and
=>
-selectbackground
'red',
-back=>
has -select foreground
'green'. Make sure that the foreground and
background values contrast with each other
if
you change these
options.
146
Chapter
7:
The Listbox Widget
Listbox Style -relief of a listbox is 'sunken'. The default -borderwidth is 2. shows the five different relief types (flat, raised, ridge, groove, and sunken). In the first window, the default -borderwidth is used; in the second window, a -borderwidth of 4 is used. To save space in the windows, I didn't draw any scrollbars. The
default
Figure 7-2
_l
Figure
Style
h
UstiMix
Ustbox
-^
J|
mm^^
one
one
one
one
one
one
one
one
one
one
two
two
two
two
two
two
two
two
two
two
three
three
three
three
three
three
three
three
three
three
four
four
four
four
four
four
four
four
four
four
five
five ~—;
five
five
ifive
five
five
five
five
five
!
Examples of -relief and -borderwidth in
7-2.
listboxes
of Selected Items
is also a borderwidth associated with any selected text. This is controlled by -select±)orderwidth option. Figure 7-3 shows what changing the selection
There the
borderwidth to 4 does to the
listbox.
-^Jl lone
two
1 5
.three
four five *
t
\
1
Figure
Example of -selectborderwidth => 4
7-3-
Special Listbox Resizing The -setgrid option changes how the window is drawn when it's resized. Using -setgrid => 1 causes the window to stay resized to the grid created by the listbox widget. Essentially, this means that the listbox will display only complete lines (no half
lines)
always display
and complete at least
option has nothing to
box
in the
window.
characters.
A
side benefit
is
that the listbox will
and can't get resized off the visible window. This do with which geometry manager you use to put the listone
line
147
Inserting Items
Listhox Indexes The items in an entry widget are ordered. The first listbox item is at index 0, and the numbers increment by 1 These values are valid for any of the methods .
an index value.
that require
n
An
integer index.
The
item in a listbox
first
index
at
is
0.
"active"
The index within
the listbox that has the location cursor.
has the keyboard focus,
it
will
If
the listbox
be displayed with an underline.
"anchor" This index
is
set
with the selectionAnchor (...) method.
"end"
The end of it
or
the listbox.
Depending on which method
mean just after the last element could mean the last element in the
could it
is
using this index,
when insert is used), (such as when delete is
(such as listbox
used).
"@x,y"
The
listbox item that covers the point at the coordinate x,y (pixel coordi-
nates).
The
closest item will
be used
if
x,y
is
not
at a specific item.
Configuring a Listbox You can use the cget method to options. You can use configure
find out the current value of
any of the listbox
to query or set any of the listbox options. See Appendix A, Configuring Widgets with configure and cget, for more information on using the configure and cget methods.
Inserting Items Use the insert method $lb->insert
to
add items
element,
(;>7insert
(
,
beginning of the
@new_elements
7:
The Listbox Widget
listbox:
)
Deleting Items You can use
delete method
the
$lb->delete{firstindex-
The
first
just that
[,
from the
listbox:
lastindex ]);
argument is the index from which to start deleting. To delete more than one item, you can add a second index. The firstindex must be less than or
equal to the lastindex specified. $lb->delete(0,
To
to delete items
To
delete
the elements in the listbox:
all
'end');
delete the last item in the listbox:
$lb->delete
( '
end
'
)
Retrieving Elements The get method
returns a
of listbox elements specified by the indexes first to
list
last:
$lh->get firstindex {
If
only the firstindex
be
less
is
[,
specified, only
than or equal to the lastindex.
©elements = $lb->get(0,
To
lastindex
])
one element
To
get a
list
of
is
returned.
all
The firstindex must
elements
in the listbox:
'end');
get the last item in the listbox:
$lastitem = $lb=>get 'end' (
To
find
)
out which items in the listbox are selected, use the
curselection
method: @list = $lb->curselection()
containing the indexes of
It
returns a
list
If
no items
are selected,
ple of
how
the
all
currendy selected items
curselection returns an empty curselection method is used:
string.
in the listbox.
Here
is
an exam-
©selected = $lb->curselection; foreach (©selected) { # do something with the index in $_ }
Make
sure to
remember
that
curselection
returns a
list
of indexes, not elements.
Selection
149
Methods
Selection
Methods
The curselection method, discussed in the preceding section, only what the user has selected. You can also change the selection by using the selection method.
tells
a
you
form of
Selecting Items To select a range of items in a listbox, you can use the "set" form of the selection method (selectionSet). select ionSet takes either a single index or a range. Any items not in the range are not affected. If you use a range, the first index must be less than or equal to the last index. Here are some examples: select everything $lb->selectionSet(0, 'end' ttselect the first item $lb->selectionSet (0) #
Even
if
);
you have used -selectmode
to limit the selection to only
one
item,
you
can force more than one item to be selected by using selectionSet (...)•
Unselecting Items To clear any selections in the listbox, use the "clear" form of the selection method (selectionClear). Pass in an index or a range or indexes from which to remove
clear the selection. For instance, to
would do
all
the selections in the listbox,
you
the following:
$lb->selectionClear (0,
Any indexes
"end");
—
outside the specified range will not be unselected
unselect one item
at a time.
You can
$lb->selectionClear "end"
also clear the selection
this
from
just
allows you to
one
item:
{
)
Testing for Selection To test to see if a specific index is selection (selectionlncludes). item last
at
the specified index
item in the if
}
list is
is
already selected, use the "includes" form of Calling
selected
and
selected:
($lb->selectionIncludes 'end' (
)
)
{
selectionlncludes if it is
not.
returns
1 if
For instance, to see
if
the the
;
;
;
;
;
150
Chapter
7:
The Listbox Widget
Anchoring the Selection Using the "anchor" form of selection (select ionAnchor) to
"anchor"
mouse
used
is
when you
set the
index
are using the
The first item you click becomes the "anchor" index. For exam-
cursor to select several items within the listbox.
(without letting up on the ple,
The "anchor"
to the specified index.
you would use
mouse
button)
this to set the
anchor as the
first
item in the
list:
$lb->selectionAnchor (0)
Moving To cause
a
to
the listbox to
%Vo->se.& {index)
show
Index
a specific item,
you can use the see method.
;
Given an index, see index. For
Specific
will
cause the listbox to page up or
an example of using see, look
at
the Listbox
down
to
Example
show
the item at that
later in this chapter.
Translating Indexes The index method
an index specification (such as "active") into the = if the listbox contained 12 items, $index
translates
numerical equivalent. For instance,
$lb->index( "end") would item in a listbox
is
at
index
set the variable
$index
to 11.
(Remember
the
first
0.)
Counting Items The size method
returns the total
number
of items in the listbox:
$count = $lb->size();
Active Versus Selected The activate method will set the listbox item at index index to the active element. This allows you to access this item later using the "active" index. Figure 7-4 shows two windows with active elements underlined. Each listbox also has the black highlight rectangle around it, which indicates it has the keyboard focus (the active element isn't seen as marked unless the listbox has focus). The first window activates the item "four" $lb->activate(3) $ lb- > focus # The second window activates the item "three" $lb2->activate(2) $lb2->focus() #
( )
Scrolling
Figure
Methods
7-4.
151
Windows showing a
listbox with
an
"active" element
Bounding Box The method bbox around the ($x,
returns a
list
of four elements that describes the bounding
box
text at index.
$y,
$w,
$h)
= $ lb- >bbox( index)
The four elements are (in order): x, y, w, and h. The x,y coordinates are the upper left corner of the bounding box. The w is the width of the text in pixels. The h is the height of the text in pixels. These measurements are shown in Figure 7-5.
x,y Text
in
listbox
h
W Figure
7-5.
Bounding box values around text
Finding an Index by Y Coordinate If
you know
a
y coordinate in the listbox, you can determine the index of the it by using the nearest method:
nearest listbox item to
$index = $lb->nearest {y)
The nearest method
returns a
number
that
corresponds to the index of the clos-
est visible listbox item.
Scrolling
Methods
The listbox can be scrolled both horizontally and vertically so it has both xview and yview methods and all their associated forms. These forms and how to use them are described in detail in Chapter 6.
;
;
;
152
Chapter
7:
;
The Listbox Widget
The scan method allows you to use a really fast scrolling method. It is automatically bound to the second mouse button by the listbox. Here is how you can do the same thing within your window: $mw->bind( "Listbox" $inw->bind( "Listbox"
When you
""
""
[
'scan'
,
window
click in the
your mouse around, speed.
,
,
,
'mark' ,Ev( 'x' [
,
'scan'
,
]
)
)
with the second
to bind this to another combination of
method
is
explained in Chapter
,Ev( 'y'
)
]
)
mouse button and then move by
at super-fast
bind statement if you keys/mouse actions. The bind
14.
Example
Sometimes when you put
ment
)
the second argument of each
wanted
through the
)
you'll see the contents of the listbox zip
You could change
Listbox
,Ev( 'y'
'dragto' ,Ev( 'x'
listbox. If
a lot of items in a listbox,
you
it
takes a long time to scroll
insert the items in the listbox sorted,
a search routine. Here's a quick script that
shows you how
you can impleto use
an entry
widget to input the search text and then search the listbox every time you get
new
character in the entry:
use Tk; $inw =
MainWindow->new;
$rnw->title "Listbox" (
)
;
For exaitple purposes, we'll use one word for each letter @choices = qw/alpha beta charlie delta echo foxtrot golf hotel India Juliet kilo lima motel nancy oscar papa quebec radio sierra tango uniform victor whiskey xray yankee zulu/; #
Create the entry widget, and bind the do_search sub to any keypress $entry = $mw->Entry(-textvariable => \$search) ->pack(-side => "top", -fill => "x"); \&do_search, Ev("K") $ent2ry->bind( "" #
,
[
]
)
Create listbox and insert the list of choices into it $lb = $mw->Scrolled( "Listbox" -scrollbars => "osoe", ->pack(-side => "left"); $lb->insert "end" sort ©choices) #
rny
,
)
(
,
$mw->Button(-text => "Exit", -command => sub
{
exit;
})
->pack(-side => "bottom");
MainLoop; # This routine is called each time we push a keyboard key. sub do_search { my (Sentry, $key) = @_;
a
Fun Things
to Try
153
Ignore the backspace key and anything that doesn t change the word The Control or Alt keys return if ($key =~ /backspace/i) rettum if ($oldsearch eq $search) #
'
# i.e.
Use what's currently displayed in listbox to search through This is a non-coir^slicated in order search my ©list = $lb->get(0, "end"); foreach (0 $#list) { if ($list[$_] =~ /^Ssearch/) { $lb->see{$_) $lb->selectionClear (0, "end" $lb->selectionSet($_) # #
.
.
)
;
last; }
>
$oldsearch = $search;
Fun Things Use
a listbox to create a
mini
file
when you
click
on
a button that, file
to Try
becomes one
viewer. Use an entry field to read a filename and it,
loads the
entry in the listbox).
file
into
your listbox (each
line in the
The Text Widget
when you
think about what a text widget might do,
displays text." This
is
tnie, yet
can do quite a
it
bit
you automatically more. The text widget
the most powerful standard widgets available in Perl/Tk. urable,
and easy
It
is
is
flexible,
Here are some examples of
to use for simple tasks.
think,
"it
one of config-
how you
can
use text widgets: Display and edit a plain text
file.
HTML
Display formatted text from an
document.
Create a scrollable color key, with buttons that allow you change the colors
Gather multiline, formatted text (including colors) from a user (mini word processor).
Display text with different colors based on the input.
Make
on. This could be
You can text
put simple
HTML, or
text,
widget can be used
Creating
it
could be similar to the widget demo.'
formatted
much
create a text widget, use the (
[
with scrollbars to allow
154
many pages
A of
Text Widget
Text method from
options
...
]
)
the desired parent widget:
->pack;
When you in.stalled the Tk module with Perl, you also in.stalled command line to .see the capabilitie.s of widgets in Perl/Tk. •
inside a text widget.
less space.
and Using a
$text = $parent->Text
and other widgets
text,
in conjunction
information to be viewed in
To
and perform an action when clicked
certain portions of text "clickable"
the widget
demo. Type widget on the
Text Widget Options
155^
After the text widget
The user can type
directly into
$text->insert 'end' (
The
basic form of the
,
insert method
A
you do, only the
typical use of the text
it's
start
takes
placing the
two arguments. The
first
widget
item in the array is
to read a
file
first is
The second argument
text.
insert method, you
to insert. Unlike the listbox If
it,
text in
it.
"To be or not to be...\nThat is the question");
value that indicates where to
argument.
ways to place or you can use the insert method:
created, there are several different
is
can't use is
an index the string
is
an array as the second
inserted into the text box.
and place
it
in the text
widget as
read:
$text = $inw->Scrolled("Text") ->pack() die "Could not open chapterl"; open (FH, "chapterl") while () { $text->insert 'end' $_) ;
|
|
(
,
}
close (FH)
You can use
the text widget to display the
ing the insert line to
$text->insert (0,
backward
file
$_)
.
(line
by
line)
by chang-
This will put the next line read
at
the top of the text widget instead of at the end.
The
text
widget can do a
lot
more than
Shakespearean play. In addition to options, to control
how
display a
just
we
also
file
have
or
two
lines
tags, indexes,
from a
and marks
the contents of a text widget are displayed.
Text Widget Options Options used with the Text method change the
way
the text
within the text widgets. The following options are standard for
all
is
displayed
the widgets:
-borderwidth, -cursor, -exportselection, -foreground, -highlightbackground, -highlightcolor, -highlightthickness, -insert-
-background,
-insertontime, -insertborderwidth, -insertofftime, -insertwidth, -padx, -pady, -selectbackground, -selectborderwidth, -selectforeground, -setgrid, -state, -takefocus, -wrap, -xscrollcommand, and -yscrollcoitimand. background,
To
more about what these options do, check back where they were first covered.
find out
Button,
-background =>
to
Chapter
3,
The Basic
color
Changes the color of the screen displayed behind the
text.
-borderwidth => amount Sets the
width of the edges of the widget.
-cursor => cursomame Sets the cursor displayed
when
the
mouse
cursor
is
in front of the text widget.
|
156
.
Chapter
-exportselection => Determines
if
The Text Widget
1
|
the text selected within the widget can also be used
dowing system (such
as
X
-font => fontname Sets the font in which the
-foreground =>
8:
by the win-
windows).
text
is
displayed.
color
Sets the color of the text.
-height => amount Sets the height of the widget. Default
-highlightbackground =>
is
24.
color
Sets the color the highlight rectangle
around the widget should be when
it
around the widget should be when
it
does not have the keyboard focus.
-highlightcolor =>
color
Sets the color the highlight rectangle
does have the keyboard focus.
-highlightthickness => amount around the widget. Default
Sets the thickness of the highlight rectangle
is 2.
-insert±)ackground => color Changes the color of the
insert cursor.
-insertborderwidth => amount Changes the width of the
insert cursor.
-insertofftime => time Sets the time the insert cursor blinks in the off position. Default
is
300.
is
600.
-insertontime => time Sets the time the insert cursor blinks in the
on
position. Default
-insertwidth => amount Sets the
width of the
-padx => amount Adds extra space -pa amount Adds extra space
insert cursor.
to the left
and
to the top
right of the text inside the text widget's edge.
and bottom of the
text inside the text widget's
edge.
-relief => 'flat'
|
Sets the relief of the
'groove'
|
'raised'
|
'ridge' 'sunken' sunken is
edges of the widget. Default
-selectbackground =>
color
Sets the color of the area behind the selected text.
-selectborderwidth => amount Sets the width of the border of the selected area.
'
'
|
'solid'
157
Text Widget Options
-selectforeground =>
color
Sets the color of the selected text.
-setgrid =>
1
|
Enables gridding for the text widget. Default
-spacingl => amount Sets the amount of additional space its
own
Default
line.
left
is 0.
on top of
a line of text that begins
-spacing2 => amount Sets the amount of additional space left on top of a line of text after been wrapped around automatically by the text widget. Default is 0. -spacingS => amount Sets the amount of additional space a "\n". Default
left after
a line of text has been
it
has
ended by
is 0.
-state => 'normal'
'disabled'
|
Indicates the state of the text widget. Default
abled', no
on
is 0.
is
'normal'.
If set
to
can be inserted by either the user or the application
text
'dis-
(via the
insert method). -tabs =>
list
Specifies a
no
list
of tab stops to use in the text widget. Default
is
undefined (or
tab stops).
-takefocus => Determines
if
|
1
|
undef
widget can obtain keyboard focus.
-width => amount Sets the
width of the
-wrap => "none" Sets the
|
text
widget
"char"
mode used
in characters. Default
is
80.
"word"
|
to determine automatic line wrapping. Default
is
"char".
-xscrollcornmand => callback Determines the callback used
when
the text widget
is
scrolled horizontally.
when
the text widget
is
scrolling vertically.
-yscrollcoitimand => callback Determines the callback used
Fonts You can use the text
is
Text that
the
-font option
to
change the
font, including
is
inserted without a text tag (a tag allows
you specify
that applies only to certain portions of the text) will
use
was covered
first
The use of option.
how
large or small
(see Figure 8-1). This defines the default font for the entire text widget.
fonts
in
Chapter
3,
the
special formatting
this font.
time
we saw
the
-font
158
Chapter
8:
The Text Widget
J
Text
This is a different font! !
are using fontname "rl6'
Figure 8-1. Text widget using -font => "rl6"
Widget Size When you a
first
create a text widget,
it
will usually
width of 80 characters. Depending on
have
how you
a height of 24 lines
and
put the text widget in the
window (whether you
use pack with the -expand and -fill options or grid —sticky => "nsew"), it can change size when the window changes size. To force a certain size, you can use the -width and -height options: with
Text widget 20 characters wide and 10 lines tall $raw->Text -width => 20, -height => 10)->pack;
#
(
The values associated with -width are in characters, and the values associated with -height are lines of text. It is possible that the text widget will not be that exact width and height if you force the window to be larger via the minsize routine (i.e., $itTw->itiinsize(400,400)), especially if you used -expand => 1 and -fill => 'both' with the pack command. So if you don't see what you expect on the screen the first time out, keep this in mind.
Widget Style As with other widgets, you can change
how
drawn using -relief and -borderwidth Figure 8-2 might not look
much
the edges of the text widget are options.
like text widgets,
but
The examples shown
trust
me
—they
in
are!
Line Spacing When
text is displayed in a text widget, it can wrap around automatically if becomes longer than the text widget can display. The amount of room between lines is defined by using the - spacing A^ options. Figure 8-3 shows different areas that -spacingl, -spacing2, and -spacingS affect. line
the left
the
how much room is above a new line of text (the The -spacing2 option affects the space between lines when text that is wrapped automatically is too long to fit on one line. The -spacingS option determines how much room is left after a paragraph is finished
The -spacingl option first
affects
line in a paragraph).
(right after
an
explicit newline).
159
Text Widget Options
^
Text
Jl
-relief => flat
-relief => groove 1
-relief => raised
-relief => ridge
-relief => sxmken
Figure 8-2. Text widgets showing different -relief values (also shows use of -width options to force smaller size)
and
-height
-spacingi
This
is
a line of text.
It
can wrap around to the
-spacingi!
next line and even another
line.
The spacing
•spacing2
how much space
determines
]
is left
between
spacing2 lines.
-spacingS \
-spacingi
and between paragraphs
Figure 8-3. Example of -spacingN options
Tab Stops The
default setup for text widget tab stops
equals eight spaces (but default setting
it
by using the -tabs option
-tabs => [qw/2 center/] -tabs => [2, "center"]
is
ever/ eight characters. Each tab
doesn't actually use spaces).
#
#
You can
replace this
as follows:
Place tabs every 2 pixels The same tiling, different syntax
The argument that goes with -tabs is an anonymous list that specifies positions in which to place each of the tab stops. You can also specify an optional justification value for
each tab stop (as
in the
preceding example)
after
each tab stop's
;
:
160
Chapter
numerical value. This
some examples
sounds much more confusing than
all
The Text Widget
really
Here are
is.
to help clarify things:
-tabs => [qw/li center/] -tabs => [qw/li 1.5i/]
The
it
8:
default justification
#
every inch, text centered on tab-stop at 1 inch, 1.5 inch and every .5 inch after
# ts
"left". The possible
is
justification values are
"left",
in centimeters, inches, or pixels),
they are
"right", "center", or "numeric".
"When you specify the values (whether not cumulative. The
edge of the
the
left
left
edge.
If
the specified
tance between the
Of
course, setting
editing, so in
You can
last
list
two tab stops
up new
most
"1.5i"] translates to one tab stop at 1 inch from and the next tab stop will be 1.5 inches from the isn't long enough to span the entire window, the dis-
["li",
list
text widget,
tab stops
specified will be repeated across the screen. is
pretty useless unless you're doing major text
cases, you'll leave this option alone.
reset the tab stops
back
to the default
by
setting
-tabs
to
undef
$text->config\ire (-tabs => undef);
A
Short Break for a Simple Example
Before
we
get into
with a text widget, This
is
a short
then save
some of let's
look
program
the at
more complex (and more fun)
complete use of the
that will display a
file,
let
things
you can do
text widget.
you make changes
to
it:
use Tk; $itiw = MainWindow->new; # Create necessary widgets $f = $inw->Frame->pack(-side => 'top', -fill => 'x'); $f->Label (-text => "Filename: ") ->pack (-side ==> 'left', -anchor => 'w'); $f->Entry(-textvariable => \$filename) ->pack(-side => 'left', -expand => 1) -anchor => 'w' -fill => 'x' $f->Button(-text => "Exit", -command => sub { exit; } -> pack (-side => 'right'); $f->Button(-text => "Save", -command => \&save_f ile) -> pack (-side => 'right', -anchor => 'e'); $f->Button(-text => "Load", -command => \&load_f ile) -> pack (-side => 'right', -anchor => 'e'); $mw->Label (-textvariable => \$info, -relief => 'ridge' )-> pack(-side => 'bottom', -fill => 'x'); $t = $mw->Scrolled( "Text" ->pack( -side => 'bottom', -fill => 'both', -expand => 1); ,
,
)
)
MainLoop; # load_file checks to see what the filename is and loads it if possible sub load_file {
it,
and
161
Text Indexes
$info = "Loading file $filename' " $t->delete("1.0", "end"); if (!open(FH, "$filenaine" { "ERROR: Could not open $filenaine\n" $t->insert "end" return; .
'
.
)
.
)
(
,
)
>
while () { $t->insert "end" $_) close (FH) $info = "File '$filenaine' loaded"; (
,
}
;
}
# save_file saves the file using the filename in the entry box. sub save_file { $info = "Saving '$filename' " open (FH, ">$filenaine" print FH $t->get "1.0" "end"); $info = "Saved. "; )
;
(
,
}
Figure 8-4' shows the
Filename:
window when
a
document has been loaded and saved.
Itexffile
This is a file that just contains text. You can add text
,
or delete text
You can create a file just by typing text here, then entering a new filename, and clicking save.
J^ Saved.
Figure 8-4. Simple file editor with a "text/He" loaded
Text Indexes When we listbox.
talked about listbox index values, each index referred to a line in the
The
first
line in the listbox
was
at
the index can point to a specific line, but that line.
An
index for a text widget
is
index it
*
should be put
in
and so on. With a
text widget,
can also point to a character within
built
optionally modifying that index with a modifier. fier
0,
by using a base index and then The entire index, base, and modi-
double quotes.
For those of you paying attention, you'll notice this screenshot looks slightly different. That's because was taken off of Windows 95 instead of X Windows. Note the "Tk" in the upper left-hand corner, and
this
the
Windows
controls in the upper-right.
162
Chapter
8:
The Text Widget
Base Index Values "n.m" This format allows you to explicitly specify a line
number within widget), "
that line. Lines start at 1
and characters
(which
number and
a character
different than the listbox
is
start at 0.
&x,y"
The
character in the widget that
is
closest to the x,y coordinate.
"end"
The very end of the "
text widget, after
any "\n" characters as
well.
mark" Specifies the character after the location
named mark. The two mark names
provided by Tk are "current" and "insert". What they refer to cussed
is
dis-
later in this chapter.
"tog. first"
A
tag
name
is
simply a placeholder for some special formatting instructions
(discussed in the very next section). After creating tags, you can use this index form. tag. fir St is,
is
the
first
character in the text widget that
you could create a "heading"
tag
is
of type tag. That
and use "heading, first" index.
"tag.last" Specifies the character directly after the text
$widget If you have an embedded widget, you can widget by the variable referring to it.
marked with
refer to
its
tag.
location within the text
$ image
You can have embedded images using the variable referring to
as of TkS.O.
You can
refer to
its
location
by
it.
Index Modifiers The index modifiers can be used following [
+
a base index value.
chars lines — You can use the + and to add/subtract lines and characters to a base index. The index "end — 1 chars" refers to text on the line before the "end". Be careful when you use this, though, because any "\n" lines also count as a -
]
count
[
]
|
I
complete
line.
lines tart JVIodifies
the index to refer to the
insert ("end linestart", the
last
line in the text widget,
index given.
first
$string)
insert
character
on
that
line;
i.e.,
$t->
will insert the string at the front of will place the
new
text before the
163
Text Indexes
lineend Refers to the last character in the line (usually the newline).
you don't know the exact number of characters text at the end of it.
in a line
It
is
useful
when
but want to insert
words tart Adjusts the index to refer to the
first
word
character at the start of the
that
contains the base index.
wordend Adjusts the index to refer to the character after the
end of the word
that con-
base index.
tains the
Text Index
Examples
"end"
The
position right after the last line of text in the widget,
text
is
no matter how much
in the widget.
"1.0"
The and "2.0
character
first
on the
line in the text widget.
first
The
1 represents the line,
represents the character.
-
1
The
chars"
on the end of the first line. We reference it by using the first on the second line (2 0) and subtracting one character value from If we used the insert method with this item, we would insert the text before the "\n" at the end of the first line.
last
character
character that.
right
.
"Lend" Also the ting to
last
character
on the end of the
first line.
This
is
a simpler
way
of get-
it.
"2.0 lineend"
The end of 2
The little
is
the second line.
It is
necessary to specify 2.0, not
just 2,
because
an invalid base index.
basic indexes are easy.
When you
more complicated. You
just
position in the text widget that
start
doing index arithmetic,
have to remember
may change
if
that
you
it
becomes
a
are referring to a
other text has been inserted or
deleted (either by the user or the application).
Although some of the combinations start"), keep
in
mind
that
you
will
may seem most
silly (for
likely
be
example, "1.0
calling
methods
line-
that return
indeterminate information about an event. For example, a user clicks in the text
widget and presses a button that
index arithmetic allows you to reference that entire line sure
which
line
it
is
on.
The without even knowing for
will increase the font size of that entire line.
.
164
Chapter
8:
The Text Widget
Text Tags Text tags give you another
way
to address portions of text in the text widget.
has three purposes, and the same tag can serve •
Assigning formatting information to a portion(s) of text
•
Associating a binding with text in the widget
•
Managing selected
how
and spacing are among
change
tag
text
Tags are also used to change ing,
A
three or only one:
all
text properties
the text appears
few of the
a
on the
screen: font, size, color-
text properties affected
by creating your own
tags (with their
own
by
tags.
You
names), and
using option/value pairs to assign formatting information. In addition to changing
you can use a tag to apply a specific binding (such as perform a on that text). A special tag "sel" manages the selected Anytime the user selects some text, the location of that text is marked with
the formatting,
when
task text.
the tag
Any it.
sel "
of the text within the text widget can have one or
you apply two
If
last
"
the user clicks
tags to the
same piece of
text
more
tags associated with
and they both
alter the font, the
tag applied wins.
Options Used With Tags The options you can use
to configure
figuration options of the text widget
be used through tagged
-background =>
tagged text are mostly a subset of the con-
itself.
There are some options that can only
text.
color
Sets the color of the area
behind the
text.
-bgstipple => pattern Sets the pattern
used to draw the area behind the
text.
Can
create a
shaded
look.
-borderwidth => amount Sets the
width of the
relief
drawn around the edges of
-fgs tipple => pattern Sets the pattern
used to draw the
-font => fontname Sets the font
used
-foreground =>
for the text.
color
Sets the color of the text.
text.
the text, line by line.
165
Text Tags
-justify => 'left'
'right'
|
|
'center'
Sets the position of the text within the text widget.
-linarginl=> amount
amount of indentation from the
Sets the
left
edge
for the
first
line of a paragraph.
-Iinargin2=> amount
amount of indentation from the left edge for the second and of a paragraph. Sometimes called a hanging indent.
greater
Sets the lines
-offset => amount Sets the amount the
text
to create superscripts
-overstrike => If
and
is
raised or lowered from the baseline.
1
|
have a
a true value, causes the text to
-relief => 'flat'
'groove'
|
way
Determines the
Can be used
subscripts.
|
line
drawn through
'raised'
|
'ridge'
it.
|
the edges of the text are drawn, line by
-rmargin => amount Sets the amount of space
left
between the
text
and the
'sunken' line.
right
edge of the
widget.
-spacingl => amount Sets the amount of additional space its
own
line.
Default
left
on top of
-spacing2 => amount Sets the amount of additional space left on top of a line of text after been wrapped around automatically by the text widget. Default is 0.
-spacingS => amount Sets the amount of additional space a "\n". Default
-tabs =>
on
a line of text that begins
is 0.
left after
a line of text has
it
has
been ended by
is 0.
list
Indicates the set of tab stops for this text. See "Tab Stops" earlier in this chapter for
more
detailed information.
-underline => boolean Indicates that the text should be
-wrap =>'none' Determines the
|
'char'
mode
in
|
will
underline.
'word'
which the
text
is
wrapped, 'none' means
wide are not wrapped, 'char' wrap between words.
are longer than the text widget
each character, 'word'
drawn with an
is
lines that
will
wrap
at
;
166
A
;
Chapter
8:
The Text Widget
created and use
it
to insert
Simple Tag Example
Let's
look
at
how
an example of
a simple tag
widget (the resulting screen
text into a text
$t = $inw->Text
( )
->pack
(
)
is
is
shown
some
in Figure 8-5):
;
$t->tagConfig\ire{ 'bold' -font => "-*-Courier-Medium-B-NorTnal *-i20-*-*-*-*-*-*") # Use -font => "{Courier New} 24 {bold}" for Win32 systems $t->insert 'end' "This is some normal text\n"); $t->insert 'end' "This is some bold textXn", 'bold' ,
—
(
,
(
,
Line
creates the Text widget
1
Line 2 creates the ure"
same
as our
as
Unix
we
text
and places
it
on the
screen.
Don't be fooled by the use of the word "config-
tag.
When you
named 'bold' and
At this point,
up
'bold'
instead of "create."
ated a tag the
)
configure a tag, you are creating
associated a different font with
widget default
font, just the
it
(it
haven't changed anything in the text widget.
a valid text string.
font" or "tagl." If tain
cre-
to
be
We
are just setting
You can use any name to indicate a We could have named the tag "bold_font" or
you have good programming style (and want that indicates what the tag does.
to
tag as long
"big_bold_
be able
to
'bold'
tag.
main-
your code), use a name
Line 3 inserts
some
text into the text widget.
some more text into the insert method allows us to specify a
Line 4 inserts
string of text to
be inserted into the
text widget, but uses the
be shown with the
The
tag as the third argument. This causes that
text
widget and assigned the tag
'bold' tag was configured to change the will
We
bold version).
to use the tag later in the code. it is
it.
happens
font,
'
bold
'
.
The
so any text with the 'bold' tag
different font.
Ta«
-1
Bmrnmamaems^
some normal text This is some boldtoxt This
is
Figure 8-5. Text widget with normal
This in
is
and
bold text
What if we want to alter text that has been typed insert method then. We use the tagAdd method:
a pretty simplified example.
by the
user?
We can't use the
$t->tagAdd( 'bold'
This applies the
'
'1.0',
,
bold
'
tag to
'end'); all
of the text within the text widget.
167
Text Tags
Using the "seV'Tag to Manipulate the Selection The "sel" is
tag
is
a special tag that
is
maintained by the text widget. Any text that
by the user will be assigned the "sel" tag. You can also force the by using some of the tag methods (which we haven't covered yet) to put
selected
selection
the "sel" tag
on some
text.
"3.0",
$t->tagAdd("sel",
For instance, to select the third
line:
"3.0 lineend");
Here's an example that shows
how
to
add another tag
to the currently selected
text:
$t->tagAdd( 'bold'
When you
if
'sel. last')
($t->tagRanges 'sel' (
use the "sel" tag as part of an index, you need to
exists (using
huge
'sel. first',
,
tagRanges) within the
text
widget
first
make
)
)
sure the tag
or you'll get a really nasty
error.
Configuring
and
Creating Tags
by using tagConfigure (unless you're using the automatically defined "sel" tag). The first argument to tagConfigure is the name of the tag. The rest of the arguments (which are optional) are
The
first
thing you'll
do with
a tag
is
create
it
option/value pairs as described in the earlier section, "Options Used with Tags."
Here are some examples: creating a tag with no options $text->tagConf igure "special " # Creating a tag that will change the color $text->tagConfigure( "blue" -foreground => "blue"); # Creating a tag that will make underlined text $text->tagConfigure( "underline" -underline => 1) # Creating a tag that changes the color and spacing $text->tagConfigure( "bigblue" -foreground => "blue", -spacing2 => 6) #
(
)
,
,
,
You can change the settings for an already second time. Any changes you make to the screen that has that
created tag by using
tagConfigure a any text on the
tag immediately affect
tag:
Add backgro\jnd color to "blue" tag $text->tagConfigure( "blue" -background => "red"); # Change the spacing for "bigblue" $text->tagConfigure( "bigblue" -spacing2 => 12); #
,
,
As with widget configure methods, you can use tagConfigure to find out the current settings for a specific tag. list
of
To
get
all
the tag options
lists:
@listof lists = $text->tagConfigure( "blue" foreach $1 (©list) { print "@$l\n"; } # print it out )
and
their values in a
,
,
;
;
168
Chapter
Each
within the
list
You can
($option, If
list
contains
also limit the information
The Text Widget
two elements: the option name and you retrieve to a single option:
$value) = $text->tagConfigure( "blue"
you only want information on the value $value = $text->tagCget "bigblue"
,
the value.
-font)
tagCget:
for a particular option, use
-spacing2)
(
Adding a Tag
8:
,
to Existing Text
We've already seen an example of using the tagAdd method. It allows you to add a tag to portions of text in the text widget. The usage of tagAdd is as follows: $text->tagAdd( tagname' '
indexl
,
[
,
index2,
indexl,
index2,
...
]
)
You can add
a tag to a single index or a range of indexes. This means you can add a tag to the text widget to multiple places at the same time. Let's say you wanted to add the tag 'heading' to the 1st, 12th, and 30th lines because they are
the location of rest of the text.
some heading information that you want The tagAdd line would look like this:
$text->tagAdd
( '
heading ',
'1.0',
to look different than the
'1.0 lineend '12.0 lineend' '
'12.0'
,
'30.0'
,
'30.0 lineend')
Now, assuming the formatting of 'heading' makes the font bigger, those lines now show up differently than the defaults from the rest of the text in the widget.
You can add more
than one tag to a section of
both a 'heading' tag and a 'color' (such as -font), the
Once you
last setting for that
place a tag on a range of
and ending indices of rounding
it.
tag. If
text.
both tags
For example, you can have try to alter the
same option
option wins.
text,
any
text inserted
between the beginning
that text will automatically get the tag of the characters sur-
This happens whether you are using insert without any specific tags
or the user just types text into the text widget.
If
you specify
a tag with
insert,
it
overrides the surrounding tag.
Using Bind with Tags One
of the main reasons for tags
is
the ability to assign a binding to certain por-
tions of the text. After creating a tag with
callback will execute
when
a
tagConf igure, you can use bind so a a mouse click)
sequence of events happens (such as
on that tagged text. On our button widgets, we have a default binding of that invoked the callback associated with the -coinmand option. We can do the same thing with tagged text.
169
Text Tags
The
example
best
using text like a
is
web
new document
something happens: a
hyperlink.
presented to the user. The basic form of a tagBind $text->tagBind( tagname
callback
sequence,
[,
When you
loaded or another
is
]
on the
click
window
is
link,
created and
call is as follows:
)
The callback is similar to that specified for the -coitmand callback on a button. The sequence is a description of the event that triggers the script. The only sequences you can specify are those that are keyboard or mouse related. (See Chapter 14, Binding Events, for more details on available events.)
The following code shows a psuedo-link example. on it is show the end of the text widget:
does
All the link
when we
click
-width => 40) ->pack(- expand => 1, -fill => 'both') $t->tagConfigure( 'goto_end' -underline => 1, -foreground => 'red'); "" sub { shift->see( 'end' $t->tagBind( 'goto_end' } $t = $niw->Scrolled( "Text"
,
,
,
,
)
Setup Bindings to change cursor when over that line "" $t->tagBind( 'goto_end' sub { shift->configure( -cursor => 'hand2') " $t->tagBind goto_end' " sub { shift->configure (-cursor => 'xterm') $t->insert end' "END\n" "goto_end"
;
)
#
,
});
(
,
'
}
)
(
'
,
,
)
Insert a bunch of lines for ($i = 1; $i insert 'end' "$i\n");
#
{
(
,
}
tagBind
Inside the subs in the
We
calls,
we
use the shift
command
to invoke a
bind callback is the text widget. This is done implicitly for you. Whichever widget tagBind is invoked on is the widget that will be sent as the first argument to the callback. To use the text widget more than once in the callback, assign it to a local variable; for exammethod.
ple, If
itry
we
can do
this
because the
to the
$widget = shift.
created our text widget in the global scope of the program and placed a
erence to the widget
is
scope and available during the callback.
you want
to use the
same callback
$tl->tagBind( 'goto_end' $t2->tagBind( 'goto_end' s\ib goto_end { ray $text = shift; $text->see end' (
'
we
in the variable $t,
the callback via the $t variable. This
}
argument sent
first
)
;
,
,
with,
ref-
could also access the text widget
only possible because $t
is
in
in the global
you have two different text widgets that use shift to get the correct text widget:
If
"" ""
,
,
\&goto_end \&goto_end
); );
(
;
(
)
170
Chapter
Using the same callback for both text widgets helps save space
To determine what the bindings tag name argument:
are for a tagname, just use
8:
The Text Widget
your program.
in
tagBind with only
the
©bindings = $text->tagBind( "tagname")
The
be empty
will
list
if
there are
no bindings
currently for that tag.
Deleting All Instances of a Tag Once
a tag
you can use the tagDelete method
created,
is
$text->tagDelete tagname
The
[
,
tags are deleted completely
reverts
back
tagname
...
when you
]
use tagDelete. This means the text
and any bindings or other
to the default configuration values,
mation associated with those tags
To remove
infor-
also deleted.
is
The tagDelete method can be used if you are cally within the program and you need to delete tion is no longer valid.
Removing a Tag from
to delete the tag:
creating temporary tags dynami-
the tags later
when
the informa-
the Text
the tag from a specific block of text,
you can use the tagRemove
method: $text->tagRemove tagname, indexl {
Specify the
name
remove the
tag.
[,
index2,
indexl,
index2 ...])
of the tag and an index or range of indexes from which to
This leaves the tag
intact;
it
merely removes
it
from the specific
text indicated with the indices.
Raising When
and Lowering Tags same
there are several tags applied to the
overrides the previous ones, and
its
text,
the
last
tag
added
to the text
configuration options are given priority.
You
can change the priority of the tags by using tagLower and tagRaise: $text->tagLower{ tagname $ text -> tagRaise tagname
These methods take argument, the
first
text in the text
specified, the
Think of
it
a tag
tag
is
[, [
,
belowtag ]) ahovetag ]
name
as the
)
first
argument.
given the highest or lowest
If
there
priority.
widget no matter where the tags are applied.
first
tag
is
specifically placed before or after the
as reordering a stack of tags
the top has the most say, and
if it
tag
If
a
second
second tag
is
tag.
applied to the same text). The tag on -foreground option of 'red', then all
(all
has a
no second
is
This affects the entire
171
Inserting Text
the text with that tag will be red, regardless of
ground
to. If
we
use tagRaise to
move
what the other text tags set -fore-foreground of 'blue' to
a tag with
the top, the tagged text will change to blue.
Getting Tag You can whole
Names
find out
widget by using the tagNames method:
text
$text->tagNaines If
the different tags that apply to a specific index or to the
all
(
index
[
])
you specify an index, the
index.
If
returned contains tags that only apply to that
list
a specific index isn't given, then the
list
returned contain
all
the tags that
apply to the entire text widget whether or not that tag has been applied to text within the widget.
Determining Where a Tag Applies If
you know the name of the
tag,
you can
widget by using the range methods. The that contains pairs of
find out
first
where
it
applies in the text
method, tagRanges, returns a
list
index values for the whole text widget:
©list = $text->tagRanges "tagname" # returns beginl endl begin2 end2 (
,
(
If
no
text in the text
You can
,
...
,
widget has that
tag, the
one
get the pairs of index values
)
returned at a
list
will
be empty.
time by using the tagNextrange
method: ($start,
The search index2
is
$end)
for
=
$text->tagNextrange( "tagname"
"tagname"
will
begin
,
indexl
[
,
index2
])
indexl and go no farther than index2.
at
If
not specified, then the search will continue until the end of the text wid-
get or until
it
finds the tagname,
whichever comes
first.
Inserting Text Now
that
we've gone over
and marks,
text indexes
we
can
talk in
more
detail
about the methods for manipulating the widget's contents.
As we've seen from the many examples into the text widget. will
be
(which
inserted. is
first
argument
The second argument
optional)
inserted text.
The is
a single tag
The usage
in this chapter, is is
name
we
use insert to put text
an index and indicates where the
The next argument names to assign to the
the string to insert.
or a
list
of tag
is:
$text->insert (index, string,
[
taglist, string,
text
taglist ...]
)
;
;
172
So
Chapter
far
we've only seen single tags used with insert.
than one
tag,
put the tag
names
If
8:
you want
into square brackets, creating a
The Text Widget
to specify
more
list:
$t->insert 'end' "This is a very tagged line", tagl tag2 tag3 (
,
[
To use tag
'
'
,
'
,
'
'
]
'
)
you can supply additional
different sets of tags,
text lines
and additional
lists:
$t->insert 'end' (
When you ferent tags,
,
"This is the heading", ['heading', "Second line", ['bold', 'blue']);
use the insert
make
command
still
be assigned to
more than one
there will be
You can
that text.
set of text
with
dif-
in pairs: text, tags, text, tags, etc. If the
tagConf igure),
tag used isn't defined (with
the tag will
to insert
come
sure they always
'underline'],
no
on the text but later if you wish.
effect
create the tag
Deleting Text To remove
text
from the
$text->delete (indexl
The
first
index argument
then the
first
you can use the delete method:
text widget, [
index2
,
]
)
required; the second
is
index must be
less
is
optional.
If
both are specified,
than or equal to the second. All the characters
from indexl to (but not including) index2 are removed from the
you want
to
delete
delete("i.O",
text widget. If
everything from the text widget, you can use
$text->
'end').
Retrieving Text The get function index2.
If
is
index2
The usage of get
one
isn't is
you'll
use a
lot. It
returns the text located from indexl to
specified, just the character located at indexl
$t = $ text ->get (indexl
,
[
index2
]
)
string will
returned.
;
As with any index ranges, indexl must be
empty
is
as follows:
less
than or equal to index2 or an
be returned.
Translating Index Values When you work
with indexes,
it
useful to
is
be able
to convert a complicated
index form into a simpler one. The index method returns an index with the form line.
char.
$newvalue = $text->index indexl (
The indexl value can be any
)
;
valid index expression.
Getting Line Information
1
73
Comparing Index Values You can compare two index $text->coiTpare (indexl,
You
pass the
first
values by using the coitpare method. index2)
op,
;
index, the test operation to perform, and the second index.
values for op are: "search( -backwards,
$location
"
$text->search (-nocase,
"find me",
'end');
"SWITCHES",
"1.0");
Marks
1
75
Scrolling The
widget can be scrolled both horizontally and
text
so
vertically,
it
implements
both xview and yview methods. These two methods are described in Chapter
6,
Scrollbars.
Marks There are several ways to refer to different positions throughout the
text widget.
Index values refer to a character. Tags are named references to a specific charac-
The term mark is used to refer to the spaces in between characmark has a name. For example, the "insert" mark refers to the position of the insert cursor. However, tags refer to the actual characters, and if those characters are deleted, the tag is no longer associated with those characters. The mark stays in place whether the characters surrounding it are deleted or other characters are added. Marks can only refer to one location within the text widget ter
or characters.
Similar to tags, a
ters.
at a time.
Once affect
it
is
created,
on which
you can use
a
mark
default), the text will
be inserted
to the left of the
to the character to the right of the mark.
inserted to the
an index. The gravity of the mark
as
side the text will be inserted.
left
of the
If
mark and the mark
If
the gravity
mark because is left
the gravity
mark
the
'
'
,
will
'right' (the
is
is
glued
the text will be
will refer to the left of the last charac-
ter inserted.
There are two special marks
that
are
set
automatically by the
"insert" and "current". The "insert" mark
is
wherever the
The "current" mark is the position closest to the mouse and mouse moves (as long as a mouse button is pressed). Both marks internally and cannot be deleted.
You
text
widget:
insert cursor
is.
adjusts as the
are maintained
mark called "anchor" that shows up in the getNames method you click in the text widget. It always has the same index value as the "insert" mark, but "anchor" might not always exist. will also see a
after
Setting To
and
Getting the Gravity
set the gravity of the
mark, you can use inarkGravity:
$text->markGravitY (iTiarAuame
The possible values
new marks mark
is
is
,
If
direction
])
"right" and "left". The default gravity for you don't specify a gravity, the current gravity for that
for direction are
"right".
returned.
[
;
)
176
Chapter
8:
The Text Widget
Determining Mark Names To
get a
of
list
the marks in the text widget,
all
©names = $text->markNames
you can use markNames:
(
There are no arguments to the itiarkNaines function, and
example of
how
marks within the
to report the
it
returns a
list.
Here
is
an
text widget:
$f->Button(-text => "Report", -coimnand => sub { my @m = $t->markNames foreach (@m) { print "MARK: $_ at ", $t->index($_) }} ->pack(-side => 'left'); ( )
;
,
"\n";
)
The
results after clicking in the
MARK MARK MARK
to set the insertion cursor are as follows:
insert at 2.15 anchor at 2.15 current at 3 .
Creating You can
window
and Deleting Marks
create a
mark and
set
$text->markSet (markname
a specific index
at
placed. For instance,
$ text - >markSet
(
by using the markSet method.
index)
markname you want
In addition to the
mark should be end of line 3:
,
it
you always want
"3.0 lineend"
"end of line3",
$text->insert "end of line3",
if
to create, specify the to
index where the
be able
to insert at the
)
"text to insert");
(
The markUnset method removes the mark from the text widget and deletes the mark completely. It will no longer show up in the markNames list after it has been unset, and it can't be used as an index value either. You can specify more than one markname in markUnset: $text->markUnset (markname
[,
markname, markname
...
])
Embedding Widgets One
of the best things
you can do with
button or entry widgets) inside
can create Before
a scrolled set of
we go
embedded
over
widgets,
all
let's
it.
a text widget
One advantage
widgets on a line-by-line
is
of
put other widgets (such as
embedding widgets
the different functions that are available to
look
at a
data entry in a program, which
quick example.
means we need
is
you
basis.
We
often
want
a lot of label
to
work with do a lot of
and entry widgets.
Embedding Widgets
177
Sometimes there are so many of them
that
hard to
it's
them
fit
all
on the screen
without making a mess of the window. By using a scrolled text widget and putting the label
and entry widgets
inside
it,
we
can create a
lot
more widgets within
a smaller space. Here's the code:
use Tk; MainWindow->new; $mw->title "Data Entry" $f = $iTiw->Fraine->pack; -side => 'bottom'); $f->Button(-text => "Exit", -command => sub { exit; } ->pack(-side => 'left'); $f->Button(-text => "Save", -command => sub { # do something with %info; ->pack(-side => 'bottom'); } $t = $mw->Scrolled("Text", -width => 40, -wrap => 'none' ->pack(- expand => 1, -fill => 'both'); $inw =
(
)
(
)
)
)
foreach (qw/Name Address City State Zip Phone Occupation Coirpany Business_Address Business_Phone/) { $w = $t->Label (-text => "$_:", -relief => 'groove', -width => 20); $t->windowCreate( 'end' -window => $w) $w = $t->Entry( -width => 20, -textvariable => \$info{$_}); $t->windowCreate( 'end' -window -> $w) $t->insert 'end' "\n"); ,
,
(
,
}
$t->configure( -state => 'disabled');
disallows user typing
#
MainLoop Figure 8-6 shows the
Win32 version of
window.
this
^^-Inixl
i *Data Entry
"'""
"^"-"
*
Name: Address: City:
State: Zip:
Phone: -
Occupation:
Company: Business_Address:
.__..™._™JExit
j
Save
Figure 8-6, Text widget containing other widgets
1
.
178
We
Chapter
disable the text widget before running
8:
Mainloop because we
The Text Widget
want the
don't
user to be able to type text directly into the text widget. This only disables the ability to enter or delete text
—the
internal widgets
still
function normally.
We
also
turned off the -wrap option so the label and entry widgets don't accidentally drop
down
You could want
when
to the next line
window
the
is
resized.
put a text widget inside another text widget, but you probably wouldn't
to.
The window Method to insert an it
embedded
we
use the windowCreate method The widget should have already been created, and widget. The general syntax is:
As you can see from the preceding example, widget.
should be a child of the text
$widget = $text->Widget $text->windowCreate (index, -window => $widget, [option => value (
In our
;
the
embedded
insert the
-window option with
)
we used
example above,
widget index to
...
'end' index. widgets.
the reference to the
Here are the available options
for the
]
)
;
You can use any
valid text
The only option we used was
a
new $widget.
window method:
-align => where 'baseline',
Possible values of
mines where the widget
The
itself.
default
is
'
is
'bottom',
'center', or
placed within the line
center
if it is
'top'.
not as
tall
deter-
It
as the line
'
-padx => amount and -pady => amount
Add space around
the widget in the x and y directions respectively (-padx =>
10).
-stretch =>
|
1
Takes a boolean value line
(1
or
0).
A
true value will stretch the widgets to
fill
the
from top to bottom.
-window => $widget Takes a reference to another widget. There are several different forms of the window method. The ate" form, creates the
know what
widget within the
types of widgets are
@types = $text->windov*Iames
The
results .
look like
text widget.
embedded ( )
one, the "Cre-
The "Names" form
lets
in the text widget:
;
this:
text radiobutton .text. label .text. button .text. entry .
first
.
text checkbutton .
you
Internal Debug Flag
1
Use the windowCget function
when
the
window was
$value
=
$text->windowCget (index, option);
you need
to
know
occupying (each widget occupies one character it
more
takes
were used
to get information about the options that
created in the text widget:
In order to use windovtfCget
like
79
the index the widget
in the text widget,
is
even
currently if it
looks
space).
The "Configure" form of window will allow you change the options associated with the widget at index or retrieve the value of the configuration option:
$text->windowConf igure index (
Remember
[,
option => value
J
)
method are -align, -padx, windowConf igure (...) behaves just like a regular widget's configure method. To make changes on the $widget directly, use $widget->conf igure (...). -pady,
that the only options
-stretch,
and
you can use with
-window.
Other than
this
this,
Internal Debug Flag The debug function takes an optional boolean argument: $text->debug( If
[
boolean
the value passed in
is
]
true,
)
then internal consistency checks will be turned on in
the B-tree code associated with text widgets.
Without any argument, the debug method turned on, and "off"
debug
not. All text
if
If false,
the checks will be
will return the
value "on"
if it
left off.
has been
widgets in the application share the same
flag.
Scanning The scanMark and scanDragto methods are used internally within the text widget. A call to scanMark simply records the x, y passed in for use later with scanDragto. It returns an empty string: $text->scanMark(x, y)
scanDragto
also takes x,
;
y coordinates, which are compared to the scanMark x,y the text widget is adjusted by 10 times the differ-
The view within ence between the coordinates. coordinates.
$text->scanDragto(x, y)
Chapter
180
Fun Things
8:
The Text Widget
to Try
Create a scrollable text widget. Insert a button widget that has text describing the foreground color of the text widget cycle
between several
color
and
text.
and when you
click the button,
different colors, updating the button's
have
it
-foreground
For a practical application, have several buttons, each associ-
ated with a different color in your application.
When
the user clicks the
button, you can change the color to a different value (possibly using the ColorEdit composite widget).
Create a text widget that will display a read-only the
window, one
increase
it.,
file.
Create two buttons
on
to decrease the font within the text widget, the other to
The Canvas Widget
cwy«.iw^«,ftoa««»
..
.j.qj
The canvas widget
is
mainly used for drawing items such as
arcs, lines, rectangles, circles,
Red Dual
text
a
and other widgets
painter's
canvas:
something on
|l«e Oiial
blank
is
canvas
some examples
of
is
you decide
Create a drawing program.
•
Display a graph based on input from the user.
•
Create a customized
any
scrollable in
how you
•
Each item you create
until
draw
to
But unlike a painter's canvas, which
it.
ited in size, this
are
It
and so on. You can also place Think of it as
inside a canvas widget.
lim-
is
direction.
Here
can use a canvas widget:
slider.
canvas widget can have bindings attached to
in a
it
to allow
for easy interaction with the user.
Creating a Canvas I
recommend
you know window:
that
you always use the Scrolled method
for sure that
your canvas
$canvas = $iTiw->Canvas # or.
(
[
first
going to be a fixed size that
is
option => values,
]
)
->pack
will
fit
in the
( )
.
$canvas = $inw->Scrolled( 'Canvas'
The
to create a canvas unless
line creates just a
(See Chapter
6, Scrollbars,
Scrolled method.) To
,
[
option => values.
;
)
->pack
( )
canvas and the second creates a canvas with scrollbars. for
more information on what
else
you can do with the
create a canvas widget, use the desired parent widget to
181
182
Chapter 9: The Canvas Widget
invoke the Canvas method and pass any
initial
Canvas method
newly created canvas widget.
Before are a
we
returns a reference to the
get into the options
and methods
options in with their values.
The
available with a canvas widget, here
few miscellaneous things you should know about using
a canvas widget.
Coordinate System A
canvas widget uses a coordinate system to locate items inside of
dinate system
Figure 9-1
isn't
shows
a normal one.
It's
more
like
it,
but the coor-
an upside-down coordinate system.
a diagram that demonstrates the coordinate system a canvas wid-
get uses.
bbox( "all"
)
]
like:
;
;
;
184
;
Chapter 9: The Canvas Widget
Calling this after you add or remove items to the canvas resets the scroll region to where it needs to be. Of course, if you are adding many different items all at once, you should wait until after you have added them all and then update the scroll region.
Using Bind with a Canvas When you
try to
bind method with
use the
a canvas widget, you'll run into
unexpected problems. You'll either get an error and your script will
around
bind won't seem
run but your
need
you'll
this,
(because the canvas has
its
You can If
also use
own bind method
In order to get
effect.
that
you have
just
bind
to avoid using):
;
,
sub
{
print "bind!\n";
}
)
SUPER: :bind instead of Tk: :bind. Either way
you used the Scrolled method
difficulty; you'll
have any
some
won't run, or your
use the explicit Tk: :bind instead of
to
$canvas - $rnw->Canvas $canvas->Tk: :bind("" ( )
to
script
your canvas,
to create
will work.*
you'll
have an added
have to use the Siibwidget method to get to the canvas widget:
$canvas = $inw->Scrolled( "Canvas" $real_canvas = $canvas->Subwidget( "canvas" $real_canvas->Tk: :bind( "" sub { print "bind! \n" }); )
;
)
,
Other than
one small annoyance, bind works just as you would expect it fairly useful) example that will print out the coordi-
this
would. Here's a quick (and nate you clicked on:
$c = $inw->Scrolled( "Canvas") ->pack() $canvas = $c->Subwidget "canvas "
;
(
)
$canvas->Tk: :bind("" s\ib
print_xy
ray
($canv,
print
"
,
[
\&print_xy, Ev(
'x'
,
Ev( 'y'
]
)
$canv->canvasy($y)
,
)
)
{
$x,
(x,y)
$y)
=
",
= @_;
$canv->canvasx($x)
,
",
",
"\n";
}
This example prints out the coordinates (in canvas coordinates) the
left
mouse
when you
click
button.
Canvas Options The options within act as
*
it.
listed in this section affect the entire
Items
are circles, lines, rectangles, text,
you would expect them
For these
u.sing Tk8.0:
to (as explained in
You can use canvasBind
the rest of the chapter, but note that
you should
canvas widget and the items
or other widgets. These options
Chapter
instead of Tk: :bind.
u.se
canvasBind
3,
I'll
instead.
The Basic Button, for
refer to Tk::bind
throughout
Canvas Options
185
most options and
in
Chapter 6 for the scrollbar options): -background, -border-
width, -cursor, -height, -highlightbackground, -highlightcolor, -high-
lightthickness,
-takefocus,
-relief,
and
-xscrollcoinmand,
-width,
-yscrollcoinmand.
New When
Options selecting items in the canvas with the
mouse
mouse
cursor, the canvas widget
does
The mouse must be to the item before it "1.0", is considered inside the item. The default value for -closeenough is which is 1.0 pixels away. Any floating point number is a valid value (and will calculations to determine
-closeenough option
if
the
how
controls
cursor
inside or outside the item.
is
close the
always be in pixels) for -closeenough. I
discussed the
this chapter.
It
-scrollregion option takes a
The coordinates The coordinates
list
indicate a
that
bounding region
are in this order:
think of the coordinates as
if
[
"The Scrollable Region"
briefly in
and
reference,
earlier in
must contain four coordinates.
list
for the scrollable area in the canvas.
minx, miny, maxx, maxy
they were defining the
[
left,
]
.
You can
top, right,
also
bottom
]
edges of the scrollable region. Normally, the canvas widget limits the user to seeing only the area defined by the
-scrollregion
option.
using -confine =>
You can allow
The
0.
default for
the user to scroll
-confine
beyond
this area
by
is 1.
Additional Scrolling Options The -xscrollcoinmand and -yscrollcoinmand options both work as described in Chapter 6, but there are two additional options that affect how the canvas scrolls its contents: -xscrollincrement and -yscrollincrement. Each option takes a valid screen distance for a value. This distance scroll in the associated direction.
ment
=>
10,
each time you
For instance,
click
the unit the canvas will use to
is if
you specify -xscrollincre-
an arrow on the horizontal
contents of the canvas will shift so that the
left
scrollbar,
edge of the contents
multiple of 10. Essentially, the canvas will shift the contents
is
the
an even
10 pixels in the
arrow's direction. If
the value associated with
less, scrolling is
done
in
-xscrollincrement
normal increments.
or
-yscrollincrement
is
or
.
186
Chapter 9: The Canvas Widget
Options for Text Items The following options
are applied to the entire canvas widget, but they really only
canvas widget: -insertbackground, -insertbor-
affect the text items inside the
derwidth, -insertofftime, -insertontime, -insertwidth, -select±>ack:gro\ind, -selectborderwidth, and -selectforeground. These options work the
same
as they
and Entry
would for an entry widget or a text widget. See Chapter and Chapter 8, The Text Widget, for more details.
5,
Label
Widgets,
Canvas Widget Option These options
all
are used with the
-background => Sets the
List Canvas method:
color
background of the canvas
to color.
-bordeirwidth => amount
Changes the width of the edges of the canvas
-closeenough => float_amount Sets the amount of distance from
the item
to
amount
when
the cursor
is
considered
inside the item.
-confine => 1
|
Indicates that the canvas will limit
region
if
set to
1
.
Default
itself
to the area defined
by -scroll-
is 1
-cursor => cursomame Indicates that the cursor will change to
cursomame when
it
is
over the canvas.
-height => amount Sets the height of the canvas to
-highlightbackground =>
amount.
color
Sets the color the highlight rectangle should
be
when
the canvas does not
have the keyboard focus.
-highlightcolor =>
color
Sets the color the highlight rectangle should be
when
the keyboard focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle. Default
-insertbackground =>
is 2.
color
Sets the color of the area
behind the
-insertborderwidth => amount Sets the width of the borders on
text insert cursor.
the insert cursor.
the canvas does have
187
Canvas Options
-insertofftime => milliseconds Sets the amount of time the cursor disappears from blinking
when
the screen
is
it
off.
-insertontime => Sets the amount
milliseconds of time the cursor appears
on the screen when
it
is
blinking
on.
-insertwidth => amount Sets the
width of the
-relief => 'flat' Indicates the
way
-scrollregion =>
|
insert cursor.
'groove'
'raised'
|
|
the edges of the canvas are
Defines the area the user
is
bottom,
right,
top,
left,
[
allowed to
'sunken' 'solid' drawn. Default is flat
'ridge'
|
|
'
'
]
scroll.
-select-background => color Sets the color of the area
behind any selected
text.
-selectborderwidth => amount Sets the
width of the border of the selected area.
-selectforeground =>
color
Sets the color of the selected text.
-takefocus =>
|
1
|
xondef
Determines whether or not the canvas can get keyboard focus. Default
is
for
the application to decide.
-width => amount Sets the
width of the canvas to
amount
-xscrollcommand => callback
when the canvas is scrolled horizontally (autowhen the Scrolled method is used).
Determines the callback used
matically set to the correct callback
-xscroll increment => amount Sets the distance the canvas contents
scrollbar
is
move when
the arrow
on the horizontal
clicked.
-yscrollcoinmand => callback Determines the callback used
when
the canvas
is
scrolled vertically.
-yscroll increment => amount Sets the distance the canvas contents
scrollbar
is
clicked.
move when
the arrow
on the
vertical
188
Chapter 9: The Canvas Widget
Creating Items in a Canvas The whole point of having
a canvas
is
to put items in
it.
You can
create arcs, bit-
and widgets. Each has an associated createXXX method, where the type of item you want to create maps, images,
XXX.
replaces the
used to
lines, rectangles, ovals (circles),
polygons,
text,
create methods return a unique ID, which can be When you see a method that takes a tag or an ID as one returned from the create method.
All of the
refer to the item later.
an argument, the ID
is
the
The Arc Item When you
tional options that will
The
shortly.
you specify a bounding rectangle with two sets of x and drawn within the confines of the bounding box. Addichange how the arc is drawn in the canvas are explained
create an arc,
y coordinates. The arc basic
is
createArc statement
$id = $canvas->createArc
Any
(jcl,
is
as follows:
yl, x2, y2)
additional options used in the
;
createArc method
are specified after the
coordinates: $id = $canvas->createArc (xl, yl, x2, y2, option => value);
Each option
for the arc item
f igure canvas methods.
-extent => degrees The length of the arc The default -extent starting
point (see
can be used
The options
is
later
with the itemcget and itemcon-
are:
specified in degrees
(or length)
-start
is
by using the -extent option. The arc is drawn from the
90 degrees.
option) counterclockwise within the rectangle
defined by Cxi, yl) and (x2, y2). The degrees value should be between -360
and
360.
If
it
is
more or
less,
then the value used
is
the specified
number of
degrees modulo 360.
Here are some examples of the -extent option: This draws half of an oval $canvas->createArc(0,0,100,150, -extent => 180); # This will draw _ of an oval $canvas->createArc(0,0,100,150, -extent => 270); #
-fill => color
To
fill
the arc with the specified color.
By
default, there
is
no
fill
color for an
arc.
-outline => color drawn with a black outline. To change the default, use the The outline color is separate from the fill color, so to make completely solid object, make the color for -outline and -fill the
Normally the arc
-outline it
a
same.
is
option.
189
Creating Items in a Canvas
-outlinestipple => bitmap To use -outlinestipple, you must also use the -outline option. Normally, the outline of the arc is drawn solid. Use a bitmap with -outlinestipple to make the outline nonsolid; the specified bitmap pattern will be used to draw the outline of the arc. -start => degrees The value associated with the -start option determines where Perl/Tk starts drawing the arc. The default start position is at three o'clock (0 degrees). The degrees specified are added to this position, but in a counterclockwise direction. Use -start => 90 to make the arc start at the twelve o'clock position, use -start => 180 to
make
the arc start at the nine o'clock position,
and so
on.
-stipple => bitmap The -stipple option causes the only if the -fill option has been -style => "pieslice" The -style of the
"chord"
|
arc to
filled
with a bitmap pattern, but
"arc"
|
determines
arc
be
specified as well.
"pieslice", draws the arc and two
how
lines
the
arc
is
drawn. The default,
from the center of the oval ends of
The "chord" value draws the arc and a line connecting the two end points of the arc segment. The "arc" value draws just the arc portion with no other lines. The -fill and -stipple options are ignored if the arc segment.
"arc"
-tags =>
is
used.
taglist
When you
you use the -tags option to assign The value associated with -tags is an anonymous list of create an arc,
tag
names
to
it.
tag names; for
example: $canvas->createArc(0,
You
don't
need
to use
0, 10, 140,
-tags => ["arc",
an anonymous
list if
you
"tall"]);
are only specifying
one tag
name: $canvas->createArc
-width => amount The width of the
(0, 0, 10,
outline
is
140, -tags => "arc");
specified
by using -width. The
default
-width
is
1.
The Bitmap Item A
canvas widget can display a bitmap instead of text
You can
just as a
button or label can.
use createBitmap to insert a bitmap into your canvas widget:
$id = $canvas->createBitmap(x, y)
;
190
Chapter 9: The Canvas Widget
Of course, you must use the -bitmap option to specify which bitmap you won't see anything. So we really create a bitmap like this:
to display or
$id - $canvas->createBit:iTiap(x, y, -bitmap => bitmap);
Why the
they didn't
way
it is.
make
just
the bitmap the third argument,
The other captions
-anchor => "center"
|
"n"
"e"
|
|
I
don't
createBitimap
available for
"s"
|
"w"
"ne"
|
know.
That's just
are:
|
"nw"
|
"se"
"sw" I
The -anchor option determines how
the bitmap
is
placed on the canvas
rela-
coordinates indicated. The default for
-anchor is "center", which puts the center of the image at the x,y coordinates. Using a single cardinal direction (for example, "e") would place the center of that edge at the x,y tive to the x,y
coordinates.
-background => color The -background option specifies the color to use for all the (zero) bitmap pixels. If you don't specify a background color or use an empty string (""), the
be transparent.
pixels will
-bitmap => hitmapname You must use the -bitmap option
You can
to
tell
the canvas
which bitmap
use the built-in bitmaps such as 'info' or 'warning'
to display. just as
you
can with the button widget, or you can specify a filename. Remember, to specify a bitmap
file,
use an @ sign in front of the bitmap filename.
-foregroiond => color
The foreground color of definition,
color
all
-tags =>
background
color.
(By
bitmaps can only have two colors.) The -foreground option
will
the
1
a
bitmap
is
pixels with this color.
the opposite of the
The
default for
-foreground
is
black.
taglist
When you option. for
create a bitmap, you can assign tag names to it by using the -tags The value associated with -tags is an anonymous list of tag names;
example: $canvas->createBitmap(0, 0, -bitmap => 'info', -tags => ["info", "bitmap"]);
You
don't
need
to use the
you are only specifying one tag name:
list if
$canvas->createBitmap(0,
0,
-bitmap => 'info', -tags => "bitmap");
The Image Item If
we
can create a bitmap on a canvas,
as well.
We
it
makes sense
can do so with the createlmage method:
$id = $canvas->createlmage(x, y,
-image => image);
that
we
can create an image
191
Creating Items in a Canvas
Again, you have to specify an image to display or you won't see anything.
createlmage
other options available for
-anchor => "center"
"n"
|
"e"
|
The
are:
"s"
|
|
"w"
"ne"
|
|
"nw"
|
"se"
"sw" I
The -anchor option for an image works the same as it does for a bitmap. The -anchor option is how the image is positioned around the x,y coordinates. The default for -anchor is center '
-image => $iinage The -image option
'
which image to display. The image value is actually a reference to an image created with Photo or Bitmap methods. (See Chapter 3 for more information on how to specify an image file.) indicates
-tags => taglist Use the -tags option to assign tag names to an image. The value associated with -tags is an anonymous list of tag names; for example: -image => $ixngptr, -tags => ["image", "blue"]);
$canvas->createlitiage(0,0,
You
need
don't
to use the
list if
$canvas->createlinage(0,
you
are only specifying
one tag name:
-image => $iingptr, -tags => "image");
0,
The Line Item The createLine method can actually create one. The first two coordinate sets you supply
multiple connected lines, not just create the
first line,
and any addi-
tional coordinates will continue the line to that point:
$id = $canvas->createLine(0, $id = $ canvas - >createLine (
,
# creates one line 400,400); 400,400, -50, 240); # creates two lines
0, ,
you can specify any options and values you wish the options and values are as follows:
After the coordinates,
ure the
line(s);
-arrow => "none"
You can
"first"
place arrowheads
]
"last"
at either
|
"both"
end of the
line (or
both) by using the
you have more than one line in your createLine method, last point can be made into an arrow. If you want each have an arrowhead, then use multiple createLine statements.
-arrow
only the line to
|
to config-
option. first
If
and/or
distl dist2, distS -arrowshape => The -arrowshape option only applies if you use Figure 9-3 shows what the distance values mean. [
,
Specify the three distances
]
by using an anonymous
the
list
-arrow option
such as
$canvas->createLine(10, 10, 200, -40, -arrow => "both", -arrowshape => 20, 20, 20]); [
this:
as well.
192
Chapter 9: The Canvas Widget
dist2 1
1
distS-
/
^^ dist1
Figure 9-3- Definition of arrowhead
-capstyle => "butt"
"projecting" "roiond" Instead of arrowheads, you can make the ends of the |
|
line
have one of these
styles.
-fill => color The -fill option is misnamed because it isn't actually line is simply drawn with this color instead of black.
filling
anything.
The
"miter" -joinstyle => "bevel" "round" The -joinstyle option affects how multiple lines are joined together. The default is "miter". If there is only one line created, this option has no effect. |
|
-smooth => 1 If -smooth has a value of 1, then, using Bezier spline(s), the line(s) will be drawn as a curve. The first two lines make the first spline, the second and third line make up the second spline, and so on. To make a straight line, repeat the end points of the desired straight line (or use createLine again to make a separate line). I
-splinesteps => count When you use the -smooth option, the more -splinesteps you use, the smoother the curve. To find out how many steps create the desired effect, you'll
have
to
experiment with different values.
-stipple => bitmap To have the line drawn with a bitmap pattern (Is in the bitmap have color, Os are transparent), use the -stipple option. The bitmap can be a default bitmap name or a filename. The wider the line (see -width), the more the stipple design will show up.
Creating Items in a Canvas
-tags =>
193
taglist
When you
names to them by using The value associated with -tags is an anonymous list of
create a line (or lines), assign tag
-tags
option.
names;
for
need
don't
tag
example:
$canvas->createLine(0,
You
the
to use a
0,
list if
$canvas->createLine(0,
0,
-tags => ["line",
100,100,
you
100,
are only specifying 100,
"blue"]);
one tag name:
-tags => "line");
-width => amount You can make the line(s) thicker by using the -width option. Normally the line is drawn only 1 pixel wide. The amount can be any valid screen distance (e.g.,
centimeters, inches).
The Oval Item An
you draw it just right. To create a circle/oval, use the createOval method and specify two sets of points that indicate a rectangle (or square) in which to draw the circle/oval. Here is a simple example: oval can be a circle
if
$id = $canvas->createOval $id = $canvas->createOval
The options
for the oval will
-fill => color The oval will be the outline color.
-outline => color The outline is the outline
make
the outline
50,
# creates a circle 50); 100); # creates an oval
familiar,
so we'll
it
just
cover them
briefly:
with the specified color. This color
default, the oval
line
black, but
is
50,
(0, 0,
be
filled in
By
(0, 0,
is
not
is
different than
circle.
Normally the
filled.
drawn around the outside of the
can be changed by using the -outline option.
and the
fill
If
you
color the same, the oval appears solid.
-stipple => bitmap
To
fill
the oval with a bitmap pattern (1 values in bitmap are colored,
ues are transparent), use the -stipple option.
-stipple has no a
bitmap
-tags =>
in
effect,
-stipple
If
the
-fill option
takes a default bitmap
name
isn't
or a
file
val-
used,
with
it.
taglist
When you The value
create an oval, use the
associated with
-tags
is
-tags option to assign tag names to them. an anonymous list of tag names; for exam-
ple:
$canvas->createOval(0,0, 100,100, -tags => ["oval",
"blue"]);
194
Chapter 9: The Canvas Widget
You
don't
need
to use a
$canvas->createOval
list if
(
,
,
you
are only specifying
-tags => "oval");
100,
100,
one tag name:
-width => amount The -width option changes how wide default for -width is 1 pixel.
the outline of the oval
is
drawn. The
The Polygon Item A
polygon
is
merely a bunch of
lines
where the
first
point automatically to create an enclosed area.
point
is
connected to the
last
The createPolygon method
requires at least three x,y coordinate pairs. For instance, the following piece of
code
will create a three-sided
polygon:
$id = $canvas->createPolygon( 1000, 1000, 850,950, 30,40);
Additional x,y coordinate pairs can be specified as well; for example: $id = $canvas->createPolygon( 1000, 1000, 850,950, 30,40, 500,500);
The options you can specify with createPolygon are the same as those you use with createLine: -fill, -outline, -smooth, -splinesteps, -stipple, -tags, and -width. Just remember that createPolygon connects the first point to the last point to enclose the area.
The Rectangle Item As
if
being able to create a rectangle using createLine or createPolygon
weren't enough,
y coordinate
we
sets,
also
have the createRectangle method.
It
only takes two x
which are the opposite corners of the rectangular
area:
$id = $canvas->createRectangle(10, 10, 50, 150);
we have seen the options available for createRectangle with the other create methods: -fill, -outline, -stipple, -tags, and -width. Although
Again,
I've
covered these options already, here are a few examples: A blue rectangle with black outline: $canvas->createRectangle(10,10, 50, 150, -fill => 'blue'); # A blue rectangle with a thicker outline: $canvas->createRectangle(10,10, 50, 150, -fill => 'blue', -width => 10); #
The Text Item Finally,
an item type that doesn't have
lines in
widget by using the createText method.
It
it!
You can add
text to a
requires an x,y coordinate pair,
canvas
which
determines where you place the text in the canvas, and the text to be displayed: $id = $canvas->createText
(0, 0,
-text => "origin");
Creating Items in a Canvas
195
you wouldn't see any text on the Because there is no point in that, we will assume that you will always -text with a text value to display. The other options available for text
The -text option screen.
specify
actually optional, but then
is
items are as follows:
-anchor => "center"
"n"
|
|
"e"
"s"
|
"w"
|
"ne"
|
|
"nw"
"se"
|
"sw" I
The -anchor option determines where the text is placed in relation coordinate. The default is centered: The text will be centered over no matter how large the piece of text is.
to the x,y that point
-fill => color The text is normally drawn in black; you can change this by using the -fill option. The name of this option doesn't make much sense when you think about it in terms of text (normally our widgets use -foreground to change the color of the text). For example, -fill => 'blue' will draw blue text.
-font => fontname
You can change
-justify => "left" If
to
by using the -font option.
the font for the displayed text
"center" more than one line, the -justify option specified. The default justification is to the left. |
"right"
|
the displayed text has
be
justified as
cause
will
it
-stipple => bitmap This option
name
(or
is
file)
a bit strange, but here
bitmap pattern. Most of the time, use
it
is
anyway.
If
you specify
a bitmap
with the -stipple option, the text will be drawn by using the this will
make
the text unreadable, so don't
unless you're using a large font.
it
-tags => taglist The taglist assigned to
-text =>
is
a single tag
name
or an
anonymous
list
of tag
names
to
be
this item.
string
This option
is
not optional. The specified string
is
displayed in the canvas wid-
get at the x,y coordinate.
-width => amount another misnamed option because
This
is
each
text character.
the text line.
is
The
It
determines the
it
does not change the width of
maximum
length of each line of
text. If
longer than this length, the line will automatically wrap to a second
default value for
amount
characters. Lines are always
broken
is 0,
at
which
will only
break lines
at
spaces so words won't be cut in
newline half.
"
;
196
Chapter 9: The Canvas Widget
Text item indexes
Methods
that affect text items will
for the regular text
canvas text item are only one line (even
sometimes ask
for
widget were covered in Chapter similar.
if it
The only
difference
has "\n" characters in
it).
is
an index value. Text indexes 8,
and the index values
that
each item
is
for a
considered
Index values are as follows:
n
A number
value: for example,
or 12.
is
the
character, 1
first
is
the second,
and so on. "end"
The character directly after the to add to the end of the string. "
insert The character
last
one. Often used with the
insert method
directly before the insertion cursor.
"sel. first"
The
first
character of the selected text. Only valid
if
there
is
a selection.
"sel. last"
The
last
character of the selected text.
Only
valid
if
there
is
a selection.
"©a:, J"
The character
closest to the point x,y of the canvas (not screen coordinates).
Deleting characters
To delete characters from within a text item, use the debars method: $canvas-> debars tag/id, first [, last ]) Specify a tag or ID to match the text item(s) and .
(
the index at which to ters to the
end of the
start deleting. If
string will
the
end index
isn't
specified,
all
the charac-
be deleted (including any "\n" characters).
Positioning the cursor
You can
xcvocsoic {tag/id
index).
,
fied item has the current
sor
if it
by using ieursor: $eanvas-> only show up immediately if the speci-
specifically place the blinking text cursor
doesn't,
it
just
The cursor
will
keyboard focus. You can
won't display
until the
still
set the position of the cur-
item does get the keyboard focus.
Index information
You can
find out an index
Don't get confused
based on another index by using the index method.
yet; here's
an example:
$index = $canvas->index("textitem"
,
"sel. first"
)
Creating Items in a Canvas
197
This will return the numerical index associated with the the text item. it's
a tag
Adding
If
will
named "textitem"), then
the
first
selected character in
match the tag or ID indicated first
one found
will
(in this case
be used.
text
To add more id,
more than one item
index,
use the insert method: $canvas->insert tag/
text to a text item,
string)
.
The
first
(
argument
is
the tag or ID,
which can match multiple
items. The second argument is the index before which to insert the new and the last argument is the actual string to insert into the text item.
string,
Selecting text
There are several methods you can use to programmatically select portions of the
To clear the selection (any selection; there are no tags or IDs sent with this command), use $canvas->selectClear To select a portion of text, use selectFrom and selectTo. The following two lines of code select the text from beginning to end for the first item that matches the tag "text tag": text.
( )
$canvas->selectFrom( "texttag" 0) $canvas->selectTo "texttag" "end"
.
,
(
,
You can add
to the selection
just ("adjust"
,
tag/id,
has the selection in
it
)
by using selectAdjust: $canvas->selectAd-
index).
You can
get the ID of the item that currently
by using $id = $canvas->selectltem()
The Widget Item You can gets, or
put any type of widget inside a canvas
at eWindow method. Before
calling
—buttons, checkbuttons, wid—by using the Gretext
you are a little crazy) createWindow, you must
even another canvas widget
(if
create the widget to
put into the canvas. Here's an example: $bttn = $canvas->Button(-text => "Button", -command => sub { print "Button in canvasXn"; $id = $canvas->createWindow(0, 0, -window => $bttn)
There are a few things you should note about
this
example (which
}
is fairly
)
typical
except the subroutine associated with the button doesn't do anything useful): •
The button
is
a child of the canvas widget.
The button could be
canvas
is
also a child of the
be a child of a •
a child of an
window
ancestor of the canvas (the button could be a child of the main
if
the
main window). However, the button should not
different toplevel
widget that has nothing to with the canvas.
The createWindow method doesn't actually create the widget; the canvas. The button is placed at the specified coordinates vas and has not been placed on the screen with pack grid ( )
,
just
it
puts
it
in
inside the can( )
,
or
place
( )
;
Chapter 9: The Canvas Widget
198
•
The widget must be created before you
•
You can
When you figure (e.g.,
createWindow.
and the callback associated with
it
will
be invoked,
with any other button.
just as •
click the button
call
it.
you can use any of
create the widget,
You can
that widget's options to con-
continue to configure the widget by using the reference to
it
$bttn).
The following options which you can use when you call createWindow than widget options: like options you use with pack
are
more
( )
-anchor => "center"
|
"n"
"e"
|
"s"
|
|
"w"
|
"ne"
|
"nw"
|
"se"
"sw" I
The widget will be placed at the x,y coordinates according to the -anchor value. The defauk is "center", which means that the widget will have its center point placed on x,y. -height => amount The widget will be given this height. If you don't use -height, the widget will have the height it was created with (usually the natural size of the widget).
-tags => taglist The taglist associates a tag with the widget. You can specify string, or an anonymous list of tag names.
-width => amount The widget will be given widget
will
this
have the width
it
width.
If
either a single tag
you don't use the -width
was created with
option, the
(the natural size of the widget).
-window => $widget This
is
you don't $widget is The
a nonoptional option. If
widget put in the canvas.
specify -window, there will be a reference to a widget item.
no
You
can create the widget beforehand or inline as follows: $canvas->createWindow(0, 0, -window => $canvas->Button(-text => "Button", -command => sub { print " Button \ " } !
It
makes sense
fancy with
to create the widget inline
if
;
)
)
you don't need
to
do anything
it.
Configuring the Canvas Widget As
usual, to configure or get information about the canvas widget,
you can use the
configure and cget methods, explained in detail in Appendix A, Configuring Widgets with configure and cget. Remember, configure and cget operate on the entire canvas
widget (possibly affecting the items within
it).
199
Tags
Conflguring Items in the Canvas Widget To change
the configuration options of any of the items within the canvas,
know
only need to
the tag
name
or the ID for that item.
You can
you
then use the
itemcget and itemconfigure methods. They behave just like the cget and configure methods, except as a first argument, they take the tag or ID of the item(s). I use the term "item(s)" because a tag can refer to more than one item. Here are some examples: $color = $canvas->itemcget "circle" -fill) $canvas->itemconfigure($id_number, -fill => "yellow", -outline => (
,
Make
sure the options
Each item type has a
list
5)
you use with itemconfigure and itemcget
are valid.
of valid options; they are listed earlier in this chapter with
each create method.
When you
-tags option, the itemconfigure method will replace any curThe taglist associated with -tags can also be empty, essentially remove all tags.
set the
rently set tags for the item.
which
will
Tags Each item can also have a tag (or more than one seen tags used before in the a tag.
A
method
tag can
be assigned
text widget,
when
where
the item
to assign a tag after the item has
is
been
tag) associated with
created, or
We
have
you can use the addtag
created.
There are two special tags
that are automatically assigned
"current" and "all"
The "all"
tag.
it.
sections of text could be assigned
tag refers to
all
and maintained: the
the items in the canvas.
The " current " tag refers to the topmost item that the mouse cursor is over. If the mouse cursor is outside of the canvas widget or not over an item, then the " current" tag does not exist.
You can use
tags to
you want
all circles
from time
to time,
make changes to
to
many
have the same
then give
all
different items at once. For instance,
if
you want to be able to change it a "circle" tag when you create them. change the configuration options of the
color, but
circles
Using the itemconfigure method to items with the "circle" tag.
The following
are
some sample syntax
lines for creating tags.
$canvas->addtag( "newtag" tag/id) "above" The "newtag" tag is added to the item that is above the tag/ID item. If there is more than one match for tag/ID, the last item found will be used so the "newtag" is directly above the tag/ID item in the display list. The display list ,
,
;
;;
;
200
Chapter 9: The Canvas Widget
created as you add items raise and lower methods.
to the canvas
is
$ canvas - >addt ag
(
"
newt ag "
"
,
al 1 "
and can be manipulated with the
)
The keyword "all" is a special tag canvas. Items added to the canvas "newtag" in their taglist.
that includes every item currently in the after the call to addtag will
not contain
$canvas->addtag("newtag" "below", tag/id); The "newtag" tag is added to the item that is directly below the tag/ID item. If more than one item matches the below tag/ID search, the lowest item in the ,
list
will
be used.
$canvas->addtag "newtag"
"closest"
(
Use the "closest" tag canvas coordinates).
If
,
x,
,
y)
;
to select the item closest to the x,y coordinates (in
more than one item matches,
the last
one found
is
used.
There are two more possible arguments for specify a to
number
that indicates
be considered. For instance,
how if
You can look
,
this
form of addtag. You can
out from the x,y coordinates items are
you want an item
be considered "closest", make the $canvas->addtag( "newtag"
far
that
is
within 10 pixels to
call as follows:
"closest",
50,
100,
10);
also specify a starting tag/ID to start a search.
The
call
would then
like this:
$canvas->addtag( "newtag"
By using
this
,
"closest", x, y,
form, you can loop through
all
10,
$tag_or_id)
the closest items.
$canvas->addtag "newtag" "enclosed", xl yl, x2, y2) You can assign the same tag to several items within the area bounded by ixl,yT) to (,x2,y2) by using the "enclosed" form of addtag. Items will only be given "newtag" if they are completely within the area. The coordinates must make sense when you specify them: xl < x2 and yl < y2. (
,
,
"overlapping", xl, yl, x2, y2) $canvas->addtag "newtag" To assign tags to any item that has any part inside a bounded region, use "overlapping" instead of "enclosed". Even if the item has only one pixel (
inside this area,
same
as for
,
it
will
;
count. All other rules for the bounding area are the
still
"enclosed".
$canvas->addtag "newtag" (
Assigns "newtag" to
all
,
"withtag"
,
tag/id)
;
the items with the tag or ID specified.
201
Tags
Binding Items Using Tags Each item will
in a
canvas can have an event sequence bound to
be invoked
when
that event
sequence happens. This
is
it
so that a callback
similar to
adding an
event sequence binding for widgets except item tags or item IDs are used.
(Remember,
if
you want
add a normal binding
to
must use Tk: :bind (or canvasBind
The general form of bind $canvas->Tk:
The sequence would be inition
[
,
similar to
are available for
the
command
is
all
]
)
You
keep can't
is
is
over
def-
Binding Events.
available in Chapter 14,
in mind that only mouse and keyboard do any of the weird esoteric bindings that
widgets.
an example that changes the color of any items tagged with "blue"
mouse
you
;
"" or "". A complete
create item bindings,
bindings are valid for items.
Here
sequence,
and explanation of event sequences
When you
itself,
as follows:
is
:bind(fc?g/iirf
widget
to the canvas
for TkS.O users) instead of just bind.)
when
it:
When the mouse is over the item, color it blue $c->Tk: :bind( "blue" "" sub { $c->itemconfigure("blue" -fill => "blue"); # When the mouse is not over, color it black. " $c->Tk bind "blue " " sub { $c->itemconfigure( "blue" -fill => "black"); #
,
,
}
)
(
:
:
,
,
});
Finding Tags find command to determine which items have a certain tag. The find are the same as those of addtag (except for the newtag argument). Here are the basic formats (see "Tags" earlier in this chapter for more details on what they mean and how they work):
You can use possible
the
ways
to call
$canvas->f ind( $canvas->f ind( $canvas->find( $canvas->find( $canvas->find( $canvas->find( $canvas->find(
"above" tag/ id) "all" "below" tag/ id) "closest" x, y [ , additional_area "enclosed" xl, yl, x2, y2) "overlapping", xl, yl, x2, y2) "withtag" tag/ id) ,
)
,
,
]
[
,
tag/id ]);
,
,
;
Getting Tags from a Specific Item To
get a
list
of
all
the tags associated with an item, use:
©list = $canvas->gettags tag/ id) If
the tag/ID matches
;
more than one item, then the first item found empty string is returned.
tag/ID doesn't match anything, an
is
used.
If
the
(
;
;
202
Chapter 9: The Canvas Widget
Retrieving when we
Bounding Box Coordinates
talked about the scrolling region of a canvas,
bbox method. The bbox method area in which
returns a
list
we saw
an example of the
with four elements that define the
The example used the special "all" tag, which refers to every item in the canvas. This was how we used it to define our scrolling region. You can specify more than one tag/ID to search for as follows: ($1,
$r,
Assuming
all
$t,
that
the specified tags exist.
$b)
= $canvas->bbox("blue"
,
"red");
you have been assigning the tags "blue" and "red" to appropricode would return the region in the canvas that encloses all
ately color items, this
blue and red items.
Translating Coordinates When you
up a callback and use the Ev( 'x' and/or Ev( 'y' arguments to find out where the user clicked, you must translate that information into canvas coordinates (Ev is explained in Chapter 14). To do this, use the canvasx and canvasy methods: set
)
$x = $canvas->canvasx (screenx $y = $canvas->canvasy (screeny
[,
[,
)
gridspacing ]) gridspacing ]);
Each method takes an optional gridspacing argument; then the canvas coordinate value will be rounded to the nearest value to
fit
the grid.
Moving Items Around Once an item has been created on the canvas, you can move it by using one of two methods: move or coords. The move method takes a tag or ID to indicate which items to move and the amounts to add to the x and y coordinates: $ canvas ->move
(
tag/id, xdistance, ydistance)
For instance, the following code will
move
;
items with the "blue" tag 100 pixels in
the x direction and 100 pixels in the y direction: $ canvas ->move
To move an
(
"blue"
,
100
,
100
)
item in the negative direction, simply specify a negative value for the
xdistance and/or ydistance. The other method, coords, allows you to explicitly specify a
new
x and y location for the
first
or ID: $canvas->coords tag/id, newx, newy)
;
item found that
is
identified
by the tag
203
Deleting Items
If
more than one
the item requires
you simply continue
set of x,y coordinates,
to
specify them:
$canvas->coords
You can
newxl,
(to^2coords
(tog/zlav!ex (tag/id,
move
The display
the ones created earlier
^canva.s->Ta.i.sB
The
the items in the canvas for a specific tag or
all
list.
all
the
If
first
tag
you want to which the first item or ID matches more than
moved.
you use the Scrolled method
to create the canvas,
you
can't
use the
item returned by that method to invoke either raise or lower; you'll get a nasty error about the
sion of
raise
wrong argument types because Scrolled
is
not invoking
this ver-
or lower, but another one. Use the subwidget to get the actual can-
vas reference and the
call to
raise and lower
will
work.
Deleting Items To remove an item delete method. It delete
all
matches
(or
more than one
takes a
it
list
item) from the canvas completely, use the
remove from the canvas. It will that you aren't deleting an example that uses three separate
of tag or IDs to
finds for the tag names, so
something you don't want to
Here
delete.
is
be careful
tag/IDs:
$canvas->delete "blue" (
You can
specify only
,
"circle"
one tag/ID or
,
as
$id_nuin)
many
as
;
you want.
;
(
;
204
Chapter 9: The Canvas Widget
Deleting Tags You can remove
tags
from items by using the dtag method. There are two forms:
$canvas->dtag tag) $canvas->dtag tag/ id, del tag) (
;
(
;
The first one will search for items with the specified tag and then delete the tag. The second will search for items that match the tag or ID and then delete the del tag (if it exists) from that item. This allows you to delete a subset of the tabs, rather than every single tag.
Determining Item Type To determine an
item's type, call the
$canvas->type tag/ id) {
type method:
;
more than one item, only the type of the first item is The returned value will be a string describing the item type: "oval", "text", "rectangle", and so on. the tag or ID matches
If
returned.
Set To
Keyboard Focus
assign the keyboard focus to an item, use the
focus method:
$canvas->f ocus tag/id) If
the item doesn't
know what
to
do with the keyboard
focus, nothing will hap-
pen. You'll use this to change the focus to a widget within the canvas.
Rendering the Canvas as PostScript You can It
get a
copy of the canvas
in a
as postscript
output
will either return the PostScript
or, if
by using the postscript method. -file option is specified, put it
the
file:
$postscript = $canvas->postscript $canvas->postscript (-file => "ps.out"); (
The following options allow you
)
to control the output of the PostScript.
-colonnap => \@array Specifies that each element in setting color values; e.g.,
-colormode => "color"
|
Creates the postscript in
("mono").
@array must be a valid postscript command
for
"1.0 1.0 0.0 setrgbcolor".
"gray" full
|
"mono"
color, grayscale ("gray"), or black
and white
205
Scaling the Canvas
-file => filename Specifies the
file in
which
to put the PostScript output.
-fontmap => \@array Each element
in
@array
is
two-element array that contains a fontname and
a
The fontname should be a complete font name so Tk *-140-*"). (e.g., "-*-Helvetica-Bold-0-Normal
point size. correctly
-height =>
—
will parse
a it
size
Sets the height of the area to print.
The
default height
is
the canvas height.
"center" -pageanchor => "n" "e" "s" "w" Indicates where the page should be placed over the positioning point fied by -pagex and -pagey options. Default is "center". |
|
|
|
speci-
-pageheight => height Sets the height of the printed page.
height
The canvas image
will
be scaled to
fit.
any valid screen distance.
is
-pagewidth => width width of the printed page. The canvas image
Sets the
will
be scaled
to
fit.
-pagex => x Sets the coordinate for the
x positioning
point.
Can be any
valid screen
distance.
-pagey => y Sets the coordinate for the
-rotate => page
-width =>
size
Sets the
point.
Can be any
valid screen distance.
1
|
If 1, tlie
y positioning
is
rotated into a landscape orientation. Default
is
portrait orientation.
width of the canvas area to be printed. Defaults to the width of the
canvas.
-X => X Sets the left
the
left
edge of the area
to
be printed
(in
canvas coordinates). Default
is
to
be printed
(in
canvas coordinates). Default
is
edge of the window.
-y => y Sets the top
the
left
edge of the area
edge of the window.
Scaling the Canvas When you them
all
put a large number of items on the canvas,
without scrolling
all
over the place.
It's
it's
sometimes hard to see
possible to scale the canvas, for
;
,
;
;
206
Chapter 9: The Canvas Widget
example, so
The usage
it
for
will shrink everything in half or
scale
explode
it
to twice the original size.
as follows:
is
$canvas->scale( tag/id, xorigin, yorigin, xscale, yscale)
The
scaling
is
centered around the xorigin and yorigin.
I
suggest using the real
you can come up with a good reason not to. Both xscale and the scaling factors used on each coordinate in each item. Here are some
origin (0, 0) unless
yscale are
examples: $canvas->scale{ "all" $canvas->scale( "all" $canvas->scale( "all" $canvas->scale("all" a great idea to
It's
Keep
ing for you. set
it
to
1
add
1,
0,
.5,
0,
0,
2,
2);
#
0,
0,
3,
3);
#
In
#
.5);
and
Zoom Out
button that takes care of the scal-
track of the scaling factor in a variable ($scale, for instance);
to start with. Multiply
thing you'll need to vas,
0,
0,
Zoom
a
no change! make all 1/2 size double everything triple everything!
#
1);
0,
do
make
is
it
by
.5
zoom
to
sure that,
you
if
you multiply those coordinates by the
out and by 2 to insert
zoom
any new items
in.
The
last
into the can-
scale factor as well (otherwise they will
look either too large or too small compared to the
rest
of the canvas items).
Scanning Use the scan method to implement scanning of the canvas: $canvas->scanMark (x, y) $canvas->scanDragto (x, y)
The
first call,
$ canvas ->scanMark(x,
the current canvas view.
The second
y)
call,
,
records the x and y coordinates and
$canvas->scanDragto (x, y) causes ,
the view in the canvas to be adjusted by 10 times the difference between these
coordinates and the previous ones sent with scanMark. This makes the canvas
look as
if it
was moved
Scrolling
at
high speed.
Methods
The canvas widget can be scrolled both horizontally and vertically. The methods xview and yview are used to communicate with the scrollbars. See Chapter 6 for more information on how these methods work.
A Drawing Program Example The canvas widget
is
very versatile and can be useful for displaying different types
mind when people
of items.
One
vas
drawing program. To save you the trouble,
is
a
of the
first
things that
comes
to
think of a can-
I've written a
rudimentary
A Drawing Program Example
207
drawing program called Quick Draw you can use to draw rectangles, ovals, and lines.
You can
also
change the thickness of the objects before you draw them.
only requires a tiny bit of error-checking to
make
it
It
a slicker program. Here's the
code: use Tk; $inw =
MainWindow->new;
$nTw->title( "Quick Draw");
$f = $inw->Frame( -relief => 'groove', -bd => 2, -label => "Draw: ") ->pack( -side => 'left',
-fill => 'y'); $draw_item - "rectangle"; $f->Radiobutton( -variable => \$draw_item, -text => "Rectangle", -value => "rectangle", -command => \&bind_start) ->pack( -anchor => 'w'); $f->Radiobutton( -variable => \$draw_item, -text => "Oval", -value => " oval " -command => \&bind_start) ->pack( -anchor => 'w'); $f->Radiobutton( -variable => \$draw_item, -text => "Line", -value => "line", -command => \&bind_start) ->pack( -anchor => 'w'); $f->Label(-text => "Line Width: ") ->pack( -anchor => 'w'); $thickness = 1; $f->Entry(-textvariable => \$thickness) ->pack( -anchor => 'w' )
-cursor => "crosshair" ->pack( $c = $mw->Scrolled( "Canvas" -side => "left", -fill => 'both', -expand => 1); )
,
$canvas = $c->Subwidget
&bind_start
(
"
canvas "
)
( )
MainLoop;
sub bind_start { # If there is a "Motion" binding, we need to allow the user # to finish drawing the item before rebinding Button-1 # this fen gets called when the finish drawing the item again ©bindings = $canvas->Tk: :bind("") return if ($#bindings >= 0); if
($draw_item eq "rectangle" $draw_item eq "oval" |$draw_item eq "line") $canvas->Tk: :bind( "" [\&start_drawing, Ev( 'x' Ev( 'y' |
|
|
,
}
}
)
,
)
]
)
{
;
;
;
;
;
208
;;
;
Chapter 9: The Canvas Widget
sub start_drawing
my ($canv,
{
= @_ $x = $canv->canvasx($x) $x,
$y)
$y = $canv->canvasy ($y) Do a little error checking $thickness = 1 if ($thickness #
if
/[0-9]+/);
!~
($draw_item eq "rectangle") { $canvas->createRectangle($x, $y, $x, $y, -width => $thickness, -tags => "drawmenow" elsif {$draw_item eq "oval") { $canvas->createOval ($x, $y, $x, $y, -width => $thic)cness, -tags => "drawmenow"): elsif ($draw_item eq "line") { $canvas->createLine($x, $y, $x, $y, -width => $thickness, -tags => "drawmenow"); )
}
}
}
$startx = $x; $starty = $y; Map the Button-1 binding to &end_drawing instead of start drawing $canvas->Tk: :bind( "" [\&size_item, Ev('x'), Ev{'y')]); $canvas->Tk bind " " \&end_drawing Ev x Ev y
#
,
(
:
(
:
[
,
(
'
,
'
)
,
'
'
)
]
)
}
siib
size_item
my ($canv,
{
$x,
$y)
= @_;
$x = $canv->canvasx $x) (
$y = $canv->canvasy ($y)
$canvas->coords "drawmenow"
$startx,
(
,
$starty,
$x,
$y)
}
sub end_drawing
my ($canv,
{
$x,
$y)
= @_;
$x = $canv->canvasx($x) $y - $canv->canvasy $y (
)
and remove the tag from the item
# finalize the size of the item,
$canvas->coords "drawmenow" $canvas->dtag "drawmenow"
$startx,
(
,
$starty, $x, $y)
(
)
remove motion binding. $canvas->Tk bind " " &bind_start #
"
(
:
:
,
"
)
( )
}
Note less
ality:
a
that
I
didn't set the
drawing space
Do
few
after a
nothing!)
-scrollregion was
for the user. (This It's
a cute
little
program
of the canvas methods. Figure 9-4
few items have been drawn on
it.
at all
because
the easiest that
I
way
wanted
to create a limit-
to provide this function-
demonstrates
how
to use
bind and
shows a screen shot of the application
Fun Things
209
to Try
QtickDraw
ilia
Draw: V' Rectangle
V
Oval
#
Une
Une
VWdth:
hi Figure 9-4. Quick
Draw application
Fun Things
screen
to Try
The Quick Draw application doesn't do much ideas for features to add to the application:
that
is
useful, but here are
•
Add
•
Create a Save Drawing feature that will loop through
the capability to print to a PostScript
file.
out their types and coordinates to a text
Drawing feature •
Allow the user
•
Add an
some
file.
Of
all
the items
course, you'll
and write
need
a
Load
as well.
to create text items.
entry widget that lets
name) with which
to
draw the
you change the color (by typing items.
in a color-
The Scale Widget
-7
A
scale widget
is
a strange
little
widget.
It's
thing other than
When you -
itself.
It
because
similar to a scrollbar
long and skinny with a button in the middle of
but
it,
it
—
does keep track of something though
change the position of the button
I with the scale changes. Here are
some
things
it is
doesn't scroll anya
number.
in the scale, the value associated
you can do with a
number between
•
Create a widget from which a user can select a
•
Create three scales, each representing a value in an
RGB
scale widget: 1
and
100.
(red, green, blue)
number. •
Create four sliders, each representing a portion of an IP address. Each scale
can go from a label
to 255,
and
it
would probably be smart
to start
widget to show the completed IP address, periods and
•
Create a temperature scale that
•
Show
the
amount of
rainfall
starts at
so far
them
at 255.
Use
all.
-50 and goes to 130 degrees.
this year.
The
scale can
be marked to show
every five inches.
The
scale widget can
have the most room
be placed horizontally or
in
vertically,
depending on where you
your application window.
Creating a Scale As with other widgets, you can create ing options to the scale to change
$parent->Scale
(
[
its
a scale
by using
210
it
option => value
on the screen (such
and pass-
configuration: ]
)
->pack;
Use one of the geometry managers discussed ment, to place
a parent widget
as pack, as
in
Chapter
shown
2,
in the
Geometry Managepreceding code).
211
Creating a Scale
Most of the options associated with the scale widget are the standard options used with
all
other widgets. All of the possible options are in the following
that
list.
A
discussion of special options that have a slightly different meaning for the scale
and options
that are specific to the scale
-activebackground => -state
-background =>
is
background should be when the cursor
is
over the
is
not over
'active').
color
background should be when the cursor
Sets the color the slider's
the slider
list.
color
Sets the color the slider's slider (the
widget follows the
(-state
is
'normal').
-bigincrement => amount Sets the amount by which
the slider will change value
in large increments. Default
is 0,
when
required to do so
causing the value to change by 1/10 the top
value of the scale.
-borderwidth => amount Sets the
width of the edges of the widget. Default
is 2.
-command => callback Sets the callback
invoked
when
the slider
is
moved.
-cursor => cursomame Determines the cursor to display
when
the
mouse
is
over the
scale.
-digits => amount Indicates
how many
significant digits to retain
when
conversion from a num-
ber to a string takes place.
-font => fontname Sets the font
used to display any
-foreground =>
text in the scale.
color
Sets the color of the text displayed in the scale.
-from => value Indicates the
low end of the
-highlightbackground =>
scale values. Default
is 0.
color
Sets the color of the highlight rectangle displayed
around the scale when
it
does not have the keyboard focus.
-highlightcolor =>
color
Sets the color of the highlight rectangle displayed
around the scale when
the keyboard focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle displayed
around the
scale.
it
has
|
.
.
212
Chapter 10: The Scale Widget
-label =>
labelstring
Describes a label for the scale. Default
is
no
label.
-length => amount Sets the length of the slider (the long direction, regardless of the value of
ent)
-orient => 'vertical'
'horizontal'
|
Sets the direction the scale
-relief => 'raised' Determines
-ori-
screen distance.
in a valid
how
|
drawn. Default
is
'sunken'
'flat'
|
is
'ridge'
'groove' 'solid' drawn. Default is flat
the edges of the widget are
-repeatdelay => milliseconds Sets the number of milliseconds
'vertical'. |
|
'
'
the widget waits before repeating.
-repeatinterval => milliseconds Sets the number of milliseconds the widget delays between
repeats.
-resolution => value by which the value
Sets the increments
-showvalue => If set
in the scale will
change. Default
is 1.
1
|
to 0, the value of the slider setting
is
not
shown
at all.
Default
is 1.
-sliderlength => value Sets the size of the slider (inside the widget). Default
-state => 'normal' Determines the with
it.
Default
'active'
|
state of the is
-takefocus => 1
'
normal |
|
|
is
25.
'disabled'
widget and whether or not the user can interact
'
\inde£
Determines whether or not the widget can receive keyboard focus. Default to let the
is
program decide.
-tickinterval => value Describes the labels drawn by the right (or on the bottom) of the scale. Labels means no labels will be drawn at all. are drawn for every value. A value of Default
is 0.
-to => value Sets the top value of the scale. Default
-troughcolor=>
is
100.
color
Sets the color of the area
behind the
slider button
(same as
a scrollbar).
-variable => \$ variable Sets the variable in
which the
slider value
is
stored.
-width => amount Sets the width of the skinny part of the slider (regardless of the value associ-
ated with -orient).
Minimum and Maximum
213
Values
Assigning a Callback The callyou change the value from 50 to 100 and the scale increment is 1, the callback will be invoked 50 times. The callback is also called when the widget is created. My recommendation is not As
usual, use the
back
to assign a callback for the widget.
invoked every time the scale value
is
to use
-command option
-command unless you have
a small
is
changed. So
number
if
of possible values.
Orientation To change
-orient
the orientation of the scale, use the
option.
It
takes a string
value that should contain either "horizontal" or "vertical". The default for this
option
is
"vertical". Figure 10-1 shows both
a horizontal scale
and a
verti-
cal scale.
1
-Si^.
J
abBBHuta „J
Figure 10-1. Vertical scale (the default orientation)
and horizontal scale
Minimum and Maximum Values Use the -from and -to options scale. Usually the
with -to.
If
to
change the possible range of values
value associated with
you happen
-from
is
to switch them, the scale will
value on the right and the lower value on the negative.
left.
still
display with the higher
Either or both values can
be
Here are some examples:
$inw->Scale(-from => $iTiw->Scale(-from => $inw->Scale(-from => $inw->Scale(-from =>
As you can
whole
for the
smaller than the value associated
-to => 10)->pack; -to => -100) ->pack; -100, -to => -50)->pack; -0.5, -to => 0.5, -resolution => 0.1)->pack; -10, 10,
see, the values assigned to
integers.
-from and -to
also don't
need
to
be
214
Chapter 10: The Scale Widget
Displayed Versus Stored Value Sometimes the value you are searching very
far apart,
and
such as
by one would be
tedious.
between two numbers
for resides
1,000,000. Stepping through each of those values
You can change
the step value of the displayed
ber using the -resolution option. The default for -resolution
be changed
to
Note
the resolution
that
if
any value
that is
that are
is
less or greater
larger than
1,
than
it
but
1,
it
can
that.
possible for the slider to have a
is
value (set by the program, for example) that
is
one
num-
smaller or larger than the dis-
is
played value.
Adding a Label You can add in
a
your scale by using the -label option. The label
a label to
different location
is
placed
depending on the value associated with -orient (see
Figure 10-2).
^
S(E9IR^fiiSSpte
-J
4
vertical
J
horizontal
l-j-i
Figure 10-2. Two scales with labels
Displaying Value Increments The
scale displays
its
current value above or to the
left
of
itself
(depending on the
value associated with -orient). Suppose you want to display labels (such as 10, 20,
...
100) that
show
the user approximately
where the button needs
to
0,
be to
them underneath or to the left of the and no scale, you can use the -tickinterval option. By default, it is set to numbers are displayed. To show the values every 10 numbers, use -tickinterval => 10. The larger the range of values from which the scale can select, the larger the value this should be, or you'll end up with a bunch of numbers so close select those values. If
you want
to display
together that you won't be able to
tell
what they
are.
See Figure 10-3.
options You'll Probably Never Need
215
vertical
-0.5
horizontal
30 0.0
0.0
J 40
ZO
80
60
100
0.5
Figure 10-3- Using -tickinterual with both horizontal
Changing the
and vertical scales
Size of the Scale
You can change the size of the scale by using the -length and -width options. You can also change the size of the button displayed in the slider widget; to do so,
will
use the -sliderlength option.
change the length of the
It
takes a value specified in screen units
slider button.
$itiw->Scale( -sliderlength => 100);
f^{
#
and
See Figure 10-4.
make the button 100 pixels.
Scale exani}ile ,
1
^
Jl
Default slidertength: '^^"
r"~~r'™
'""""
~" ~
Sliderfengthof 100:
jl
Slideriengthof 10:
Hi
Figure 10-4. Different -sliderlength values
Options You'll Probably Never Need The two final options for the Scale widget creation method are -bigincrement and -digits. The -bigincrement option specifies the size of jumps when using really large numbers. The default for -bigincrement is 0, which means it will jump in increments that are 1/10 the total range. The -digits option represents how many digits will be used when converting from a number to a string. The default (0) forces the scale to use a precision that allows for a different string for every possible value on the scale.
;
;
;
216
Chapter 10: The Scale Widget
Configuring a Scale As
configure and cget methods, which let you query scale widget. See Appendix A for more details on how to
usual, the scale has both
and
options for the
set
use these methods.
Getting the Value of a Scale The get method $value
You can
=
will return the current value of the scale:
$scale->get
also specify
(
)
x and y coordinates and
retrieve the value of the scale at that
point:
$value = $scale->get
(x,
y)
;
Setting the Value of a Scale You can
force the value associated with the scale
by using the set method:
$scale->set (value)
This
method
option
great for setting an
is
at all. If
initial
value
you were using -variable,
if
you
aren't using the
-variable
just set that variable to the
desired
starting value.
Determining Coordinates The coords method ($x,
$y)
=
$scale->coords
The coordinates scale.
You can
($x,
$y)
=
returns a
list
containing x and y coordinates:
;
indicate the position in
which the current value
is
located in the
also pass in a value to find the coordinates of:
$scale->coords (value)
Identifying Parts of a Scale You can
find out
what
part of the scale a coordinate resides in
by using the iden-
tify method: $value
=
$scale->identify(x, y)
The identify method
;
returns a string containing
"slider", "troughl", "trough2", or an empty refer to
any of these
parts).
one of the following
values:
string (if the coordinates don't
Fun Things
217
to Try
Fun Things
to Try
Create a survey form that contains scale widgets for user information. Items
such as age (0-150 would be a safe range), income, and number of children the household can
all
be entered
into a scale.
Make good use
in
of the -reso-
lution, -to, and -from options to make the job easier for the user. Create a ping application that uses scale widgets (one for each portion of the IP address) to request
an IP address from the
user.
Menus
Different Types of Menus There are several ways to create and
Here are some examples of
application. •
Create
•
Display a
File, Edit, list
utilize a
menu from
how you
can use a menu-type widget:*
and Help menus across the top of your
within your Perl/Tk
application.
of fonts from which the user can choose (the selected font can
be marked with a checkmark). Display a
•
right-clicks
list
of editing
on another
commands
that
become
available
when
object (such as a listbox or entry widget) in your
the
user
window.
You can build each of these different types of menus with the basic menu widget. The menu widget itself is a list of items that are displayed one item per line in a box. Each item can have an associated callback that is called when the menu item is
invoked or selected. Unlike the other widgets
we have
seen so
far,
you cannot
use any of the geometry managers on a menu. Instead, you must use a method called
post
to display
your
menu widget (post
will
be discussed
later in this
chapter).
shows the contents of a typical menu widget. It contains several items, and a few more items. Separators are useful for grouping together related commands and providing a visual break if one menu contains a number of commands. Figure 11-1
a separator,
*
contains commands that aren't used frequently, such as configuration options, File Help, and .so on. You would be wise to put frequently accessed commands in the winto provide easier access for the user.
Typically, a
Open,
dow
218
menu
File Close,
219
Different Types of Menus
menu widget Item1
Item2 Items Item4
Figure 11-1. Simple
Menus
menu
are a great
radiobuttons,
way
widget with five items: Iteml, Item2, Separator, ItemS, to replace checkbuttons
you can place them on
and radiobuttons.
menu and
a
and Item4
you have
If
five
save a ton of screen space for
more important widgets.
A menubutton when
the
widget
menu
is
is
based on the menu widget and has a button
displayed.
When
the button
is
pressed, the
menu
that controls is
displayed
below the button. The button contains a text string that describes the items in the menu. A menubutton is the type of menu you'll use 90% of the time. Figure 11-2 shows a block diagram of a menubutton after the button has been pressed. The button part of the menubutton is the where the word "File" appears. directly
Figure 11-2.
A menubutton
menu
widget that uses a
widget
The main advantage of using a menubutton widget is that it handles the display functions of the menu. Because this is the most frequently used menu-related widget,
The
it
will
last
be covered
first.
menu-related widget covered
ently than the other type of
item from a
list
is
the optionmenu,
which behaves
menus. The optionmenu allows the user
differ-
to select
one
of items. For example, you can use an optionmenu to add the
following options to your program: •
Allow users to
•
Allow users
•
Allow users to choose Silent,
select a favorite color
to select the country in
how
from a
list
which they
of colors. live.
verbose they would
Semi-Verbose, and Verbose.
like the application to be:
Chapter 11: Menus
220
Figure 11-3 shows a block diagram of an optionmenu with Item3 selected.
Optionmenu widget (or popup menu)
Item1
Item2
Items Select Value:
Item4
Figure 11-3- Example of an optionmenu widget
Menus simply give you a way to group related tasks together, and the optionmenu allows you to group several choices together. There is a callback associated with each
menu
much
item,
like the callbacks associated
using 10 separate buttons, you can create 2
menus
with button widgets. Instead of
that
each contain 5
menu
items.
on display space and helps users understand that those items have a purpose and have been grouped together for their convenience.
This saves lar
simi-
The Menubutton Widget wMB^WIWi \
Item
1
..1
^ As described earlier, the menubutton widget has a down from a button when the button is pressed. The
from the window when an item from the menu
is
menu menu
that is
selected or
drops
removed
when
the
user clicks elsewhere in the application.
Many
applications use a menubutton-type construct.
The menubuttons
grouped across the top of the application and have names like File, Options, and Help. Figure 11-4 shows an example of several menubuttons
are normally Edit,
grouped together
in a frame.*
Creating a Menubutton when you
create a
menubutton widget, use the parent widget
Menubutton method, which then creates a menubutton widget options you send with the Menubutton method can configure both is initially displayed on the screen and the actual menu items: $itibutton =
$parent->Menubutton
(
[
options...
]
)
to invoke the
reference.
The
the button that
->pack;
this same look in a window by using a menubar widget. However, the additional provides is minimal, so we won't be covering it in this book. To get this look, create a frame widget with a relief of "ridge" and borderwidth of 2. Pack the menubuttons with -side => "left" for ail but the help menu, which has -side => "right".
•
You can accomplish
functionality that
it
221
The Menubutton Widget
— RIe
^ Jl
M^mftRittofi Edit
Options
Help
Exit 1
Figure 11-4. Example of window with several menubuttons across the top
When
it
is first
displayed with one of the geometry managers, you will only see
which is a button with "flat" relief. The menu menubutton won't appear until you press the button. Figure 11-5 shows the menubutton widget before and after the button is pressed. Notice how the button part of the menubutton, part of the
the relief of the button changes after
it
is
pressed.
^ mmii
^
Jl
'
3 Menuil
^J4
Menubutton
L
Menubutton =*
—
^^
1
Itemi torn 7 Item 3
Item
Figure 11-5- Menubutton before
and after the
button
4
is pressed
Menubutton Options The options specified with the Menubutton command (or via the configure method) can affect only the button part of the menubutton, both the button and the menu, or just the menu.* The options that affect the menu are valid for the menu widget as well as the menubutton widget. We will cover the available options briefly (and some not so briefly) in order to discuss the effects of each. The brief synopsis of all the options and their effects appears first.
When
the description says "Affects the button only," the behavior
would be
*
The menubutton widget comprises other widgets
functionality.
is
the
same
as
it
for a button widget.
(in this case,
button and menu) to provide the overall
.
222
Chapter
-activebackgroimd => Affects the
1 1:
Menus
color
background color of the button and the currently highlighted menu
item.
-activeforeground =>
color
Affects the text color of the button
-anchor => center '
'n'
|
'ne'
|
'se'
's'
|
'sW
|
'w'
|
|
item.
'nw'
|
'
Affects the button only.
-background =>
Changes the position of the
text within the button.
color
Affects the button
when
'e'
|
and the currently highlighted menu
and the menu.
the state of the button
All the
background color changes
and menuitems
is
'
normal
to color
'
-bitmap => bitmapname Affects the button only. Displays bitmap instead of text.
-borderwidth => amount Affects the button only.
Changes the width of the button edges.
-cursor => cursomame Changes the cursor when
Affects the button only.
it's
over the button part of
the menubutton.
-disabledforeground => Affects the button
color
and the menu item
text
when
-state
the
for either
is
'disabled'.
"below" "left" "right" "flush" -direction => "above" TkS.O option only. The value "above" puts the menu above the menubutton, "below" puts it below the button, and "left" and "right" puts it on the |
|
appropriate side of the button,
|
|
"flush" puts the menu
directly over the
button.
-font => fontname Affects the button only.
-foreground =>
Changes the font of any
text displayed in the button.
color
Affects the button only.
Changes the color of any
text or
bitmap to
color.
-height => amount Affects the button only.
Changes the height of the button.
-highlightbackground =>
color
Changes the color of the highlight rectangle displayed around the button when the button does not have the keyboard focus.
Affects the button only.
-highlightcolor =>
color
Changes the color of the highlight rectangle displayed around the button when the button does have the keyboard focus.
Affects the button only.
223
The Menubutton Widget
-highlightthickness => amount Affects the button only. Default
gle
around
Changes the width of the highlight rectan-
is 0.
edges of the button.
all
-image => imgptr image instead of
Affects the button only. Displays an
-indicatoron =>
1
|
mechanism
Affects the button; indirectly affects the display
When text,
set to 1
,
text.
on
a small bar appears
for the
menu.
the right side of the button next to any
bitmap, or image.
-justify => 'left'
'right'
|
Changes the
Affects the button only.
-menu => $menu Tells the menubutton
'center'
|
justification of the text
to display the
menu
within the button.
associated with
$menu instead of
anything specified via the -menuitems option.
-menuitems => Causes the
list
menu
to display a
of items to create.
list
-padx => amount Adds
Affects the button only.
extra space to the
left
and
right of the button
inside the button edge.
-pady => amount Affects the button only.
Adds
extra space to the top
and bottom of the button
inside the button edge.
-relief => 'flat'
'groove'
|
Affects the button only. Default
'raised' when the button
-state => 'normal'
is
'raised'
|
'
is
.
The
relief
'sunken'
of the button changes to
'disabled'
|
menu (menu
Affects the button; indirectly affects is
'
|
pressed.
'active'
|
flat
'ridge'
|
cannot be displayed
if
state
'disabled').
-takefocus =>
|
1
|
xmdef
Affects the button only. Default
is
0.
Determines whether or not the button
can have the keyboard focus.
-tearoff => Affects the
dashed
-text =>
|
1
menu
line in the
only. Default
is
1.
If set
to 0,
does not display the
tear-off
menu.
text string
Affects the button only. Displays the specified string
the -bitmiap or
-image option
is
used).
on the button (ignored
if
224
Chapter 11: Menus
-textvariable => \$variable Affects the button only. The information displayed on the button.
in
$variable
is
displayed
-underline => charpos The character
Affects the button only.
at
the integer charpos
is
underlined.
If
the button has the keyboard focus, pressing the key causes the button that
corresponds to the underlined character to be pressed.
-width => amount Affects the button only.
Changes width of the button
to
amount.
-wraplength => pos Affects the button only. Default
maximum amount
0.
is
Determines the screen distance for the
on one
of text displayed
line.
Button-Only Options The following options behave exactly
only the button portion of the menubutton, and
affect
as described in
Chapter
3:
-cursor, -anchor, -bitmiap, -border-
width, -font, -foreground, -height, -highlightbackground, -highlight-
-highlightthickness, -image, -justify, -padx, -pady, -relief, -takefocus, -text, -textvariable, -underline, -width, and -wraplength.
color,
-state,
Tear-off Items Each menu you create can be "torn off from
menu get
is
a
dashed
becomes
dow
its
line (see Figure 11-6);
own window and
its
when you
remains present
window. The
first
item on the
select this item, the until
you close
it
menu
wid-
with the win-
manager.
The other You can move the menu around on the screen, but you can't resize menu items will behave normally when they are selected. Be careful; you can tear off the same menu multiple times. Tom-off menus won't be updated when other events it.
in the
program are updated, so
it
is
a
good
idea to limit your use of tear-off menus.
with your list of arguments To remove the tear-off ability, use -tearof f => when you create the menu and the dashed line will no longer appear.
The
tear-off line in the
so your
menu
actually counts as
an item.
menu items will then number from 1 and menu items will number from and up.
then your
up.
It
If
uses index
if it
exists,
you use -tearof f=>0,
225
The Menubutton Widget
Menid)
3^§^
J
J
Menubutton
Menubutton
Itemi
Itemi
ItemZ
item 2 Item 3
Item 3
Item 4
Item 4
Figure 11-6.
Menu
with tear-off item
and menu
without tear-off item
Color Options options that determine
Several
color
both the button and the menu:
affect
-activebackground, -activeforeground, -background, and -disabledforeground.
Both -activebackground and -activeforeground played in the button and
menu
the currently active
affect the text/bitmap dis-
item in the menu. The cur-
menu item is the one that the mouse cursor is currently over. The becomes slightly raised and might change color depending on these The effect of these options on the button is the same as it is for a normal
rently active
menu
item
options.
button widget.
The -backgroimd option affects the entire menu and button background. The -disabledforeground option changes the color of the text of any menu items that have their own -state of 'disabled'; it also changes the text/bitmap color of the button if its -state is 'disabled'
Button Indicator In Chapter 4, their
own
tor that
we saw how
the radiobutton and checkbutton widgets each have
type of indicator. The button part of a menubutton also has an indica-
can be displayed on
right of the text, bitmap, or
indicator
button.
used
is
used to show
The option
that
it.
The
indicator
is
a small
3D
bar displayed to the
image on the button (see Figure something
to display the indicator
is
to display the indicator for the radiobutton
^
11-7). Usually the
happen when you press the -indicatoron, the same option
different will
fctefKUtNitton
^
and checkbutton widgets.
j|
'
Indicatoron
Figure 11-7. Menubutton with indicator shown
Menu
-^
,
,
226
Chapter
1 1:
Menus
-indicatoron to 1 does not change the appearance of the menu at you would not use the -indicatoron option unless you were using menubutton as a type of option menu or in a non-standard fashion. Setting
all.
Usually,
the
Specifying Items for the
Menu
Everything in this section will also apply to using the -menui terns option with the
menu widget
in addition to the
menubutton widget.
The easiest way to add items to the menu in a menubutton is to use the -menuitems option. The value sent with the -menui t ems option is a list of lists* that
menu but also any possible configuraway to illustrate this is with an example.
indicates not only the order of items in the tion options for that
menu
item.
The
best
$menub = $mw->Menubutton(-text => "Menubutton", -menuitems => [[ 'coitimand' => "Item 1"], 'command' => "Item 2"], [
[
[
In this snippet of code,
we
'command' => "Item 3"], 'command' => "Item 4"]]);
same menu
are creating the
that
we
displayed in
Figure 11-5. Here's a
breakdown of
the elements of the
list
and what they mean. The -menu-
items option expects a list of lists. It is the sub-lists that contain information about menu item. Each list that configures a menu item has a specified order to it. The first thing in the list is a string that will determine what type of menu item is created. The available types of menu items are "command", "radiobutton", "checkbutton", and "cascade". The second thing in the item list is a string that is displayed on the menu. After that, the options that affect that menu item type can be specified. To create a separator, use a string in place of an anonymous list. each
As you can
menu
-menuitems, I didn't assign any callbacks for any of the you selected one, nothing would happen. To assign callbacks, we
see, after
items. If
would change
the statement to look like
this:
$meniib = $mw->Menubutton(-text => "Menxibutton"
-menuitems =>
[[
[
•
is
If
]
]
you don't know what I mean by "list of list.s," you'll find that the Camel book (Programming Perl) The new version contains more information than you'll ever need to know about hashes, and creating anonymous lists.
a u.seful reference.
lists,
'command' => "Item 1", -command => \&do_iteml 'command' => "Item 2", -command => \&do_item2
227
The Menubutton Widget
'coinmand'
[
[
I
]
,
'command' => "Item 4", -command -> \&do_item4
]
]
used the -command option to add the callbacks, and
tine for
menu
each
item.
It
doesn't
=> "Item 3",
-coinmand => \&do_item3
make any
I
)
used a different subrou-
sense to specify a callback for the
separator item.
The
first
diately
two items
by
for
each item
a text string that will
list
must be the item type
be displayed
in the
play a different text string by using the -label option or to
second argument It
in this
list
might be confusing that
must be a
we
followed immeyou plan to disdisplay an image, the
string
menu. Even
if
string.
use both "command" and -coinroand. The
item type string and the second
is
first is
the option (which should be followed
the
by a
callback).
You can
method to add items to the menu: $menub-> also use the Addl terns -label => "Iteml", -command => \&do_iteml) ;. Addltems "command" The argument list is slightly different (you send only the type, and then you must use the -label option to specify the text to appear on the menu, but all the ( )
(
,
options for each
menu
item type are exactly the same).
menu
Certain options only apply to certain
item types, which are discussed in the
following sections.
Command item, So
far,
type
each example of a
menu
has had only "command" and "separator" types
of items. Usually, you'll also use the
pen when
the
Radiobutton It is
menu
item
is
-command option so
that
something
will
hap-
selected.
item, type
possible to put radiobuttons in a
menu
rather than inside the
window where
radiobutton would in the winThe same radiobutton rules apply: You should always have at least two radiobuttons and they should be grouped logically by using the same -variable => $variable option for each group. Figure 11-8 shows an example of the placement of radiobuttons in a menu.
they take up space. They look and act
dow
except they are
listed in the
menu
just like a
instead.
;
;
;
;
228
Chapter
Menut
-J
1 1:
Menus
J
J
Menubutton
^ Radio
1
# Radio 2 ^ Radio 3 '^
Radio 4
-*"
Radio 5
"^
Radio 6 1
Figure 11-8. Radiobuttons as
example
In an
in
menu
Chapter
4,
items
Checkbuttons
and
Radiobuttons,
tons to select the background color of the window.
radiobuttons in a #
!
menu and
We
we
used radiobut-
could also use those
save space in our application:
/usr/bin/perl -w
use Tk;
my
MainWindow->new;
$inw =
$iTiw->title "Menubutton" (
)
;
$inw->Menubutton(-text => "Color" ->pack( -side => 'left', -anchor => n foreach (qw/red yellow green blue grey/) { $menub->radiobutton( -label => $_, -coinmand => \&set_bg, -variable => \$background_color, -value -> $_)
$menub
=
)
'
'
)
}
MainLoop;
sub set_bg { print "Background value is now: $background_color\n" $inw->configure( -background => $background_color) }
Figure 11-9
menu
shows what the window looks
like after
it
has been resized and the
has been posted.
Checkbutton item type
You can
also put checkbuttons in a
menu
to
keep them out of the way. Use the
-coitimand option to configure the checkbutton to perform an action selected. Figure 11-10
Remember
shows what checkbuttons look
like in a
when
not.
is
menu.
the checkbutton guidelines: each checkbutton should have
-variable, because each can be selected or
it
its
own
229
The Menubutton Widget
^
~
^
-
N
color
-
sWiEiiRi^ptoii
^^^^^^^^-^8
red *^
"^
yellow
green blue
grev ™™* 1
Figure 11-9- Using radiobuttons in a
menu
^
to set
background color
Menu^
^
4
Menubutton
rm W Check
1
r
Check 2
pr
Check 3
r Check 4 m Check S r Check 6 Figure 11-10. Checkbuttons in a
menu
(1, 3,
and 5 selected manually)
Cascade item type
A
menu item points to another menu. When you select this type another menu will pop up to the right of the current menu. This is
cascade
item,
of
menu
the most
complicated item type to implement because you have to create another entire
menu
to display (the next major section in this chapter covers the
Figure 11-11 shows what a cascade
menu
item looks
like.
Menubutton
Figure 11-11. Cascade
menu
item inside a menubutton widget
menu
widget).
;
;
;
;
Chapter 11: Menus
230
The submenu must be a child of the menu within the menubutton widget. This allows Peri Tk to keep track of the correct hierarchy of the menus. The best way to create a submenu is to create the menubutton first and then create the submenu. $inenub = $inw->Menubutton(-text => "liy Menu",
-menuitems => [["cascade" => "Submenu"]]); $suhinenu - $inenub->inenu->Menu( -menuitems =>
We
can use the menubutton widget"s menu
item and then create the
new menu
$menub->entryconfigure( "Suimenu"
,
-menu =>
program
cade menus.
#! /tisr /bin/perl
item.
Now we
to point to the
is
it
can add
new submenu:
;
necessary to
menu
with the actual
menu
to return the actual
menu
it
first
will display.
you to play around with so you can get the two submenus, one with numbers and one with
for
creates
It
it
it
;
)
$ submenu )
Because of some problems with cascade menus, cascade entry and then configure
]
method
( )
as a child of the
menubutton and configure
the cascade item to the
entire Perl
...
[
create the
Here
is
an
feel of casletters:
-w
use Tk;
my $mw
= MainWindow->new; $mw->title "Menubutton" # Create menubutton and put on the screen $menub = $mw->Menubutton -text => "Menubutton" ->pack; (
)
)
(
make our suh menu to be cascaded a child of upper menu. $menul = $menub->menu->Menu; foreach (qw/one two three four/) { -label => $_) $menul->add( 'command' #
,
}
#
make second sub menu also a child of the upper menu
$men\i2 = $menub->menu->Menu;
foreach (qw/A BCD/) { $menu2->radiobutton (-label => $_) }
now add the cascade items to the main menu $menub->cascade( -label => "Numbers"); $menub->cascade( -label => "Letters"); #
now configure those cascade entries to point to correct submenu $menub->entryconfigure( "Numbers" -menu => $menul) $menub->entryconfigure( "Letters", -menu => $menu2); #
,
MainLoop;
You can
also create cascade
menu, but remember
to create
menu it
items
on
a
menu
as a child of that
that cascades
menu's menu.
from another
The Menubutton Widget
231
Separator item type Separators are noninteractive portions of a menu.
between menu items. To method on the menubutton widget or use a visual break
of another
They do nothing except provide separator
create one, either call the a string in the
-menuiteras
list
instead
list.
ImU
Mi^ii^
J
a
Menubutton
j
Itemi
ItemZ Item 3 Item 4
Seoarator
line 1
Figure 11-12. Separator in a menubutton widget
Figure 11-12 shows the separator
which
is
a
to create the
line (not
$niw->Menubutton(-tearoff =>
0,
unlike the tear-off menu, The following code was used
line. It is a solid line,
shown menubutton shown in
dashed
in Figure 11-12).
Figure 11-12:
-menui terns =>
[
['command' => "Item 1"], ['command' => "Item 2"], ^'command' => "Item 3"], ;'
We
could have used any string
style to is
at all in
always use the same string so
command' => "Item 4"]
place of the "-"
it is
line.
easy to recognize
However,
when
]
it
->pack; is
good
a separator item
created.
Accelerators The -accelerator option allows you to place a text string to the right of the text or image displayed in the menu. The string usually contains a clue to a quick-key combination that Figure 11-13, Item
will 1
execute the
command
associated with the
-menui terns
created by using this
list
-accelerator =>
"Alt+1"]. To make the
form an
need
action, you'll
in the
to use
bind
option: Alt-1
[
menu
item. In
The menuitem was 'command' => 'Item 1',
has the accelerator string Alt+1 next to
it.
key combination actually per-
(see Chapter 14, Binding Events).
;
,
252
Chapter 11: Menus
.
.
PI Meiiii^
.
1
1
^
Menubutton falBH
Item
1
AIU1
Item 2
items Item 4 1
Figure 11-13-
Menu
with accelerator next to Item 1
Menu Item
Displaying an Image in a Each menu item
is
image instead of
text.
the
-image
option.
a type of button, so
it
makes sense
Figure 11-14 shows what happens
The code
that created the
menu
is
that
you can display an
when you
also specify
as follows:
$imgl = $rnw->Bitmap(-file => "/usr/XllRe/include/Xll/bitmaps/lineOp.xbm" $inw->Men\ibutton(-text => "Menubutton", -menuitems => [[ 'coinmand' => "Item 1"], 'command' => "Item 2", -image => $imgl] )
[
'command' => "Item 3"], 'command' => "Item 4"] ->pack(-side => 'left');
[
[ )
]
g^MCTtrt^
-ijj
Menubutton
fteml
\ Item 3 Item 4
Figure 11-14.
An image displayed instead of text
In Chapter 4,
I
discussed using icons and
how
they can
make
options easier to
understand. Try to use good judgement and not go crazy with the picture items.
Too many vague
make an
menu
icons (such as the one displayed in Figure 11-14) can
application confusing.
The Menubutton Widget
233
Assigning a Different Menu By
default,
create your
But there
when you use the -menuitems option, a menu is own menu widget and tell the menubutton widget
is
a trick involved.
It's
You can
created. to use
a chicken-before-the-egg problem.
it
instead.
You need
to
menubutton and then create the menu widget as a child of the menubutton. Use configure to assign the new menu to the menubutton. Here is the
create
a
code example: create menubutton w/ some fake menu items $ml = $mw->Men\ibutton(-text => "Text Menul", -menuitems => [[ 'command' => "Item 1"], 'command' => "Item 2"],
#
[
[
[ )
]
'command' => "Item 3"], 'command' => "Item 4"] ->pack -side => "left", -expand => 'y' -fill => 'both' (
)
Create a Menu as a child of the Menubutton $ml $menu = $ml->Menu( -menuitems => [[ 'command' => "Item 1"], 'command' => "Item 2"], 'command' => "Item 3"]]); #
[
[
Now use the $menu with the Menubutton $ml->configure(-menu => $menu) #
MainLoop
As mentioned, you need to create the menubutton first and make it a child of $itM (the MainWindow). I created some menu items that will be different on the new
menu
so you can
tell
which menu the menubutton
is
using.
Configuring a Menubutton The cget method allows you
to get configuration information about
options associated with a menubutton.
You can use configure
any of the
to query or
change any of the options. Both configure and cget are explained
Appendix A, Configuring Widgets with configure
fully in
and cget.
Configuring Menubutton Items The menubutton widget has an entrycget method widget's entrycget method.
that
is
the
same
as the
menu
$value = $menub->entrycget index, option); (
The arguments cussed
in
"The
are an index
Menu Widget"
and the option
to query. Valid index values are dis-
later in this chapter.
;
;
,
; ;,
;
234
Chapter 11: Menus
The entryconf igure method is also provided by the menubutton widget. It performs the same function the menu widget's entryconf igure method performs: $men\ib->entrYconf igure index, (
Adding Items
to
option
[
])
;
a Menubutton
The Addl terns method gives you another way to put new items in the menu. It will always add the new item(s) to the end of the menu in the order they appear in the list. Similar to the arguments sent to the -menuitems option, the arguments sent to Addl terns are included in several lists. There is no need to enclose the item lists inside another list level because the only thing you send to Addl terns is item
lists.
Here
is
an example:
$menub = $rnw->Menubutton -text => "File" ->pack; $menub->AddItems ["coinmand" => "Open", -coinmand => \&do_open] ["command" => "Close", -command => \&:do_close] )
(
(
,
-command => sub
["command" => "Exit",
This use of
Addl terns
is just
another
way
exit
{
}
,
]
)
of saying the following:
$menub = $mw->Memibutton(-text => "File", -menuitems => ["command" => "Open", -command => \&do_open] ["command" => "Close", -command => \&do_close] [
)
]
["command" => "Exit", ->pack;
Notice the extra set of All the information in
sent to
[
]
around the
between the
[
lists ]
is
{
exit
containing the
exactly the
}
]
menu
same
as
it
item information.
was when
it
was
Addl terns.
The command method adds use command, you must use in the
-command => sub
menu
.
a
item to the end of the menu. When you -label option to specify the text to be displayed example created: the same menu Addltems
command
the
This code creates
( )
$menub = $mw->Menubutton(-text => $menub->command( -label => "Open", $menub->command( -label => "Close", $menub->separator $menub->command( -label => "Exit",
"File" ->pack; )
-command => \&do_open) -command => \&do_close) -command => sub
{
exit
}
)
Creating a Cbeckbutton The checkbutton method adds a checkbutton item to the end of the menu. Like the command method, you are required to use the -label option to specify the text string to display in the
menu
with the checkbutton. All other checkbutton item
The Menubutton Widget
235
options are the same as those listed in "Specifying Items for the this chapter.
Menu"
earlier in
Here's an example:
$menub = $mw->Menubutton(-text => "Options"); $menub->checkbutton( -label => "Confirm Quit?" -variable => \$confirm_quit)
checkbutton is really a menu widget method, but it also works on a menubutton The same is true of radiobutton, separator, and cascade.
widget.
Creating a Radiobutton The radiobutton method adds must specify the
text to
a radiobutton item to the
be displayed
in the
menu by
end of the menu. You
using the -label option.
$menub->radiobutton(-label=> "Radio item")
Creating a Separator The separator method adds
a separator line to the
end of the menu.
It
does not
take any arguments: $menub->separator
(
)
Adding a Cascade Menu end of the menu. You must by using the -label option. Use $menub-> entryconf igure -menu => $submenu) to assign the menu to be cascaded.
The cascade method adds
a cascade item to the
specify the text to be displayed (
assume we already created $menu_more $menub->cascade (label => "More menu..."); -menu => $menu_move) $meniib->entryconf igure "More menu. ", #
.
(
.
Getting a Reference to the The menu method
Menu Item
returns a reference to the
menu used
within the menubutton
menu as the parmenu widget methfrom our menu by using
widget. This allows us to create cascade entries with the actual ent of the cascaded ods.
For example,
menu;
we
it
also allows us access to
could delete a
menu
all
item
of the
$menub->menu->delete(l), which would delete the second item in the menu. For more information on the menu widget methods, see "The Menu Widget" later in this chapter.
;
;
;
236
Chapter
1 1:
Menus
Complete Menubutton Examples Menus
more complicated widget than we've seen before because you them the same way. Sometimes you can use the simple -menuitems option, and other times you'll want to add to them dynamically. This section contains some full-length Perl scripts that create some useful are a
don't always add items to
menus.
Creating a Here
is
Menubar
the code that
was used
to create the
window and menubar
in Figure 11-4:
# /usr/bin/perl -w use Tk; my $inw = MainWindow->new; $iTiw->title "Menubutton" !
(
)
;
$inw->Button(-text => "Exit", -command => sub
{
exit;
}
)
->pack{-side => "bottom");
= $mw->Frame (-relief => 'ridge', -borderwidth => 2); $f->pack(-side => 'top', -anchor => 'n', -expand => 1, -fill => 'x');
my $f
foreach (qw/File Edit Options Help/) { push (©menus, $f->Menubutton(-text => $_)
)
}
$menus $menus $menus $menus
[3
]
[0] [1] [2]
->pack -side ->pack(-side ->pack(-side ->pack(-side (
=> right => 'left') => 'left') => 'left') '
'
)
MainLoop First a
frame was created across the top of the
window and packed
so
it
will resize
itself dynamically when the window gets larger or smaller. Then the menubuttons were created and packed into the frame. Each of the menus has no items. We'll
leave that as an exercise for the reader.
Dynamic Document List In certain cases, you'll
a
menu
dynamically.
Many
recently
opened and
applications
want to add and remove items from remember which documents you've most
keep them attached something creates a
similar,
to the File
menu
for easier access later. This
but I've simplified the problem
new document name, and
—
we'll just
we'll display that
example does
have a button
document name
in
that
an entry
237
Complete Menubutton Examples
widget so
#
we know which one we
are editing. Using our
methods from the menu widget,
select !
we
menubutton and
can create a solution
a
like this:
/usr/bin/perl -w
use Tk; $inw = MainWindow->new; $mw->title "Documents" (
)
Create a frame for our menubar across the top of the window $f - $mw->Frame{ -relief => 'ridge', -borderwidth => 2) -expand => 1, -fill -> 'x'); ->pack(-side => 'top', -anchor => 'n' #
,
Create the memibutton, with two items: New Doc and a separator $filem = $f->Men-ubutton(-text => "File", -tearoff => 0, ["command" -> "New Document", -menuitems => -command => \&new_document]
#
[
->pack{-side => 'left'); We will open docijment 1 to begin with, and we want to limit the number # of documents in our list to 0-9 {leaves 10 docs max in menu) $doc_num = 1; $doc_list_limit = 9; )
]
#
Create button that will do the same thing as the New Document menu item $mw->Button(-text => "New Document", -command => \&new_doc\jment) ->pack(-side => 'bottom', -anchor => e # The entry will display the current doc we are "editing". $entry = $mw->EntrY( -width => 80) ->pack( -expand => 1, -fill => 'both'); #
'
'
)
MainLoop;
Creates the next doc in line, incs the doc coionter Adds the new doc to the menu, and removes any docs from the # menu that are over the limit (oldest out first) sub new_doc\jment { my $name = "Document $doc_num" $doc_num++; # #
push (©current, $name) $filem->command( -label => "$name", -command => \&select_document, $name [
&select_doc;mient ($name) if
} }
;
($#current > $doc_list_limit) $filem->menu->delete(2) shift (©current)
{
]);
few
)
238
Chapter 11: Menus
sub select_document { iny ($selected) = @_; $entrY->delete(0, 'end'); $entry->insert 'end' "SELECTED DOCUMENT: $selected" (
,
Figure 11-15
shows what our window looks
like after
we've created three documents:
[selected DOCUMENT: Document 3
New Document Figure 11-15. Example of Document History
window
The Menu Widget when you
There are times
won't want to use a menubutton widget. Perhaps you
some menus that will cascade from your menubutton. You still need need to create the menus. You might also think of a way to use a menu that doesn't involve a button. For example, you could set up your application so the user right-clicks on a widget' and a related menu pops up, allowing the user to to create
change configuration options. It
is
also a
whether
it's
good idea a
to
be
familiar with the
menu widget by
itself
or the
methods
menu
for manipulating a
menu,
attached to a menubutton.
Creating the Basic Menu To
create a $inenu =
menu
widget, invoke
$parent->Menu options) (
The menu widget
is
menu
$menu->post
(
...
)
•
menu:
on which one of the geometry managers post directive:
is
displayed to the user via a
;
Different arguments sent to is
is
the desired parent of the
;
the only widget
not used directly. The
method
Menu from
post
will
determine
discussed later in this chapter.
Use "" with bind.
how
the
menu
is
displayed. This
The Menu Widget
Menu
239
Creation Options
As with any widget, there are options behaves.
Many
ton widget portion of the chapter, so aren't available with the
The following
is
a
list
how
that affect
I'll
menu widget
-activebackground =>
looks and
discussed in the menubut-
only cover those that perform actions that
menubutton widget or whose actions
of the options available for the
Sets the color of the
the
menu widget were
of the options for the
menu
are different.
widget:
color
background behind the
active
menu
item.
-activeborderwidth => amount Sets the
width of the edges of the active
-activeforeground =>
item's border.
color
menu
Sets the color of the text in the active
-background =>
menu
item.
color
Sets the color of the
background of the
entire
menu.
-borderwidth => amount Sets the
width of the menu's edge.
-cursor => cursomame Sets the cursor displayed
-disabledforeground =>
when
the
mouse
cursor
is
over the menu.
color
Sets the color of the text of
any disabled menu items.
-font => font Sets the font of the text displayed in the
menu.
-foregro\and => color Sets the color of the text in the
-menuitems => Defines a
list
menu.
list
of items to create in the menu.
-postcoitimand => callback Sets the callback that
-relief => 'flat'
-selectcolor =>
invoked before the
'groove'
|
Sets the relief of the
is
'raised'
|
is
posted to the screen.
'ridge'
|
'sunken'
edges of the menu.
color
Sets the color of the selection
-takef ocus =>
|
menu
|
1
|
box
in
checkbutton or radiobutton items.
undef
Controls the ability to use the keyboard to traverse the menu. Default
-tearoff =>
|
1
Determines whether or not the item. Default
is 0.
is 1.
menu
will contain the tear-off item as the first
240
Chapter 11: Menus
Menu
Style
The edges of the menu default to 'raised' with a -borderwidth of 2. This makes the menu look like a large button with multiple items of text listed in it. We can change the look of the menu edges by using the -relief option: -relief => 'flat'
The menus screen. The
'groove'
in Figure 11-16
actual
|
'raised'
|
'ridge'
'sunken'
|
were created and then torn
menu edge
inside the
is
off so they are left
window manager's
on the
decoration.
^ Ktenu wAidge
Menu
Itemi
Itemi
itemi
itonl
Itemi
ItemZ
ItemZ
itemZ
ItomZ
ItemZ
Item 3
Item 3
1
Items
Items
Items
Item 4
Item 4
1
item 4
Item 4
Item 4
Menu
1
Menu
w/flat
\Aetm
w/ltrised
Figure 11-16. Different relief options with
The width of the menu's edges the -borderwidth option:
w^roove
menu
w/sia)i(en
widget
(regardless of the
-relief) are changed by using
Changing the -borderwidth always makes the
different relief types stand out
-borderwidth => amount
more, as shown
1
Menu w/groove
Menu w/k^sed
MenuwAWge
Memiwlsunten
Itemi
1
Itemi
Itemi
Itmil
Itemi
ItemZ
1
ItemZ
ItemZ
ItemZ
ItemZ
Item 3
1
Item3
Item 3
Items
Items
Item 4
1
Itan4
Item 4
It«n4
Item 4
Menu
Figure 11-1
in Figure 11-17.
7.
w/flat
Menus
fi
with different relief options
The -activebordeirwidth option mouse cursor over it):
and -borderwidth
affects the active
menu
set to
4
item (the one with the
-activeborderwidth => amount
Menu Fonts and Cursors The
font of the text displayed in the entire
option: -font => font
menu
is
controlled with the
-font
The Menu Widget
241
shows
Figure 11-18
a
menu
with a different
"lucidasans-14". Fonts
font,
can be used for the value of -font were covered
in
Chapter
that
3.
Menu w/groove Item 1 Item 2
Item 3 Item 4 Figure 11-18.
To change
Menu
with a different font
the cursor displayed
when
the
mouse
cursor
is
over a
menu
widget,
use the -cursor option: -cursor => curso2ni.ame
The
default cursor for a
sor.
The
arrow
menu widget is different than the window's menu is 'arrow', whereas the window
default cursor for a
that points the other
is
an
way.
Calling a Subroutine Before Displaying the menu
Before displaying the
default cur-
cursor
(via the
post command
Menu
or a menubutton),
use the -postcoinmand option to specify a subroutine to
you can
call:
-postconimand => callback
The form
for the
callback
(described in Chapter
update the
state of
2).
each
is
the
same
One of the menu item
as
best uses of the -postcoinmand option if
needed. Here
menubutton widget but uses -postcoinmand before
it
is
the one used in a button widget
to
is
an example
perform an update of the
drawn:
Create the menubutton $menub = $inw->Menubutton(-text => "File", -tearoff => 0, -menuitems => [[ 'coinmand' => "Open", -command => \ &do_some thing 'command' => "Save", -command => \ &do_some thing 'command' => "Close", -command => \&do_something]
#
]
[
]
[
[
)
'command' => "Exit",
-command => sub
{
exit }]]
->pack
A flag we use to see if the document has been saved yet. $unsaved = 0;
#
We have to wait \intil after we've created the menubutton to access the menu widget part of it: $meniib->menu() ->configure(-postcommand => \&update_menu)
# #
is
to
that uses a
menu
.
242
Chapter
1 1:
Menus
This looks at some flags in our program and determines if the items should be updated or not sub update_menu { # #
($unsaved)
if
{
$menub->menu->entryconfigure(l, -state => "normal"); else { $menub->menu->entryconfigure (1, -state => "disabled");
}
} }
Specifying Menu Items The -menui terns option allows you to create the menu and the menu items at the same time. The format for doing so is the same as the format for the menubutton's -menuitems option. There
no Addltems method for a menu widget. The Addl terns method is only menubutton widget. You can use either the -menuitems option add method with a menu widget, add is described in the next section.
is
available with the
or the
Menu Indexes Like entry and text widgets,
menu
widgets have their
own
indexing scheme, as
follows.
n
The items in a menu are numbered from to is the first item at the top of the menu, and n is the last item in the menu. (The tear-off item in a menu counts as index if it is present. Use -tearof f => to turn it off.) /t;
"active"
The menu item
that
lighted). If there are '
none
is
currently active (the
no menu items
active,
mouse
is
over
it
and
it
is
high-
then "active" means the same as
'
"end"
The
last
menu
item in the menu.
in the
menu, then
window. This form of index
specification
If
there are
no items
'end' means the same as "none".
"last" Another way to say "end".
"none"
No
item.
The number
is
a
y coordinate
will resolve to the
same
as 0.
menu
in the
item closest to the y coordinate.
"@0" means the
The Menu Widget
243
"pattern"
The
pattern
ing with 0)
There
is
text to
matches
it
aren't really that
are probably
match the menu items is
against.
first
menu
item
(start-
used.
many menu widget methods. The most
entiryconfigure and delete because
than you'll use the others. Remember,
can invoke the
The
menu widget method
if
you
use them more often menubutton widget, you
you'll
are using a
directly
important methods
by using $inenubutton->menu->
method ().
Menu Widget
Configuring the
The cget method returns the current value of an option. It only affects the options for the entire menu; there is an entrycget method that will return information about specific menu items. Both the configure and cget methods are discussed in detail in Appendix A.
Configuring Menu Items The entrycget method queries
a specific
menu
item and returns the information
about that configuration option: $menu->entrYcget (index,
-option);
The index determines which menu item entrycget affects. Any of the options that can be sent with the add method (covered in the following section) are valid. The entryconf igure method returns or alters the configuration options of the menu item at index just as configure does for the entire menu widget: $menu->entryconfig\ire( index,
You can
specify
no options
[-option,
for that
...]);
to get the current configurations for
You can specify a single option to get the value index. You can also specify multiple option/value pairs
index.
at that
value,
all
of the options
of only that option to set the values of
those options for that index.
Adding Items -menuitems option, you can use the add method to add items menu. The first argument to add is the type of menu item to be added. It should be one of the following: "contmand", "radiobutton", "checkbutton", "separator", or "cascade". Here is a usage statement: In addition to the
to the
end of
a
$menu->add( type
[
,
options...
]
)
;
The options that affect each menu item are the same as those for the -menuitems option: -activebackgroimd, -activeforeground, -accelerator,
;
;
;
;
,
244
Chapter 11: Menus
-background, -bitmap, -coinmand, -font, -foreground, -image, -indicatoron, -label, -menu, -offvalue, -onvalue, -selectcolor, -selectimage, -state, -underline, -value, and -variable.
The
results of the following
two code snippets
are identical:
Snippet 1 Using add for menu items $menu = $mw->Menu; $menu->add( "command" -label => "Open", -command -> \&open_file) $menu->add( "command" -label => "Close", -command => \&close_file)
#
#
,
*
,
#Snippet 2 # Sending a list intially using -menuitems option $menu = $mw->Menu( -menuitems => ["command" => "Open", -command => \&open_f ile] [
["command" => "Close", -command => \&close_file] ]); call to add will add another item to the end of the menu. To add a somewhere other than the end of the menu, see the insert method
Each additional
menu
item to
(covered in the next section). Instead of
shown on able need
-text or -textvariable the
option.
menu If
to use the
Inserting
item.
options,
You should
we
notice that
use -label to indicate the text
we
-labelvarimenu item, you will
don't have a
you need to change the text shown in the entryconf igure method (discussed later in
this chapter).
Menu Items
The insert method works exactly the same way the add method works, except the new menu item will be inserted right before the menu item at index. You cannot insert a
menu
always be the
first
item before the tear-off
is
item because the tear-off must
item in the menu:
$menu->insert (index,
Here
menu
type
[,
aptior^
...
]
)
;
an example:
$menu->insert "end"
"radiobutton" -label=>"red"
(
Deleting
,
,
Menu Items
To remove menu
items from your menu, use the
$menu->delete index) (
# or.
)
;
.
$menu->delete indexl (
,
inde?c2)
delete method:
The
Menu
You can
Widget
delete
245^
one item by specifying only one index. You can delete more than a range of indexes. Here are some examples:
one by specifying
$menu->delete( 'last' 'end'); $menu->delete $menu->delete( "Open" )
(
)
deletes the last menu item deletes every menu item (except tearoff) deletes the item that matches "Open"
#
;
#
,
#
;
Invoking Menu Items The invoke method will try to invoke you clicked on it with the mouse):
the
menu
item
at
the specified index (as
if
$menu->invoke (index)
The
specific result of the invocation
The
index.
depends on what type of menu item
from any -coinmand callback associated with
result
that
is
at
index will be
returned by the invoke method. $menu->invoke "red" (
)
Determining Item Type The type method
returns a string that indicates the type of
menu
item located
at
index.
$type = $menu- >type( index)
;
The string returned will be one of the following: "command", "radiobutton", "checkbutton", "cascade", "separator", or "tearoff". $type = $menu->type(0)
;
#
look at index
Translating Index Values The index method
returns the numerical index of the
$menu->index( index)
menu
item
at index.
;
The code $menu->index( 'end' returns 9 if there are 10 menu items in the menu. The code $menu->index("Open" returns the index number of the menu )
)
item that matches "Open".
Displaying a If
you
Menu
menubutton widget to display your menu, you need You can use the post method or the Popup method.
aren't using a
display
it.
a
way
to
The post method displays the menu for you, but the menu only goes away after you select a menu item or specifically call unpost. The Popup displays the menu only while the mouse button is depressed.
;
;
;
246
Chapter 11: Menus
The post method requires x and y coordinates to tell it where to place the menu on the screen. Typically, you call it wherever the user clicked (unless you want it to display in the same place all the time). Here is an example that displays the menu when the user clicks the right mouse button in a listbox: Create a menu with two items for our exairple $menu = $mw->Menu(-tearof f => 0, -menuitems => [['command' => "A"], command' => "B" $lb = $mw->Listbox ->pack # create a binding on the listbox that will display our menu # when we click with the right mouse button $lb->bind("", \&display_menu( Ev('X'), Ev('Y')]); #
[
'
]
]
)
)
(
( )
[
sub display_menu ITT^
($lb,
$x,
)
,
{
$y)
= @_;
$menu->post $x, $y) (
;
}
I
created a simple
menu
some users mouse button to
we can get through the example quickly. I removed menu because I don't like tear-off menus all over the so keep this in mind). The bind is where I mapped the
so
the tear-off item from the
place (but
do,
right
display the menu.
used Ev( "X"
I
)
and Ev( "Y"
to
)
send the
more post with
coordinates of the location in which the user clicked (see Chapter 14 for
information about Ev("X") and Ev("Y")). The subroutine simply
calls
the correct arguments.
The menu will be displayed even when the user lets go of will unpost itself automatically when the user selects a menu Another way to display a
menu
is
played only while the user holds
mouse
the
button.
mouse
button.
It
item.
Popup. This causes the
to use
down
the
To
menu to be dismenu item,
select a
you must click down the mouse button, slide the cursor to the desired item, and then let go of the mouse button. The Popup method can be called with no arguments or with one or two options. The options that affect Popup are -popover and -popanchor. Calling Popup $menu->Popup
like this
( )
menu at the very center recommend that you at least use
displays the
of your entire screen. This
so
the
I
will take either the string
"cursor" or
a
-popover
isn't
very useful,
The -popover option The menu will be cen-
option.
widget reference.
tered under the cursor or centered over the widget; for example: $menu->Popup( -popover => "cursor"); $menu->Popup( -popover => $button) $menu->Popup( -popover => $listbox) ;
;
Notice that
we
#
# #
Center menu under cursor Center menu over $button Center menu over $listbox
are not using the syntax \$listbox. Because our scalars already
contain a reference to a widget,
we
don't
need
to reference
it
again.
The Menu Widget
247
The second option, -popanchor, affects how the menu gets positioned relative to the -popover argument (or the entire screen if -popover isn't specified). The -popanchor option takes a string argument where the string is one of the following: "nw", "ne", "sw", or "se". For instance, if you would like to display the menu's upper-left corner where the user clicks, use this code: $menu->Popup( -popover => "cursor", -popanchor => "nw");
This
how
is
I
the complete
menus
like to create right-click
example
in the "Right-Click
that are associated with widgets.
Menu
See
Example."
Displaying a Cascading Menu If
your
play
menu
menu
has a cascading
associated with
it,
use postcascade to
dis-
it:
$menu->postcascade( index)
The postcascade method cade
menu
index other
will
unpost any other submenu and then post any cas-
menu
associated with the
item located
at
index.
If
the
menu
not a cascade item type, then the only thing that happens
is
submenus
item
that
is
are unposted.
$menu->postcascade
Undisplaying a
(
suianenu"
"
)
;
Menu
you have displayed the menu on the screen using post, you can use unpost remove it from the screen: If
$menu->unpost
to
( )
unmap $menu from the window. If any cascaded menus be unmapped as well.
This will
at
any
of this
menu
are
also displayed, they will
Getting the Position of an Item The Yposition method topmost pixel of the
returns a decimal string that gives the
menu
item
at
y coordinate of the
index:
$location = $menu->Yposition index) (
Right-Click
Menu Example
There are times appears
A
you'll
when you
canvas
is
want
right-click
to use a right-click
on
menu, which
a perfect place to use a right-click
menu; there
ferent possible actions to take that associating different
of objects in the canvas
is
is
a
menu
that
a particular widget or location in the application.
advantageous.
are often so
menus with
many
dif-
different types
;
248
To
Chapter 11: Menus
create a right-click
desired,
menu widget, add the items to it as make the items perform useful tasks. To right-clicks on the desired object, use the bind
menu, simply
create a
and use the -coinmand option
menu when
display the
the user
to
command: $object->bind( ""
You can use
a right-click
,
menu
sub
{
$menu->Popup -popover => 'cursor'); (
}
)
with a listbox to allow users to delete or edit the
currently selected item.
Optionmenu Widget JiQm>mmii -H^i optionmenu
-
|
The optionmenu
cally sets the
a specific implementation of a
is
g^^ jj^^ difference
between the two
-indicatoron option
handles the display of the
menu
to
1,
that the
removes the
in a slightly different
You can use an optionmenu when you want want
several different items but don't
or with several radiobuttons.
is
To add
to
tear-off
menu
item,
and
way.
to give the user a choice
between
waste space with a listbox and scrollbar
items, use the
-menui terns or the other methods
menubutton wid-
optionmenu automati-
that
-options command
allowed you to add to a
instead of
menu
or
menubutton.
Creating
and Configuring an Optionmenu
The optionmenu
is
Optionmenu method:
created by using the
$optioninenu = $inw->Optionmenu
(
...
)
;
with a menubutton widget are also available for optionmenu widget. The following options are specific to the optionmenu:
All the options that are available
the
-textvariable, -options, -variable, and -coinmand.
-menuitems option or other methods to add items to an optionmenu, use the -options option. It takes an anonymous list that can contain either strings or other anonymous lists. The idea behind an optionmenu is to select one item from a list of items. The text displayed is the currently selected menu item. The -textvariable option determines where the displayed text is stored. There is also a -variable option, which you can use to store a value that is different than the one shown on the menu. Specify the displayed value and the stored value by using the -options option. If the displayed value is the same as Instead of using a
the stored value, use a simple
-options =>
[1,
2,
3,
4,
list:
5,
6],
-textvariable => $nvmiber
249
Optionmenu Widget
To
store a value other than the
-options => [["one",!],
one shown, use
["two", 2],
this
code:
["three", 3], ["six",6]],
["four", 4], ["five", 5], -textvariable => $di splayed, -variable => $number
words are displayed
In this example, the written
$displayed), and the stored value
(in
in the
menu
(and are stored in
$nuinber) are the integers. The nondis-
played value can be any scalar value.
The
-cortiinand option assigns a callback that will
be executed when a selection
has been made. The default arguments to the callback are the variables assigned with -textvariable and then -variable
(if it exists).
You can use
callbacks to
perform an action based on the item selected from the optionmenu. Here's a complete script that will allow you to see most of the optionmenu's useful features: #
!
/usr/bin/perl -w
use Tk; $inw =
MainWindow->new;
$ir[w->title "Optionmenu" (
)
;
$display_var = "ten"; $niw->Optionmenu( -command => sub { print "ARGS: @_\n"; print "in optioranenuNn" -textvariable => \$display_var, -variable => \$stored_var, -options => [["ten", 10],
;
},
"twenty", 20] ["thirty ",30]] [
)
->pack
( )
MainLoop; It's
a
good
idea to also create a label widget so the user
menu's purpose (shown
is
aware of the option-
in Figure 11-19).
Figure 11-19. Optionmenu with a label widget to the
left
The only methods available with the optionmenu are the cget and configure methods. The cget method returns information about an option in the optionmenu. The configure method can get or set option values for the optionmenu widget. Both cget and configure are covered in detail in Appendix A.
Chapter 11: Menus
250
Fun Things Create one click
on
get will
menu
to Try that has
a widget, the
two
menu
items: Disabled
will
pop
up.
If
and delete all
select
be disabled. Selecting 'Normal' reenables
Create an application with two menubuttons.
Take
and Normal.
you
different types of
menu
menu, with an
right-
that
wid-
that widget.
Have
the items
on the
first
add
items to the second menu.
the fun things from previous chapters
least a File
When you
'Disabled',
Exit item.
Be
and add menus
inventive!
to them.
Add
at
Frames
A
frame widget
is
other widgets to
a boring widget at
sit.
This doesn't
first
seem
glance. All
it
important, but
it
does is.
is
provide a place for
The geometry managers 2, Geometry Manage-
provided with Perl/Tk have some limitations (see Chapter
we
ment), and
can use frames to help them do
our example geometry manager throughout
most popular, but remember geometry managers as
A
this
their jobs better. We'll
chapter because
that the basic rules for using a
it
use
seems
pack to
as
be the
frame apply to the other
well.
is to contain other widgets, accommodating the size of the you don't have any widgets packed into the frame, you won't the widgets inside the frame are resized for any reason, the frame
frame widget's job
widgets within. see the frame.
If
If
will try to resize as well (either larger or smaller).*
Creating a
Frame
Use the parent widget of the frame $frame = $parent->Fraine
(
[
to invoke the
option => value,
Frame
( )
method:
])->pack();
...
MainWindow, a toplevel, or another frame widget.t After the frame is created, it can become a parent to other widgets. You must have created the frame but not necessarily packed it on the screen for it to be the parent
The $parent can be
a
*
You can change
t
Technically, any widget can be a parent of another widget, but
comes
this
behavior by using packPropagate
( )
or
gridPropagate I
like to
( )
make my
life
easier
when
it
widget inside the window. If I made a frame the child of a $button, I wouldn't be inside the button. I would then have to use the -in option with pack, confusing myself
to placing the
able to pack
it
even
Keep
further.
it
simple,
and
you'll
be much happier.
251
.
252
Chapter 12: Frames
Keep in mind that, even if you pack other widgets inside your you don't pack the frame as well, the other widgets won't show on the
of other widgets. frame,
if
screen. Just as with
method
all
the other widgets in Perl/Tk, the options specified in the
change
will
how
window. There
the frame looks inside the
options available with the frame widget, and they aren't complicated section covers
-background =>
at all.
This
and what they do.
the options
all
Frame few
are
color
Sets the color of the frame's
background area (there
is
no foreground
area).
-borderwidth => amount Sets the
width of the frame's edges. Default
is 0.
-class => classname Indicates the class associated with the frame in the option database. This
option can actually be used on any widget, not
-colormap => "new" Specifies
whether to use
TkS.O only.
|
frame.
$window
|
the application. Default
-container =>
just a
a
is
new colormap
or share one with another widget in
undef
1
If true,
this
frame
will
when
the
be used to contain another embedded
application.
-c\irsor =>
cursomame
Changes the cursor
to use
mouse
pointer
is
over the frame.
-height => amount Sets the starting height of the
-highlightbackgroimd =>
frame
in a valid screen distance.
color
Sets the color the highlight rectangle should
be when the frame does not have
keyboard focus.
-highlightcolor =>
color
Sets the color the highlight rectangle should
keyboard focus. Default color
is
be when the frame does have the
black.
-highlightthickness => amount Sets the thickness of the highlight rectangle. Default
-label => labelstring Adds a label to the Frame with the
-labelPack => Specifies
[
pack options
pack options
text "labelstring".
]
for the label.
is 0.
Frame Style
253
-labelVariable => \$variable Specifies a variable that contains the text for the label.
-relief => 'flat' 'groove' 'raised' 'ridge' 'sunken' 'solid' Changes the appearance of the edges of the widget. Default is flat |
|
|
|
|
'
'
-takefocus =>
-visual =>
When
|
1
|
undef
whether the frame should take the focus. Default
Specifies
"
is 0.
type #"
used on an
X Windows
system, changes the depth of colors available to
your application. Does nothing on Win32 systems.
-width => amount Sets the starting
Frame
width of the frame
in a valid
screen distance.
Style
you can use the -relief and -borderwidth options to change how the edges of a frame widget are drawn. The default -relief is flat and the default -borderwidth is 0. If you want the frame to have any edges at all, make sure you change -borderwidth to something higher than 0. Unless you put something in a frame, you'll never see it. So, for the examples in
As with
all
widgets,
'
'
,
Figure 12-1,
I
have inserted a label widget and an entry widget
of that frame. Note that
I
that state the relief
by using Label
actually created a label widget
and did
( )
not use the -label option (see the next section).
^ gd,,-,v:,,:»m^Pii^rtes
Frame
^Jiia
—_—
exaori^tes
-
J
iiai:
flat:
»
—__™.
...™—_™.
.
groove:
graove:
| j
raised:
raised: ridge:
sunken:
\
1
ridge:
i
|
|
^
sunken:
^
Figure 12-1. Different relief values forframes; borderwidth of 2
window.
which frame is "groove" to my
of 5
is a great way to find out where your frame is you have a complicated window, it's confusing to remember where. I'll often add -borderwidth => -relief => 5, Frame command to find that frame in the window.
Using -relief and -borderwidth in the
and borderwidth
If
254
Chapter 12: Frames
Adding a Label
a Frame
to
With Perl/Tk, you can add a label to your frame by using the -label option, which takes a text string as an argument: $inw->Fraine( -label =>
"My Frame:
")
->pack;
configure label in frame later $frame->configure( -label => "My Frame:
#
By
:
default, the label
placed
is
(see Figure 12-2). Again,
I
at the
")
top of the frame, centered across the width
put something in the frame so you can see the frame as
well as the item in the frame. In this case,
options in the frame.
-borderwidth =>
I
->pack;
I
placed a button with the default pack
also created the frame with
=>
-relief
'groove',
you can see the edge.
2 options so
-J B'aufne exsn^ite
^
jj
Frame Label !
Figure 12-2.
Frame with
You can change option.
It
in
frame
label in default position
by using the -labelPack where the array contains any
the location of the label inside the frame
anonymous
takes an
pack options
Button
array as an argument,
for the label:
-labelPack =>
-side => 'left', -anchor => 'w']
[
Be careful to notice that this option has an uppercase letter in it. If you try to use -labelPack without the capital "P," you'll get a compilation error. Also notice that there isn't a -labelGrid option available. You must use pack() to put widgets inside your frame if you are going to use the -label option. If you don't, bad things happen (your application might not run at all). Instead of using a static text string with your frame's label, you can assign a variable by using the
-labelVariable option
(again, notice the capital V):
-labelVariable => \$label_text
When you change frame
The
will
the contents of the variable $label_text, the label in the
change as
instant
well.
you use the -label or -labelVariable option,
You can use these $frame->configure( ...
placed inside the frame. call
or later with
placed above
all
a label
options either in the )
other widgets inside the frame.
.
If
you use them
is
created and
initial
later,
Frame ()
the label
is
255
Colormap Complications
Frames Aren Y Interactive The frame widget itself is not interactive; by default, it can't accept input from the user. The widgets inside it can, but the frame cannot. As always, the focus ability is controlled by the -take focus option: -takefocus =>
With a frame widget, the user
it
set to 0. If for
is
on your frame, you
will
need
to
some reason you need to get input from => 1. it to -takefocus
change
Colormap Com^plications when you you'll
are running several applications at
sometimes notice
that the colors
once and you
become
an application to the browser, the colors
corrupted.
start a
web
When you
browser,
switch from
your other applications suddenly
in
you switch back from your browser to an application, the browser colors change. This is happening because the web browser is a color hog. It has requested more colors than the operating system can allocate at once. The OS must alter the colormap between applications to allow the active application to change.
If
use the colors
way
to
it
wants to use. The colormap simply gives the operating system a
keep track of
who
is
using which colors.
Perl/Tk applications can have
make each button
many
—you
colors too
can get color-happy and
a different color of the rainbow. This can cause problems
there are other applications running that
want
applications are color hogs, Perl/Tk will switch to black-and-white
don't like
behavior,
this
-colormap
you can use the -colormap option
word "new"
takes either the
given "new",
it
will create
its
own
that
is
the
-visual
or a reference to another
colormap.
When
for
If
you
override
window.
it.
If
you use -colormap with is
one
catch,
option.
The -visual option takes number;
mode.
to
another window, the two windows will share the colormap. But there
and
if
a lot of different colors too. If other
as
an argument a
string that contains a
keyword and
a
example:
-visual => "staticgrey 2"
The keyword can be any one of the following: staticgrey, greyscale, staticcolor, pseudocolor, truecolor, or directcolor. The number indicates the depth of color used (2 = black/white).
When you
use -colornnap to share the colormap between two windows, the -visual option for both must be the same. This means that -visual must be imdef for both (the default) or it must have the same value. Neither -colormap nor -visual can be altered by using the configure method.
256
Chapter 12: Frames
You
will see
both -colorroap and -visual options
gets, also.
We
est, you'll
probably never use either option
covered
it
here
first
because
this is
in
Chapter
where we see
13,
Toplevel Wid-
it first.
To be hon-
in either widget.
The Magical Class Option You can
force your frame to be in another class (besides frame)
option. Simply give
it
a string that
is
by using the -class
a unique class identifier;
-class => "I^frame"
For more information on using classes (and what good they can do you), see
Chapter
13-
Frame Methods The only methods These are described
available with the frame widget are in detail in
Appendix
cget and configure.
A, Configuring Widgets with configure
and cget.
Fun Things
to Try
When you
use the Scrolled method, you are using frames without even knowThe newly scrolled widget is placed inside a frame with its scrollbars so that behaves as one contained widget. Here are some other ways you can use
ing it
it.
frames: •
Create several lines of labels with entry widgets. Each
own •
frame so
it
will
look
'line'
needs
to
be
in
its
right.
Place an image along one side of your application window. Put the widgets in a
frame (on the
left
or
on the
right)
and place the image on the other side of
them. •
Place a scrolled listbox in your application window, a frame containing three
buttons (OK, Cancel, Apply) along the bottom of the window, and a frame
along the right containing two buttons (Delete, Add) that manipulate the
list-
box. By using frames, you can keep the buttons that belong together in one area
instead
purpose.
of grouping them with other buttons that serve a different
Toplevel Widgets
Any Perl/Tk application includes at least one toplevel widget. When you call the new method from the MainWindow class, you are creating a toplevel widget withYou can create other toplevel widgets to be used in your out even knowing application in addition to the MainWindow toplevel widget. The MainWindow is Other special because it automatically displays when you call MainLoop toplevel widgets in your program must be explicitly displayed somewhere in the it.
{ )
.
code.
Here are some examples of
how you
can use toplevel widgets:
•
Display informational text with a Close button.*
•
Provide data gathering that
triggered
is
by something the user does
(for
exam-
ple, clicking a button).
All toplevel
widgets have the same behavior: Each has decoration that
tent with the
system on which your application
is
run.
is
consis-
Each toplevel can contain
other widgets and/or multiple groups of widgets (for example, they can be
grouped
The
in a
frame widget).
rest of the
chapter will cover
how
to use toplevel widgets
and what options
allow you to change their behavior.
Creating a Toplevel Widget To create a toplevel, call Toplevel from the desired MainWindow widget (you already know that to create
Look
at
Tk::Dialog.
It is
designed to do
this
and uses
parent widget, usually the a
main window, you must
a toplevel widget.
257
;
;
;
;
258
Chapter 13: Toplevel Widgets
use MainWindow->new{)). The returned item
place items within
is
a reference to the toplevel wid-
allows you to configure the widget,
get; the reference
it.
Here
(
)
it,
and
;
$inw->Button(-text => "Toplevel",
MainLoop sub do_toplevel { if (! Exists ($tl))
methods on
a simple example:
is
use Tk; $raw = MainWindow->new; $inw->title "MainWindow"
call
-command => \&do_toplevel) ->pack()
;
{
$tl = $inw->Toplevel ; $tl->title( "Toplevel") $tl->Button(-text => "Close", { )
}
-command => sub else { $tl->deiconify() $tl->raise()
{
$tl->withdraw
)
}
->pack;
}
}
When you
run
program, clicking on the Toplevel button in the main
this
creates the toplevel widget
toplevel from view.
show want
it
You need
it
needs
to)
and displays
show something
the Close button
is
it.
window
Clicking Close hides the
to test for the existence of the toplevel before
because you don't want to re-create
to try to
When
(if
it
if it
you
already exists and you don't
that doesn't exist.
clicked, the toplevel
is
withdrawn.
It still
exists;
it
is just
not visible to the user. This saves time the next time around by redisplaying the
same window. You can also use withdraw if you don't want to show the toplevel while you are filling it with widgets. Simply use the withdraw method, place the interior widgets, and then redisplay the widget by using deiconify and raise. These options can be specified
in the call to
Toplevel
or by using the
configure
method.
-background => Sets the
color
background color of the toplevel widget. Note
may be hidden by
widgets placed in the toplevel
if
that the
the toplevel
is
background completely
covered by widgets.
-borderTvidth => amount Sets the
width of the border around the toplevel. Default
is 0.
-class => classname Sets the classname
used with the option database
for this toplevel widget.
259
Creating a Toplevel Widget
-colormap => "new" Specifies whether
$window
|
to use a
the application. Default
-container => TkS.O only.
-use
|
is
new colormap
or share one with another widget in
undef
1
If true, this
window
will contain
an embedded application (see the
option).
-cursor => cursomame Sets the type of cursor
used over the toplevel widget.
-height => amount Sets the height of the toplevel.
-highlightbackground =>
color
Sets the color the highlight rectangle
should be
when
the toplevel does not
have focus.
-highlightcolor =>
color
Sets the color the highlight rectangle should
be when the toplevel does have
focus.
-highlightthickness => amount Sets the thickness of the highlight rectangle. Default
is 0.
-menu => $inenu TkS.O only. Indicates that the toplevel uses the
menu
in
$menu
across the top
of the window.
-relief => 'flat' 'groove' 'raised' 'ridge' 'sunken' 'solid' Changes the appearance of the edges of the toplevel. Default is flat |
|
|
|
|
'
'
-screen => screenname Sets the screen on which
to place the toplevel.
Cannot be changed by config-
ure method.
-takefocus => Determines
if
|
1
|
undef
toplevel can have keyboard focus. Default
is 0,
meaning
it
can-
not have keyboard focus.
-use => $windowid TkS.O only. $windowid must contain a hex string of the window the toplevel. The -container option must have the value 1
to
embed
in
to use this
option.
-visual =>
When
"
type #"
used on an
X Window
System, changes the depth of colors available to
your application. Does nothing on Win32 systems.
-width => amount Sets the desired
width of the toplevel.
260
Chapter 13: Toplevel Widgets
Toplevel Methods The methods
available with the toplevel widget are listed
lowing sections
Window as seen many
(it is
important to note that
all
and explained
in the fol-
of these methods apply to a Main-
Main Window is just a specialized toplevel widget). You haven't them before because toplevel is a different sort of widget than the others covered so far in this book. Also keep in mind that a lot of these methods were designed originally for use with a Unix windowing environment, and quite a few of them will state "No effect in Win32 system." Many of these functions serve no useful purpose to the typical ordinary Perl/Tk application, but I'll document them here for thoroughness. well; a
of
methods here
Several of the like
with If
window manager properties, which
alter
often look
WM_PROPERTY_THING. These properties are also traditionally associated the X Window system on Unix, but some still apply in Win32 systems as well.
a specific
method doesn't say anything about which system it applies to, it If it only applies to one or the other (or only half-works in one
apply to both.
will
sys-
tem), this will be mentioned as well.
Configuring a Toplevel Both cget and configure methods are used to toplevel widget. See
Appendix A
for
more
set
and get option values
detailed information
on how
for a
to
use
these methods.
Sizing a Toplevel You can use
the
geometry method
geometry string determines the
The geometry glance,
it
geometry -^=7
is
string
is
a
geometry
window on
string.
Here
is
A
the screen.
concept that originated on Unix systems, and
a
a bit cryptic.
to define or retrieve a
and placement of
size
at first
a regular expression that describes a complete
string:
(\d+x\d+) ?([+-] \d+ [+-] \d+) ?$
The equal (\d+x\d+)
sign can be omitted completely (and usually is
the width
and height
(in that order)
is).
The
first
portion
separated by an x. Both width
by default and in grid units if the window is gridded with the grid method (described later). The last portion of the geometry string represents the x and y coordinates of the location in which the toplevel should be and height are specified
in pixels
placed on the screen. Both x and y are always in pixels. Here are a few examples of
what some geometry 300x300 300x450 300x450+0+0 300x450-0-0
# # # #
strings
look
like:
width and height both = 300 width = 300, height = 450 width - 300, height = 450 placed in upper left comer width = 300, height = 450 placed in lower right comer
261
Toplevel Methods
300x450+10+10
width = 300, height = 450 placed 10 pixels out from upper left comer window is 'natural' size, placed in upper left comer
#
#
+0+0
#
When geometry
no arguments, the current geometry string is returned. You can also specify a new geometry by using geometry with the new geometry string as the argument. To set the size and position of the window immediately, you would do this: is
called with
MainWindow->new(
$inw =
)
;
$ir[w->geometry( "300x450+0+0")
;
you specify only the width and height, the placement of the window is determined by the window manager. If you specify only the positioning, then the size of the window will be determined by the widgets placed within the toplevel, but the window will be placed at those x and y coordinates. If
You can
force the
empty geometry
window back
to
its
natural size
by
calling
geometry
(
)
with an
string:
$toplevel->geometry
(
" "
)
Maximum Size You can use maxsize
to restrict the largest size of the
window.
It
takes
two
inte-
gers as arguments, as follows:
$toplevel->maxsize(300, 300) If
you
call
maxsize without any arguments,
with two items in
empty
it
an empty
representing the current values. Calling
string or a
list
maxsize with two
strings cancels the limitation.
Minimum
Size
You can
also restrict the smallest size of the
dow
always be
will
at least
and height
eliminate the
minimum
using minsize. The win-
;
minsize without arguments
the width
window by
the size specified:
$toplevel->minsize(100,100) Calling
you'll get
an empty string or a list containing minsize with two empty strings will
will return
respectively. Calling size restriction.
Limiting Resizing You can
control whether a
window can be
resized in width and/or height
using resizable: $toplevel->resizable 1 ($canwidth, $canheight) = $toplevel->resizable() (
,
)
;
by
,
262
Chapter 13: Toplevel Widgets
means it is resizable, and means it is nonresizable in the specified you don't specify any arguments, resizable returns a list with two items. The first item is a 1 or and indicates whether the width is resizable. The second item is a 1 or and indicates whether if the height is resizable. By default, Specifying
1
direction. If
a
window
resizable in both directions.
is
Using a Size Aspect You can use
the
aspect method
window
to force the
to stay a certain
width and
height:
$toplevel->aspect
(
[
minN, minD, maxN, maxD
])
;
The aspect method does some very subtle things, and you'll probably never use it. If you do, play around with different values (starting with the example below) to get the effect you want.
When you
use the aspect method with no arguments,
no
string (if there are
constraints to the aspect of the
returns either an
it
window)
empty
or an array contain-
ing four elements: ($miriN,
$miriD,
$iTiaxN,
Using these values, you can see ($minN/$mirLD)
You can
also
= $toplevel->aspect;
$maxD)
how aspect
< width/height
aspect
(1
2,3,1); the
effect
is
on the win-
subtle.
Setting the Title You can change
the text across the top of the
window by
using the title
method: $toplevel->title("This will be the title");
Pass a string in with title and the
dow, assuming the window
is
new
title
will
currently visible.
If
appear immediately
in the
win-
you don't pass an argument with
title string is returned. For the X Window System, the default window is the name used to run the program, and the first character of name is uppercase. For Microsoft Windows, the title always starts out as
title, the current title
the
of a
Toplevel.
Showing the Toplevel The deiconify method causes ifies
it
immediately
if
the
the toplevel to
window
be displayed noniconified or deicon-
has already been displayed once.
If
the
window
263
Toplevel Methods
has been withdrawn, a $toplevel->raise() must also be done to correctly display the window.
The raise method brings the toplevel to the front of all dows in the application if you call it with no arguments: $toplevel->raise
You can
(
)
also put the toplevel in front of another toplevel:
$toplevel->raise $other_toplevel (
It is
the other toplevel win-
sometimes necessary
show up on
to
)
use both deiconify and raise to get the
window
to
the screen.
Withdrawing the Toplevel When you
window, it is a good idea to make it invisible while you with widgets. You can do so by using the withdraw method: create a
$toplevel->withdraw(
it
)
window is already visible, withdraw will make about the window until it has been deiconified. If
fill
the
the
window manager
forget
Iconifying the Toplevel The iconify method
forces the toplevel into iconified form:
$toplevel->iconify() Iconifying will not
is
not the same as withdrawing the window; withdrawing the
show an
icon on the desktop.
Specifying the Icon In the Unix
window
X Window
Bitmap
System,
when you iconify your application, it is repreYou use the iconbitiinap method to specify
sented on the screen with a bitmap. this
bitmap: $toplevel->iconbitmap() $toplevel->iconbititiap "bitmap" (
)
;
same form the -bitmap option supported by the button widget (see Chapter 3, The Basic Button). Calling iconbitmap with no arguments returns the current bitmap or an empty string. Calling iconbitmap with an empty string removes the current bitmap. It
takes a bitmap in the
On Win32
systems, the application
Tk icon and the name of Win32 system does nothing. able
is
kept in the
Start
taskbar with an unchange-
the application. Using the iconbitiinap
method on
a
;
;
;
;
;
264
Chapter 13: Toplevel Widgets
Specifying the Icon
A mask
this will
specified from a
file
X Window
only work with
or a default bitmap
name
Systems). (see
It
also takes a bitmap
-bitmap documentation
in
Where the bitmap mask has zeroes, no part of the normal icon bitmap be displayed. Where the mask has ones, normal icon bitmaps will be displayed.
Chapter will
bitmap can be specified by using the iconmask method
for the icon
(remember,
Mask
Calling string
3).
iconmask with no arguments returns the current bitmap mask or an empty no bitmap is being used. Calling iconmask with an empty string unsets
if
the mask: Scurrentinask = $toplevel->iconiTiask()
$toplevel->iconmask( "bititiapname" $toplevel->iconmask{ " ")
Setting the
displayed
empty
;
get the mask set the mask # unset the mask # #
;
Name of the Icon
The iconname method is
)
when
sets or returns the current text associated
the application
is
iconified.
You can
with the icon that
pass in a
new
string or
an
string:
$toplevel->iconname "newname" $current_name = $toplevel->iconname() (
)
you don't specify an argument at all, iconname returns the current iconname or an empty string. You can query and set the iconname on a Win32 system, but it doesn't do anything. This is a method that is used on the X Window System only. If
Setting the Icon Position The iconposition method suggests to the X Window System manager where icon should be placed on the desktop when the application is iconified: {$x, $y) - $toplevel->iconposition( $toplevel->iconposition($x, $y) If
X and y
X and
y. If
aren't specified, a
you
find
returned containing only two items, the current
iconposition with two empty the window manager is cancelled.
strings
(one for each x and
y),
Window Instead of an Icon
window) instead bitmap for an icon. Specify the widget by using the iconwindow method. To out what the current widget is, call iconwindow with no arguments (an empty
Some systems of a
)
call
the suggestion to
Using a
list is
the
(not
Win32) support the idea of using
a widget (or
265
Toplevel Methods
string
is
returned
string instead of
if
there
$widget
no associated $widget). You can specify an empty by using a widget for the icon:
is
to cancel
$currentwindow = $toplevel->iconwindow( $toplevel->iconwindow($window) $toplevel->iconwindow( " "
)
;
get set # imset #
#
)
Determining the State The state method
returns
one of three
strings:
"normal", "iconic", or "with-
drawn". $state = $toplevel->state(
The
)
string indicates the state of the
window when state
name
assigned to
returns an
called.
Name
Assigning an Application The client method
is
empty
string
if
your application doesn't have a
it.
$toplevel->client $toplevel->client "name" $naine =
);
{
(
)
To
assign a name, send a string to the
toplevel widget.
You can use
this in
client method
an .Xdefaults
file in
after
the
you
create your
X Window
System to
assign colors to your application.
Window Properties window properties: WM_DELETE_ WINDOW, WM_SAVE_YOURSELF, and WM_TAKE_FOCUS. The callback (if any) associated with each property will be invoked when the window manager recogThe protocol method
controls the following
nizes the event associated with the property:
$toplevel->protocol
(
[
property_name]
[ ,
callback
]
)
;
The WM_DELETE_WINDOW property callback is invoked when the window has been deleted by the window manager. By default, there is a callback assigned by Perl/Tk that destroys the window. If you assign a new callback, your callback will be invoked instead of the default callback. If you need to save data associated with that window, do so in the callback and then invoke $toplevel->destroy() to mimic the correct behavior afterward.
The other two
much
less
properties,
commonly
tems but not
in
WM_SAVE_YOURSELF and WM_TAKE_FOCUS, WM_TAKE_FOCUS is used in Unix
used. Eor instance,
Win32. The presence of these properties
window system you
are running.
If
your application
will
is
are sys-
dependent on the
be running on multiple
systems, don't expect these properties to always be available.
To
find out
if
they
;
266
Chapter 13: Toplevel Widgets
one
are available, assign each
application to see If
the
if
a callback that
print
is
does
a
print and
mn
the
you leave out the callback when you use protocol, the current callback
assigned to that property will be returned (or an empty string rent callback assigned).
You can remove
instead of the callback.
If
of
then
ever invoked.
all
if
there
isn't a
cur-
by sending an empty string specified, the method returns a list
the callback
neither argument
is
properties that have callbacks assigned to them.
Colormap Property The colormapwindows method This property
erty.
is
used to
the
affects
talk to the
WM_COLORMAP_WINDOWS
prop-
window manager about windows
that
have private colormaps. Using colormapwindows with no arguments returns a of windows.
The
colormap than
list
contains
windows
pass a
have
list
a different
their parents:
ilist = $toplevel->colormapiwindows
You can
(in order of priority) that
list
of
windows
( )
;
colormapwindows
to
as well:
$toplevel->colormapwindows (©list) If
you don't use
this
function at
all,
Perl/Tk will take care of everything for you,
although the order of the windows might be different.
The
Command Property
The command method (not
to
be confused with the -command option used with
most of the widgets) controls the
'WM_COMMAND
arguments, command returns a
reference:
list
$listref = $toplevel->conimand()
The
list
holds the words of the
property.
When
used with no
;
command used to start the application. Use this bit command was (which is sometimes
of code to determine what your application nothing):
$listptr = $mw->coinmand foreach (©$listptr) { print "$'_\n";
( )
;
}
You can
unset the
'WM_COMMAND
$toplevel->cornmand(
" "
)
;
property by sending an empty
string:
267
Toplevel Methods
The Focus Model The
method
f ocusmodel
the keyboard focus
$toplevel->f ocusmodel
The
default
is
changes present
controls
when
whether or not the toplevel widget
another application or [
(
"active"
in
"passive"
|
"passive", meaning
window should have
it
]
give
will
up
will give it:
)
up
The
the keyboard focus.
your application depend completely on the type of window
manager you are running your application under. under Win32 or the X Window System.
My
testing revealed
no changes
Getting the Parent of the Toplevel The frame method
returns a hexadecimal string that
is
the "ID" of the parent of
the toplevel widget: $id = $toplevel->f rame
You can
use
$widget->id
( )
( )
to get the
same ID from any widget
in
your application.
The Application Grid way back
There are a few complications with the grid method. Remember
in
Chapter 2 there was a grid there also which controlled geometry management. To resolve this
little
$iTiw->wm( 'grid'
We
must use the
we
problem, ...
,
wm
)
have to
call this
grid method
in a
funny way:
;
(stands for
window manager) method
to invoke
grid
Now that we have that cleared up, we can get into what wm( 'grid' When you tell the window to grid, you are restricting the size can
,
to the grid as defined in grid.
We
have
to
.
.
does.
)
.
be.
it
must always snap
indirectly.
The
size
the
list-
remember
box widget and the -setgrid option back in Chapter 7, The Listbox Widget. Once you use -setgrid => 1 on a listbox, you can use @list = $toplevel-> wm('grid') to determine the values used in the grid. The values I got on my system were 10, 10, 7, and 17. This means the base width and height were each 10 pixels and each grid unit incremented by 7 pixels in width and 17 pixels in height. You can change the grid size and increments by calling wm( 'grid' with new values if you desire, but if you don't, Tk manages everything quite nicely for ;
,
,
.
.
)
any of the gridded widgets.
You should for
also
know that you can new values.
each instead of
unset the grid values by using empty strings
;
;
.
268
Chapter 13: Toplevel Widgets
Being the Leader it's good to know what you're not The group method makes a widget the group leader of related windows. For each toplevel that you want to be in $widget's group, call $toplevel->group($widget) If $widget isn't specified, it will return the current group leader of $ toplevel, or it will return an empty string if $ toplevel
This
another method you'll never use, but
is
using
it
for.
.
part of a group.
isn't
You can send an empty That
is,
to
remove
string to cancel toplevel's association with that group.
a toplevel from the group, call
$toplevel->group
(
" "
)
Removing Decorations To make ders,
a
window
with none of the normal
window
decorations
and so on) you can use the overrideredirect method with a
$toplevel->overrideredirect (1)
bor-
true value:
Remove all decorations
#
;
(titlebar,
you won't be able to move the window on the screen once it is you forgot to put an exit button on it, you won't be able to quit the application gracefully (doing a CTRL-C in the window that started the script will Be
careful though;
drawn.
If
kill it).
This tion
a
is
way
loading.
is
—
make a splash screen Remember that you must
to
call
MainLoop
overrideredirect with no argument
Calling
overrideredirect again with
for
it
as
your applica-
show up
to
at all.
returns the current value (1 or 0):
$current_value = $toplevel->overrideredirect Calling
shows up
a screen that
()
value will not turn decorations back on
a
once the window has been displayed.
Who Placed the Window? When tells
the toplevel widget
the program
where
is
window manager window manager where it window manually when it
placed on the window, either the
to be or the program
tells
the
wants to be. In some cases, the user positions the
comes up. $who = $toplevel->positionfrom() $toplevel->positionfrom "program" (
When
called without argument, the
which one happened.
If
it
)
;
#
Try and force it
positionf rom method
returns information
returns the string "program", an
empty
string,
on
or a
means either the window manager or the program requested the position. If positionf rom returns the string "user", the user manually placed the window when it was created. $widget,
it
Fun Things
You can
269
to Try
try to force
gram" or "user"
which
string,
happen by calling positionf rem with the "proonly work if your window manager agrees with
will
but
it
will
you.
Who Sized It? The sizef rem method does the same thing positionf rem does except information regarding the size of the window. $who = $toplevel->sizefrom() $toplevel->sizefrom( "user" )
returns
"program" or "user"? Try and force it
#
;
#
;
it
Not a Real Window A
transient
window
is
one
that isn't quite a real
window
(such as a pull-down
menu). You can indicate to the window manager that the toplevel
menu) is related to transient method:
the pulldown
by using the
its
master (the
$toplevel->transient () $toplevel->transient ($master) $mYitiaster =
If
window
in
which
(for
it
is
example,
displayed)
;
you don't use any arguments with transient, an empty string.
it
returns either the current mas-
ter or
Review It
is
there
a is
mation
good idea too is
much
also
to use another toplevel
information to
sometimes
a
fit
good
in
widget instead of the MainWindow
one window. Using toplevels
idea.
When
design decision that you'll have to make.
You
to use
don't
to
group
infor-
an additional toplevel
want
to
if
is
a
have too many win-
dows for the user to navigate, but a well-designed application might be able to make use of one or two. For instance, the Tk module comes with a Tk::Dialog module that lets you easily display messages to the user. Check out the documentation included with the Dialog.pm file for more information on how to use it.
Fun Things
to Try
Take the Dynamic Document ate a
new
List
example from the
toplevel every time the user hits the
actually create or load a
file.)
last
chapter and
New Document
make
it
cre-
button. (Advanced:
;
Binding Events
is an event-driven programming language. You design your program respond to events generated by the program. Event sequences can be pushing a button, moving the mouse, or typing some characters with a keyboard. The relationship between the event sequence and the widget is called
Perl/Tk to
a binding.
Each widget provided with Perl/Tk has button widget changes color
when
the
invokes a callback that you specified ings,
ones
that are created
when you
own
mouse
when
it
default bindings. For example, the
pointer is
is
clicked.
create the widget
You can have your program respond
command
its
over the button and
it
These are default bind-
itself.
to additional events
by using the bind
to assign callbacks to different event sequences; the basic format
is:
$widget - >bind sequence (
In addition,
,
cal Iback)
you can override the
own
or just
from the widget to which you would
like to
default bindings
by creating your
removing them.
The bind Method To use
the
bind method, invoke
add the binding. For instance,
if
it
you want
to
add
ton, use $button->bind. In certain instances, you
270
$butmain window
a binding to a button in
would use
the
271
The bind Method
of your application: $inw->bind
(
.
.
,
)
•
There are several different
arguments you can send to bind. The following
$widget->bind() Calling
bind
list
them
explains
sets of valid
all:
;
with no arguments returns a
,
)
of bind sequences (e.g.
list
have been created
that
for that widget.
It
not
will
any of the default bindings. Here's an example:
return
$button = $mw->Button( ... $button->bind( ""
)
,
->pack; sub { ...
}
)
©bindings = $button->bind( print "Bindings for button: ©bindings \n " # would print: # Bindings for button: )
This function will return an empty string
if
no
there are
additional bindings for
that widget.
$widget->bind(5e^Mewce) ; You can determine what callback
associated with a bind sequence. Pass in
is
"") as the first argument and the currently assigned callback will be returned. Expanding the preceding example, we can use the information in ©bindings to see what callbacks are asso-
the bind sequence (for example,
ciated with them: f oreach
©bindings { print "$_ is assigned callback (
)
$button->bind($_)
",
,
"\n";
}
#
is assigned callback Tk: :Callback=CODE(0x91fdcc)
you send a bind sequence that doesn't exist for that widget, you'll simply empty string as the result. Also, if you use a sequence that is considered a default binding (for example, "" on a button widget), you'll get an empty string as well (unless you've added another binding to it If
get an
with bind). $>-wi.dgQt->bi.ndi {sequence ,
To have sequence
callback)
a callback invoked in the
bind
cussed in Chapter
3-
call. It
Here are
;
when
a
sequence happens, specify
it
after the
can be any of the valid forms for callbacks a
$button->bind( "" sub { print "Right clickedXn" } $entry->bind( "" sub { print "Hit return in entry widget\n" $button->bind " " \6cbl_addtl_action $canvas->Tk: :bind{"", \&draw_rec tangle, Ev("X"), Ev("Y") ,
)
,
(
( )
,
)
callback.
}
)
;
;
[
To remove
dis-
few examples:
a binding for a specific sequence, send an
empty
]);
string for the
;
,
272
,
,
;
Chapter 14: Binding Events
$widget->bind(/Scrolled( "Text" ->pack(-e>^and => $t2 = $inw->Scrolled( "Text") ->pack( -expand => )
$menu = $mw->Menu(-menuitems =>
-fill => 'both'); -fill => 'both'
1, 1,
)
["command" => "Search", -command => \&search_f ile] ["command" => "Search Again" -command => \&search_again]
[
],
-tearoff => 0) $mw->bind (Tk Text " " sub { $menu->Popup(-popover => 'cursor', -popanchor => "nw") } ;
:
Any
)
widgets you create inside the application would then have the search
text
menu pop up tines to
,
:
over
it.
You would have
to
do
a
little
work
in the search rou-
determine which text widget triggered the function, but you wouldn't
have to recode the same bind sequence for each
widget you create.
text
we specified the sequence ("") to be we would get a list of the current callbacks associated
In the preceding example,
bound.
If
we
didn't,
with that event sequence.
The
special tag 'all' can
application. But
you would
be
be used
careful; you'll get
first
much more
widget and
activity in
window
in the
your callback than
think!
Arguments Sent to The
to refer to every
argument
calling widget. This
the Callback
to a callback assigned with is
true
even when
bind
is
always a reference to the
you bind to a widget
class.
You can use
the
reference passed in to retrieve information about the widget from which the
sequence was invoked. Here's an example of using a single entry widget: $entry = $mw->Entry () ->pack; \&hit_retum) $entrY->bind( "" sub hit_ret\am { ,
my
($e)
= @_;
print "Entry contained: }
;
",
$e->get,
"\n";
273
Defining Event Sequences
When you
bind
use
job of determining
to
invoke a callback on an entire widget
class,
which widget was the subject of the event much
$inw->Scrolled( "Text" ->pack( -expand => $iTiw->Scrolled "Text ") ->pack( -expand => )
(
$menu = $ir(w->Menu(-menui terns =>
[
1, 1,
it
makes the
easier:
-fill => 'both'); -fill => 'both');
["command" => "Save", -command => \&save_file] ["command" => "Open", -command => \&open_file] ],
-tearoff => 0) $mw->bind(Tk: :Text, "" sub { $menu->Popup(-popover => 'cursor') sub save_file {
my ($text)
});
= ©_;
die "Couldn't open outfile for writing"; open(FH, ">outfile") "end"); print FH $text->get "1.0" close (FH) |
|
(
,
}
The
call to
bind
uses Tk: :Text as the
be applied to every
which
text
widget
cation might also to actually
is
text
clicked,
its
argument. This will cause the bind to this
example, no matter
contents will be written to "outfile".
prompt the user
do something
first
widget in the application. In
The
appli-
for a different filename at that point, allowing
it
useful.
Defining Event Sequences So
far,
and
you've seen several different event sequences
—but
haven't
I
yet
explained
Although the examples you've seen
— , ,
the
format
for
building
them.
simple,
event
may seem obvious and
sequences can get much more complicated.
The event sequence is built from an optional modifier, an event, and an optional detail. They are separated by dashes and then placed between angle brackets:
As
we
discuss
all
the possible bindings,
keep
in
mind
that
it
is
possible for
more
than one event sequence to match. The more detailed matches will invoke their callbacks
first. If
binding
is
invoked
first,
a binding has
created
on
all
been created on
a specific button,
and then another
of the buttons, the specific-button bind callback will be
and then the more general
all-button bind callback will
be invoked.
Modifiers A
same time the main event happens, holding down the Control key and clicking the mouse. The modifying
modifier
such as
is
an event
that
happens
at
the
274
Chapter 14: Binding Events
event must happen
first
in order for the entire event
pressing the Control key and then pressing the
The possible modifiers and
their
mouse
sequence to match
(e.g.,
button).
meanings are as follows:
Control
The Control key must be pressed down ).
as the
main event
happening
is
(e.g.,
Shift
The Shift key must be pressed down ).
as
the
main event happens
(e.g.,
Lock
The Caps Lock key must be pressed
to turn
on caps lock
(e.g.,
).
Alt
Causes the main event to match only while the main event happens Microsoft
Windows
users
(e.g.,
if
either of the Alt keys
should be aware that sometimes
doesn't allow the event notifier to notify applications that the
been pressed. The
left
Alt
key
is
try the right
using an
pressed
down
MS Windows left Alt
key has
normally the Alt key people use
switching between applications by using ALT-Tab.
work,
is
).
If
the
left
Alt
when
key doesn't
one before giving up. This warning also applies if you are server (e.g., Exceed) on MS Windows to access a Unix
X Window
system.
Button* where *
is 1, 2, 3, 4,
These modifiers indicate fied
or 5. You could also use that,
B# as a
shortcut.
before the rest of the event happens, the speci-
mouse-button number must be depressed. For instance,
when
if
you want
to
mouse button 1 and then mouse button (or ). The event
you can use the 3, same event would not be triggered if you clicked mouse button 3 and then mouse button 1. The events are order dependent. trigger
It
is
an event
the user clicks
not valid to use only
because, without
"Button" and the number, you are indicating
the dash
between
a modifier to another event
type.
Double
Double is a special type of modifier that indicates the main event should happen twice. Double puts a constraint on the minimum amount of time between the repetitions of the main event. Double is most often used to indicate a double-click of a
mouse
button.
is important to note that is not equivalent to . Although they sort of mean the same thing, there is no
It
275
Defining Event Sequences
time constraint with the
event.
The second means
"You clicked button 1, and then at some later point, you clicked button 1 again." The event means "You clicked button 1, and within a certain time period, you clicked button
again."
1
Triple
Similar to Double, Triple
is
another special modifier type.
main event occur three times
It
requires that the
in rapid succession.
to consider with Double and Triple modifiers is that you click five times quickly on a button, the first click would match at event, the second click would match a event, the third click would match event, and the fourth click would also match a event, and so on. This is true only if the event is defined. If only is defined, the third click would reactivate that binding instead of the binding. The timeline in Figure 14-1 shows
Another interesting thing they are cumulative.
when
If
the events are generated.
Clickl
Click2
Click4
Clicks
Single Click
1st Doubleclick
2ncl
Double Click
3rd Double Click
event generated
event generated
event generated
event generated
Figure 14-1. Cumulative double-clicking example
Meta (orM) Requires that the Meta key be pressed during the main event. The Meta key usually used
on X Window Systems
is
only.
Mod^orM* This
is
also only used
5);
use Ev( 'K'
)
on
X Window
to determine
Systems. There are several modifiers (1—
where they
on your keyboard.
are
Event Types (with Optional Details) The event portion of
the event string
is
the event
we
modifier or not (as specified in the preceding section).
event
is
triggered or generated,
it
means
callback associated with the event,
The following
is
a
list
it
are looking
When
that the event has
will
look as
if
for. It
can have a
the information says an
happened.
If
there
is
no
nothing has actually happened.
of event types and the optional details where applicable.
.
276
Chapter 14: Binding Events
ButtonPress (or Button)
A
ButtonPress happens
when
mouse button
a
pressed down. The Button
is
it's just a shorter way to write it. If you use any mouse button, but you can specify a spe-
event also refers to a ButtonPress; the event , cific
it
button by adding a
refers to
, , and so on.
detail:
ButtonRelease
A
ButtonRelease event happens
when
the
mouse button
is
released.
You can
happen based on the button being pressed down (Button or ButtonPress) and let up (ButtonRelease). You can specify a detail to indicate a different button: , , and so on. If a specific button isn't specified, any button will match the event. have
different things
Circulate
The
Circulate event
window and
is
when your
generated
the stacking order
is
application has
more than one
switched around.
Colormap
The Colormap event happens when
the colormap for the widget (usually a
toplevel) has changed.
Configure
The Configure event happens when to this one,
dow
is
be
careful;
resized,
it
a widget
can be called quite
is
configured.
often.
Configure event being generated for those widgets. ated,
it
you map
a callback
Every time the application win-
window
each widget within the
If
is
configured, resulting in a
When
the widget
is first
cre-
also generates a Configure event.
Destroy
When
the widget
fully destroy a
is
destroyed, the Destroy event
is
widget by using $widget->destroy
generated.
You can
force-
( )
Enter
The Enter event happens when the mouse cursor the widget. It is important to remember that this
enters the area occupied is
by
not the "user-presses-the-
RETURN/Enter-keyboard-key" event. Expose
The Expose event happens when
the
window has been exposed.
Focusin
When (or
the widget receives the keyboard focus because the user has tabbed to
$widget->f ecus
( )
happens
in the
it
program), the FocusIn event happens.
FocusOut
The FocusOut event
is
the opposite of FocusIn.
leaves the widget, FocusOut
is
triggered.
When
the keyboard focus
277
Defining Event Sequences
Gravity
The Gravity event happens when the widget moves because ent changed size.
the widget's par-
KeyPress (or Key)
When
a
key on the keyboard
is
pressed, the KeyPress (or Key) event
gener-
is
ated. It is possible to narrow this down to the specific key such as the "a" key by using a detail with the event: . If you want to determine which as an argument key was pressed to trigger the event, you can use Ev K (
'
'
)
with your callback: $ir[w- >bind
(
"
"
,
[
\
&check_key
,
Ev
(
'
K
'
)
]
)
;
This has the effect of sending the key symbol for the key pressed as an argu-
ment this
to
check_key. To find out which key symbols are
for
which keys, use
piece of code: use Tk; $mw = MainWindow->new; $mw->bind("", siib MainLoop
print "Key: $_[l]\n";
{
[
As you press keys on the keyboard,
},
you'll see their
Ev('K')]
)
key symbols printed out
on the screen. Notice that the shift characters above the numbers (such as $, %, /\, and so on) come out as named ("dollar," "percent," "caret," and so on). KeyRelease
The KeyRelease event the key
is
released.
is
the
companion event
Sometimes
it
is
to KeyPress.
It is
invoked
when
preferable to wait until the key has been
released before doing anything.
Leave
The Leave event happens when the mouse cursor leaves the area occupied by the widget. Use Enter and Leave events to create two bindings for the same widget and you can do neat things such as change the mouse cursor while the mouse is in the widget (look into using -cursor first if it's available for that widget).
Map The Map event happens when window has been mapped or opened
(deiconified).
Motion
When
the
erates a lightly
bind to
mouse moves around on
Motion event. This
because your callback just a single
will
be triggered
all
the time. Granted,
widget, you'll only get Motion events
ing over that widget, but that gest having a very
the screen above your application,
it
gen-
another event that you don't want to bind to
is
is still
good reason
when you
Motion event.
you
are pass-
a lot of invocations of the callback.
for binding to the
if
I
sug-
.
278
Chapter 14: Binding Events
Reparent
The Reparent event happens when parent of
the
bound widget has changed.
Unmap The Unmap event happens when
bound window has been
the
iconified.
Visibility
When
widget
a
several
ways
When
•
screen,
the application it
When
visible,
first
starts
it
onto the screen, a
the widget
is
There are
triggers the Visibility event.
it
in
your application:
up, and the widget
Note
triggers a Visibility event.
don't pack •
becomes
first
widget becomes visible
a
Visibility
that
if
you
is
placed on the
create a widget
and
event will not be generated.
unpacked by using pack
(
'
forget
'
and then
)
repacked.
When
•
window is resized and the widget suddenly comes into view window has been made smaller and then resized larger).
the
(usually after the
When
•
the widget
and
get)
scrolls
is
inside another widget (such as a text or canvas wid-
back on the screen.
Event Information You can find out information about an. event by using the Ev method. There are many values you can use in a call to Ev, and they are thoroughly documented on the Perl/Tk documentation web site at http://w4.lns.comell.edu/~pvhp/ptk/ doc/bind. htm, which ptk/pod/bind.pod.
I'll
is
maintained by Peter Prymmer, and http://www.perl.com/
cover the values that you would want to use 99.9 percent of
the time.
Remember
events.
you use an Ev value
If
that certain values
used with Ev are only valid
that doesn't apply, you'll get
for certain
an undefined value.
Coordinates To determine the coordinates at which the event happened, use Ev('x') and They return coordinates relative to the window in which the event hapEv( 'y' pened. If you want coordinates relative to the root of your window system (desk)
•
top in Windows, Xroot in X), use uppercase
Ev('X') and Ev('Y')are valid only Key Release, or Motion events.
Button To
X
and Y: Ev( 'X'
for ButtonPress,
)
and Ev( Y' '
)
ButtonRelease, KeyPress,
Number
find out
which button number on the mouse was pressed, use Ev('b')- It If you use Ev('b') with
valid only for ButtonPress or ButtonRelease events.
event,
you would obviously get
1
back.
is
a
279
Bailing Out of a Callback Created with bind
Height and Width to return the height and a 'w' to return the width associated with the The width and height returned indicate how large the widget is. For instance, if you want to find out the new size of a button after the window has been manually resized by the user, you can do this:
Use an 'h'
event.
$button->bind("",
sub { print "H: $_[!], W: $_[2]\n"; Ev('h'), Ev('w')
[
]
},
)
The callback will only be invoked when the widget has been configured. This happens when the widget is first created and any time the widget is resized. Ev( 'h'
)
and Ev( 'w'
are valid only for Configure, Expose,
)
and GraphicsExpose
events.
Keyboard Information There are several ways
to find out
which keys the user has pressed on the key-
board. Use 'K' to print out the value associated with that key called a keysym. If you use lowercase 'k', you'll get the ASCII value associated with the key. Try this bit of code to see the difference: $b->bind{"", )
and Ev( 'K'
You can
also get the
Ev( 'k'
[
sub
{
print "ARCS:
(a_\n"
;
are valid only for KeyPress
)
keysym
},
]
)
and KeyRelease events.
number
as a decimal
Ev('k'), Ev('K')
rather than a string
by using
Ev('N').
Event Type You can
find out
Ev('T').
When
It's
what type of event the callback
is
responding to by using
responding to a KeyPress event, the string
pretty obvious, but
sometimes
it's
useful
if
you
will
are using the
be "KeyPress".
same callback
to
respond to several different events.
Bailing Out of a Callback Created with
bind To
stop the processing within your callback, you can use a
return control. This will not stop any further cessed.
To
halt the processing of
combination, you can use Tk:
:
any and
break
all
bound
return statement
to
callbacks from being pro-
callbacks
bound
to a widget/event
instead of the milder return.
;
.
;
;
:
280
Chapter 14: Binding Events
The bindtags Method To
find out the tags associated with a widget, use the
bindtags method;
for
example: print join(' ', $button->bindtags # prints this: Tk: Button .button print join(' ', $inw->bindtags () # prints this MainWindow all
( )
:
)
:
This
tells
.
)
all
;
.
us the order in which the widget will respond to binding callbacks. The
always to the class that the widget belongs
first
response
first
example and MainWindow
is
to;
Tk::Button in the
in the second.
The information returned from bindtags isn't nearly as interesting as what you can do with arguments sent to it. To remove all specific bindings from a widget except those that apply to all '
'
$button->bindtags
Now
[ (
'
all
'
]
)
the button will not respond to being pressed,
page
bindtags, you can reverse the order
for
events like
in
or the
in the Perl/Tk
web
which the widget responds
to
this:
$b->bindtags
We
mouse movements,
As demonstrated
default bindings associated with the widget.
already
[ '
(
know
all
'
that
,
$b->toplevel ref $b) $b] ,
(
,
)
'all' means any bindings associated with the special
all bindtag. Using $b->toplevel returns the window $b lives in: MainWindow=HASH(0x9798d8). Using ref($b) gives the package $b belongs to: Tk: :ButTk: Button. Finally, $b means the specific instance of $b: ton=HASH 0x99c0cc '
'
:
)
(
HASH(0x99c0cc) in
parentheses
that
it
is
is
is
a
what we see when
just the physical
we
memory
print the value out.
The hex number HASH means
location of that widget.
stored in a hash structure.
Ways
Use bind
to
do things easily. You can menu when you right-click on Use bind with text tags to create a pseudo-html document. Add a double-click binding to the listbox so that something happens when a user double-clicks on an Using bind
add
is
a powerful
way
to
make your
a binding to a listbox widget so
it
application
will display a
it.
item in the listbox. There are more ways you can use
cover here. Just
make
sure you don't
do anything
example, triple-clicking while holding
down
bind than
I
could ever
that the user can't figure out (for
the Control key
is
a bit obscure).
Composite Widgets
So
we have
far,
only discussed each basic widget separately. The Perl/Tk distribu-
tion also includes several composite widgets.
of widgets that
do something
specific
Composite widgets are combinations
when
some
they are combined. Here are
examples of composite widgets:
Optionmenu Based on menubutton widget; on the menu.
it
allows the user to select from a
list
of items
LabEntfy
Based on frame widget;
it
is
Based on toplevel widget;
it
an entry widget with a configurable
label.
Dialog
I
displays a bitmap
and
a
message
to the user.
chose these examples because they demonstrate a good point about composite
They can be based on a widget (in that contains widgets, or on a toplevel widget complete window.
widgets.
When
I
first
started learning about
ing something.
If
I
looked
at
this case,
menubutton), on a frame
that contains other widgets
composite widgets,
the code out of the
I
always
comer of my
felt like
eye,
it
I
and
was
made
is
a
miss-
sense.
if I looked at it head on, I was suddenly utterly confused and wasn't sure what was doing. The important thing to remember is that there is quite a bit that goes on behind the scenes that we take advantage of when we are creating a compos-
Yet it
ite
My
widget.
goal with this chapter
isn't for
you
to write the
most complex type of compos-
how
composite widgets work is more than enough. You can build up slowly from there. The best thing to do is read through this chapter and then look at the examples already included with the ite
widget you can think
of.
Simply understanding
281
;
;
;
;
;
;
282
Chapter 15: Composite Widgets
The composite widgets included with the Tk module are many different people, and will do something when you run them (plus they are usually documented with pod documentation). Rather than show a do-nothing example in this chapter, I will refer you to real distribution of Perl/Tk.
complete, have been reviewed by
code.
Looking at an Example Sideways I
admit
it.
I
examples. They give
like
me
I'm getting into the nitty-gritty. Since there posite widgets, we'll start simple
come back
a starting point to
to
quite a bit of nitty-gritty with
is
and work up from
when com-
there.
you look at the code for these composite widgets, the LabEntry has amount of code. Here is the LabEntry.pm widget code: If
the smallest
Copyright (c) 1995-1997 Nick Ing-Simmons All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Class LabeledEntry
#
.
# #
#
package Tk: LabEntry; require Tk: Frame; ©ISA = qw{Tk: Frame) :
:
:
Constiruct Tk: Widget 'LabEntry'; :
sub Populate {
require Tk: Entry; # LabeledEntry constructor. :
#
my($cw, $args) = @_; $cw->SUPER: Populate $args entry, # Advertised subwidgets: my $e = $cw->Entry() $e->pack( -expand => 1, -fill => 'both'); $cw->Advertise( 'entry' => $e) $cw->ConfigSpecs (DEFAULT => [$e] $cw->Delegates (DEFAULT => $e) $cw->AddScrollbars($e) if (exists $args->{-scrollbars} :
(
)
)
)
}
1;
That's the complete set of code,
comments and
composite widget because of the
Programming each package
method
if it
line (ilSA
=
Perl (O'Reilly, 1997) to find out a
special array called (ilSA
can't find the
method
in that
all.
You can
tell it's
qw(Tk: Frame). :
what the @ISA array
tells
Perl
where
package." There's a
a frame-based
We
can look
is for:
in
"Within
else to look for a lot
more
there about
283
Location of Files
how
to explain a simple concept:
your code.*
line in
wouldn't want to overuse their words
just
To have your composite widget work, you need
this
implements inheritance, but
this
All the other
I
explanation
is
—how does the entry widget come
Next step because
if
we
use a LabEntry,
one subroutine
in the
whole
we file;
nitty-gritty.
into play?
We know
gets created
it
see one on the screen. You'll notice there's only that subroutine
is
Populate. You never
called
call it directly, but it does get called. The arguments to Populate are two scalars. The first is a reference to the frame itself, and the second is a reference to a hash that contains all the argument pairs you would have used to create the widget. Here's an example of creating a LabEntry widget:
$label_entry = $mw->LabEntrY(-textvariable => \$text, -label => "Enter Name:", -labelPack => -side => 'left'
)
[
As you glance through the code, you know an entry widget see this
my $e
line:
= $cw->Entry
( )
.
Then
and Delegates. For
Advertising, ConfigSpecs,
a
is
let's just
->pack(
)
created because
bunch of weird
now
]
stuff
you
happens with
say that these functions
allow the entry widget to behave as you would expect an entry widget to behave.
The LabEntry 's
when we the
label
create
we
If
it.
created automatically because
is
-label option with
a simple
look back to Chapter a frame, a label will
composite widget
is
that
it
12,
we
Frames,
be created
use the -label option
we
use
So what makes
this
we know
for us.
that
if
takes advantage of the label already included
with a frame widget.
Location of Files When you name
create your
own
composite widgets, you create a
file
that has the
same
(including capitalization) of your widget and has a .pm suffix. For instance,
you wanted place the code if
new composite
to create a for
it
widget called ListButton, you would
in a file called ListButton.pm.
new
use ListButton
In the
code
at the
top of your code, assuming you keep your composite widget
that uses
your
ListButton.pm) in the
same before any use or require use lib
(
"dirl "
,
"dir2 "
widget, include
after the files
use Tk (such as
directory as the rest of your application code.
If
not,
statements, add: )
pointing to whatever directory you're using for ListButton.pm.
* You really don't need to inherit from a frame, but most people do, and because you have an automatic container for your composite widget.
t
The
we
nitty-gritty
don't
need
would involve
tracing through
that level of detail here.
all
the Perl/Tk
code
it
to see
makes what
things a
little
simpler
gets called where, but
;
;
284
Chapter 15: Composite Widgets
Creating a Composite Widget Based on
Frame There are
between creating
differences
slight
frame and creating one based on a toplevel.
a I
composite widget based on a
example
will include a short
for
each to give you an idea of what you can do.
Assuming you're making
a composite widget called
you absolutely must have
in
package MyWidget; require Tk: Frame; ©ISA = qw(Tk: Frame
your
new composite
MyWidget, the
widget
first
five lines
file are:
:
:
)
Construct Tk: Widget :
'
I^f/Widget
'
sub Populate {
You must MyWidget
declare your
new
widget as
line. (If you were going would use DirName: :]y^/Widget.)
The next two
lines are simple:
to
its
own
package, hence the package
have a subdirectory
for
your widgets, you
Tk: Frame to make sure you have
require
:
loaded the information necessary to use a frame widget, and then add Tk::Frame to the
©ISA
variable.
(you could also write
name
calling
line calls the
Construct method from
Tk: :Widget->Const3ruct( "MyWidget"
this as
of your widget. In this
directory in
By
The next
call to
which your widget
Construct you do not add
Tk:: Widget ))
with the
name
the
of the
resides.
Construct, you create a constructor method
widget. This allows you to create a
for
new MyWidget by
your
new MyWidget MyWidget
calling the
method: $newwidget = $itiw->MyWidget (...);
You
are creating a composite widget based
late
to create
on
a frame, so
you need
to use
Popu-
your subwidgets and do any other necessary configuration.
Inside Populate It
a
is
create
good in
idea to
add
a
require statement
for
any other widgets you want to
your composite widget. In the LabEntry code,
Tk: Entry because LabEntry creates an entry widget. :
we saw
a
require
Creating a Composite Widget Based on
Populate
is
Frame
two arguments:
called with
285
a reference to the
composite widget and
arguments to variables so you can use them
a reference to a hash. Assign these later:
my
($cw,
$args)
= @_;
The next thing you should do entire
Do
composite widget.
and then seeing
if
the value
is
this
was
deal with any specific options that apply to your
by getting them out of the $args hash reference defined:
$option_value = delete $args->{ "-flag" if (defined $option_value) {
}
}
say you want to use the option -filename, which will get the value associ-
Let's
ated with the
-filename option
into $ filename:
$filename = delete $args->{ "-filename" if (defined $filename) { # Open file.
}
.
}
After dealing with
the arguments that
all
idea to call SUPER:
:
Populate
$cw->SUPER: Populate $args :
(
you want
you want
if
methods
for
gets,
call
is
a
good
)
in
your composite widget. For
to create a listbox with several buttons, call the appropriate
each one.
you should
it
like this:
Next you should create the widgets you want instance,
to pull out directly,
If
you want the user
Advertise
for
be able to manipulate those wid-
to
each one.
Calling Advertise
The Advertise method allows you to use the siibwidget method to get directly at that widget later on in the program. For example, after you create the LabEntry, you can get a reference to the entry widget: $label_entrY = $mw->LabEntry (-textvariable => \$text, -label => "Enter Name:", -labelPack => -side => 'left' ])->pack(); $entry = $label_entry->Subwidget "entry" $entered = $entry->get [
(
)
( )
When you tise
for
have two
create a composite widget
each widget. For example, calls to
if
Advertise:
$cw->Advertise( 'entry' => $e) $cw->Advertise( 'button' => $button)
remember to add another call to Adveryou create an entry and a button, you'll
;
;
286
Chapter 15: Composite Widgets
Calling Delegates
When you to define
you
create a composite widget,
When you
widgets into one.
what methods
and sending
it
are essentially combining
two or three
invoke methods on the composite widget, you have
are actually called.
a reference to the
Do
so by using the Delegates method
widget you want to use:
$cw->Delegates (DEFAULT => $e) All other
subwidget methods of the composite
the siibwidget
You can
will
have to be accessed by using
method and then invoking methods from
Delegates
also use
$cw->Delegates
('
insert
to call a
method on
there.
a subwidget as follows:
=> $scrolled_listbox,
'
$scrolled_listbox, DEFAULT => $e) 'delete'
==>
;
In this example,
if
be passed along
$conposite->insert (...), the method call will $scrolled_list±)Ox->insert method. You cannot pass
the user calls
to the
along any methods that your composite already defines.
own insert
If
your composite uses
its
method, you would have to manually pass control to the subwidget
yourself.
Calling ConflgSpecs
When you it.
create a composite widget,
You can use Conf igSpecs
to
do
so.
you want to
handle
option, or specify a default widget that will handle
simple composite widget such as LabEntry will
default widget to handle
all
of the configuration.
$cw->Conf igSpecs (DEFAULT => [$e]
Specify
DEFAULT
as the
first
call
an option
alias
of the
configure
to another calls.
Conf igSpecs just to set Conf igSpecs like this:
a
called
)
parameter, and then specify an
taining the widget to use as the
configure and use
It
it,
all
configure on ways to call Con-
call
There are three different
figSpecs: create an option and a way
A
be able to
to
anonymous
list
second parameter. This way, anytime you
concall
the composite widget reference, you'll be configuring the
entry widget.
Creating an alias
You can short
name
use Conf igSpecs to create an
alias for
and long version of the same option. to
mean
exactly the
same
thing, call
If
an option, possibly to make a
you want
Conf igSpecs
$cw->ConfigSpecs( '-file' => '-filename');
Specify the alias
first
and the equivalent option second.
to use
-file and -file-
like this:
Creating a Composite Widget Based on
Frame
287
Defining options
To
some
define an option and associate
$cw->ConfigSpecs(-newoption =>
action with
it,
call
Conf igSpecs
, "newOption", "NewOption"
[
,
]
like this:
)
The option you are creating the action for is listed first, and the second argument is an anonymous list consisting of four items. The first item is the action you want to take and should be "DESCENDANTS", "ADVERTISED", "SELF", "CHILDREN", "PASSIVE", "METHOD", "CALLBACK", or a $reference to a subwidget. The second and third items in the list have to do with the option database and can be left blank if you prefer. The fourth item is the default value of that option, usually undef or " " or whatever you want the default value of that option to be if the user doesn't specify
The
it.
action part of the
list
defines
what happens. Each possible value
is
defined as
follows:
DESCENDANTS The configure
for that option will
ADVERTISED The configure
will
be applied to
SELF The configure
will
be applied to the base widget
be applied recursively to
all
all
descendants.
advertised subwidgets.
(in this case, a frame,
but the
base widget can also be another composite widget).
CHILDREN The configure
will
be applied
to
all
children.
PASSIVE The value will be stored in $args. This is the way you would use Conf igSpecs on any options that can be used at create time or by custom methods of your composite widget.
METHOD The method with the same name as the option will be called. For instance, if « . => you call $cw->ConfigSpecs(-newoption ["METHOD", » undef] and then the user uses the -newoption option, the method newoption (which you still have to define in the file somewhere) will be -•
^
^
)
invoked. When you cannot define an option with one of the other you can use METHOD.
settings,
CALLBACK Invokes a method inside your composite widget sent
when
=>
["CALLBACK",
the widget
is
that option
if
,
configured or
$cw->ConfigSpecs (-itiyopt "MyMethod" undef]) would call the
created. For instance,
"inyMethod"
is
,
)
;;
( ;
;
.
,
,
288
,
,
Chapter 15: Composite Widgets
subroutine rayMethod
when
the option -itr/opt
Conf igSpecs below
try.pm's
is
used (also see BrowseEn-
an example).
for
$reference Forces a
call
to
Usually
option.
$reference->configure( -option => value) for $reference is a subwidget of the composite widget
that (for
example, an entry widget). ConflgSpecs example
Here
is
Conf igSpecs
the
$w->Conf igSpecs -listwidth -listcmd -browsecmd -choices -state -arrowimage -variable DEFAULT
As you can this
see,
call
=>
=> => => => => => =>
from the TkS.O version of BrowseEntry.pm:
[qw/PASSIVE listWidth ListWidth/ undef [qw/CALLBACK listCmd ListCmd/ undef [qw/CALLBACK browseCmd BrowseCmd/ undef] [qw/METHOD choices Choices/, undef] [qw/METHOD state State normal/] [{-image => $b} ,qw/arrowImage Ar rowlmage/, undef ]
,
]
,
,
,
]
,
"-textvariable" [$e]
)
you can send multiple pairs of information to ConfigSpecs. In is one PASSIVE option, two CALLBACK options, and two
example, there
METHOD
options.
Any
methods pointed
to in
configure with
other calls to
directed to the subwidget $e.
Take
a look at the
ConfigSpecs
different options will
be
complete code to see what the
do.
Frame-Based Widget Review Just to
sum
up, here's
some pseudocode
frame-based composite widget: $package NewWidget; ©ISA = qw(Tk: :Frame) Tk: :Widget->Construct 'NewWidget' (
sub Populate
)
(
{
my
{$cw,
$args)
= @_;
Handle any creation only options = delete $args-> { -option} if (defined $value) { #
my $value
}
Create any subwidgets you want to $widget = $cw->Widget (...); #
.
.
to
show you how
to create
your
own
Toplevel-Based Composite Widgets
$cw->Delegates $cw->Conf igSpecs
289
( )
(...);
}
sub myoption
{
}
1;
Toplevel-Based Composite Widgets one small difference between a composite widget based on a frame If you want to be able to use ->new() to create your window, define InitObject instead of Populate. Most of the composite widgets included with the Tk distribution do not do this, however. Look at ColorEditor.pm and DialogBox.pm for examples of how to create a toplevel-based composite widget. All the rules for using ConfigDefaults are the same. There
is
instead of a toplevel.
;
Methods for Any Widget So
far,
most of the chapters
in this
book have concentrated on
This chapter covers the methods that apply to
all
need most of these methods, but there are a few
Many call
times, you'll use a
MainWindow
these methods, but you can also
specific widgets.
widgets. You'll probably never
that you'll
use frequently.
reference (usually $inw in our examples) to
call
them from other widgets, such
as
$but-
ton, $checkbutton, and so on. Most of the methods are informational only,
meaning you pass no arguments We'll use the generic
to them;
$widget here
you only get
a value back.
instead of a specific widget type. This will
help you to remember that these are multipurpose methods.
Building a Family Tree The following methods deal with the ancestors or children of widgets and how they were created: children, name, parent, toplevel, manager, and class.
Widget's Children To determine the children of children method:
a
widget (usually
a toplevel or a frame),
use the
@kids = $widget->children() # i.e. Tk: :Button=HASH(0x85e3a0) Tk: :Button=HASH(0x85e4a8)
The
list
returned contains scalars that are the children of $widget.
You can then
use those references to perform actions such as setting a background color or font.
290
291
Building a Family Tree
Name of a Widget To determine what
the parent calls the widget use the
$name = $widget->name
You can combine
the
(
)
;
name and children method
©kids = $widget->children() f oreach @kids { print "Name: ", $_->name(), (
name method:
like this:
)
"\n";
}
Here
is
example output from
that code:
button buttonl
Parent of a Widget To
get a reference to the parent of a widget, use the
$parent = $widget->parent
parent method:
( )
The Widget's Toplevel To
get the toplevel widget that contains a widget, use toplevel:
$path
$widget->toplevel
=
(
)
The $path returned is a number (that is, 8606484) that you can compare to another number that was returned from another call to toplevel to see if they are equal.
Widget's You can
Manager
find out
Smanager It
which geometry manager $widget used by
= $widget->inanager
()
calling
manager:
;
returns a string that describes the geometry manager; for instance,
toplevel widget,
it
to
work
it
is
a
"grid", "pack", "place", or "wm". The manager
will return
method doesn't seem
if
correctly
on Windows
95, but
it
works on Unix and
Windows NT.
The Widget's
class
The class method returns a example, $listbox->class
{ )
"Menu".
string that indicates
returns "ListJDOx",
which class it belongs to. For and $menu->class returns ( )
;
;
.
292
Chapter 16: Methods for Any Widget
Widget's You can
ID
get an ID string for a widget
$id = $widget->id() print "$id\n"; # Prints 0x9c944c
The value returned
is
a
by using the id method:
;
hex value. This method does not work under Windows
95.
Widget's Path You can you
pathname of the window by id method:
get the
calling
pathname and using
the ID
retrieved with the
$path = $widget->pathnaine($id)
There
is
;
PathName method:
also the
$path = $iTiw->PathNaine
( )
;
method prints out the path of $mw would have a PathName of " "
the widget that
This
calling
is
it.
For example,
my
.
Color-Related Methods There are four methods
that deal with color:
colormapfull, rgb, cells, and
depth.
Is the
Colormap
To determine
Full?
the colormap for the widget
if
$isfull = $widget->colormapfull
The colonnapfull method
Cell
(
is full,
use colonnapfull:
)
returns a
1 if
the colormap
is full
and
if it is
not
full.
Count
The number of
cells in the
colormap can be obtained by using the cells method:
$count = $widget->cells
The value returned
is
a
(
)
number
indicating the
number
of colors; for example, 64.
Color Depth You can
get the
number
of bits per pixel by using the
$depth = $widget->depth() # $depth might contain "16"
depth method:
293
option Databases
Translate to
RGB Value
You can translate a color name to the red, green, and blue values by using the rgb method. Send rgb a color name (valid color names v^ere covered in Chapter 3) and
it
returns a
list
containing three items that represent the red, green,
and blue numbers. ($red,
Now
$green,
$blue)
= $widget->rgb( "color"
)
$red, $green, and $blue each contain an integer from
to 255.
Setting Colors You can have your the
based on one color automatically by using
entire application
setPalette method: $widget->setPalette( color)
The background all
color of
is
set to the specified color,
other widgets are calculated based
lighter color than the
color
on
$widget
a
background,
you picked. This method
it
on
will
that color.
show up
So
if
and the colors
a button's
edge
for is
a
a lighter shade of whatever
affects the entire application
even
if
you only
call
it
widget instead of a toplevel.
You can
set colors for explicit options
to associate with
it.
by specifying the name and then the color
For instance, the following code will set
and
in the application to red
all
backgrounds
$b->setPalette( "background" => "blue",
all
foreground items
to blue:
"foreground" => "red");
Predefined Color Scheme The bisque method $widget->bisque
sets the entire application to is
( )
the
same
use a bisque scheme. Calling
$widget->setPalette "bisque"
as calling
(
)
Option Databases Under the
X Window
System, a
file
named
contains configuration information for
X
.Xdefaults in the user's
call
it
directory
applications, including the colors
and
You can create the same type of file for Win32 whatever you want. You might use a file like this to let your
fonts an application should use.
systems and
home
users change the application's color settings.
Typically the lines in this
file
look something
screen*background yellow screen. button. foreground: green screen* font: {Arial} 24 {normal} :
like this:
;
;
Chapter 16: Methods for Any Widget
294
The
;
:
first
name
item in each line should be the
My
options are for your application only. screen, so that
is
what
I
used as the
keyword
first
of your application unless the
test application
in
each
was line.
named
in a file
The second key-
(if specified) is a widget type or name (you can specify a name for any widby adding the -name option to the creation command of that widget). The third keyword is the "class" for which you want to set a default. You can set a default value for any of the options associated with a widget. See Appendix A to find out which class is associated with each widget type.
word get
To read ple,
in this file, call optionReadf ile with the location of the "color_options" or "C: / .Xdefaults" or " .Xdefaults"):
$widget->optioriReadfile "filename" (
Make
)
newline on
last line
of this
file
or you'll get an error
C:\PERL\lib\site/Tk/Submethods.pm line
line 2 at
make much sense except
16." This error doesn't
exam-
;
sure to include a newline on the
that says, "missing
file (for
that the first line
number
it
gives
you matches the number of lines in the option file you are trying to read in. If you to call the method, you'll get a more use $widget->option( "readfile" ,
.
.
.
)
sensible error message.
As the second argument to optionReadf ile you can specify an optional priority, which should be one of "widgetDefault", "startupFile", "userDefault", or "interactive". The default priority is "interactive", which is the highest priority.
$widget->optionReadf ile
You can add an
(
"
filename"
,
"widgetDefault"
)
option type in the program dynamically by using the
optionAdd
method (whether or not you have used optioriReadf ile) $widget->optionAdd(pattezT! => value);
For example,
we
can change the font for the entire program
$widget->optionAdd
(
"
screen* font "
,
" {
Arial } 24 {normal }
"
like this:
)
The optionClear method should clear out any current option the file (or retrieve them from the resource manager): $widget->optionClear
settings
and reread
( )
To determine
the current setting for the value associated with a specified
and
optionGet:
class, call
$widget->optionGet (name, class);
name
295
Converting Screen Distances
The Application's Name The name of the application that is used in the option file discussed earlier is by default the name of the file from which the script is run. You can use the appname method to change the name of the file: $mw->appnaine "newname" (
You can
)
;
find out the current
name
of the application by calling
appname with no
arguments: $name = $inw->appname
( )
;
Widget Existence To determine
if
a widget has
(Exists ($widget)
if
been
created, use
Exists ($widget)
{
)
}
Note the uppercase "E" on built-in Perl
Is the To
this
method. The Exists method
exists method. Make
sure
you
is
different
from the
don't confuse the two.
Widget Mapped?
find out
if
the widget has
been mapped
to the screen, use the
ismapped
method: if
$widget->isinapped Do something else { # map the widget (
( )
)
#
}
}
The ismapped method and if it is not.
returns
1
the widget
if
is
currently
mapped
to the screen
Converting Screen Distances If you prefer to use inches as a screen distance but you want to print out pixels, you can use the pixels method to convert any valid screen distance string into a
pixel value; for example:
$pixels = $widget->pixels "2i" $pixels - $widget->pixels "2m" (
)
;
#
)
;
#
(
What is What is
2 2
inches in pixels? millimeters in pixels?
;
;
;
;
;
296
Chapter 16: Methods for Any Widget
The pixels method rounds to pixel result by using fpixels:
the nearest
$pixels = $widget->fpixels("2i") $pixels = $widget->fpixels("2m")
;
#
;
#
whole
What is What is
pixel.
2 2
You can
get a fractional
inches in pixels? millimeters in pixels?
Size of Widget You can
use the following methods to find out the size of a widget in several
dif-
ferent ways.
Geometry
Widget's
The geometrY method
geometry
returns the
widget
string for the
in the
form of
widthxheight+x^y. $geom = $widget->geometry()
The geometry
string
was discussed
in detail in
Chapter
13-
Geometry values
are
specified in pixels.
Requested Height The height of the widget
is
returned by the
$height = $widget->reqheight
The widget
itself
reqheight method:
( )
determines the appropriate height.
Requested Width The width of $width
=
the widget can be determined
$widget->reqwidth(
by using the reqwidth method:
)
Actual Width To
get the width of the widget as
$cur_width
When
=
the widget
$widget->width( is first
created,
ished drawing everything. After
it
currently
is
drawn, use the width method:
)
width
that,
it
will return a 1 until the application has fin-
will return the actual
Actual Height To
get the current height, use the
$h = $widget->height
(
)
height method:
width of the widget.
297
Widget Position
width method, height returns a 1 when the widget is first created. You can use the update or the af terldle method to force everything else to happen and then call height or width to get the finished values.
Just like the
Widget Position The methods
in this section all deal
with the position of a widget.
Position Relative to the Root Window To determine which widget
is at
the point x,y;, use the
containing method:
$which = $widget->containing($x, $y)
The $x and $y coordinates must be
Windows found
system, the desktop).
those coordinates.
at
nates, the
one
If
relative to the root
An empty
string
window
returned
is
if
(or
on
there
a Microsoft
no widget
is
there are several widgets located at those coordi-
closest to the front
is
returned.
Coordinates Relative to Parent You can
get the coordinates of the upper-left
y methods. The
comer
of a widget by using the
x and
coordinates they return are relative to the parent of the widget:
$x = $widget->x() $y = $widget->y()
Coordinates Relative to Root Window To on
get the coordinates relative to the root
window, you can use rootx and rooty
the widget: $x = $widget->rootx $y = $widget->rooty()
( )
The coordinates
refer to the upper-left corner of the widget.
Virtual Desktop Coordinates If
you have
a virtual desktop, there are special
relative to the virtual desktop. Virtual
dow
System (such as the
Microsoft
Windows
methods
desktops are very
fvwm and tvtwm window
as well.
that will give coordinates
common on
the
X
Win-
managers), but they exist on
;
;
; ;;
;
; ;
298
Chapter
To determine the height and width and vrootwidth methods: $height = $widget->vrootheight $width = $widget->vrootwidth()
To
1 6:
Methods for Any Widget
of the virtual desktop, use the
vrootheight
( )
get the coordinates of the widget's upper-left corner relative to the virtual desk-
top, use
vrootx and vrooty:
$x = $widget->vrootx $y - $widget->vrooty()
( )
All four of these
methods return an empty
Cursor Coordinates Relative
string
to
if
a virtual desktop
on the screen
not found.
Desktop
You can use pointerx, pointery, and pointerxy clicked
is
to determine
where the user
in a widget:
$x = $widget->pointerx() $y = $widget->pointery() ($x, $y) = $widget->pointerxy{) All the coordinates returned are relative to the
desktop (even
if it is
a virtual desktop).
Screen Information The following methods virtual
all
return information based
on the screen (which can be
a
desktop or a normal desktop) and the colors of the desktop.
Screen
Name
Each screen you use has a name associated with
it.
To
get the
name, use the
screen method: $name = $widget->screen()
The name returned will be formatted as " displayName, screenlndex" " as the screen name. dows 95 machine returned " :
Screen Height
.
My
Win-
.
and Width
The screen height and width is really just the resolution of the screen. Sometimes you might need information to determine how large a window can fit on a user's display. To get the height and width of the screen in pixels, use the screenheight and screenwidth methods: $height = $widget->screenheight $width = $widget->screenwidth()
( )
299
Screen Information
If
my
resolution
returns 1024.
If
is
768x1024, then screenheight returns 768 and screenwidth
you prefer
to get the size of the screen in millimeters, then use
screeninmheight and screeninrnwidth: Sheightmm = $widget->screermimheight
( )
$widthinm = $widget->screenirinwidth()
;
The same
resolution, 768x1024, returns 203 millimeters as the height
meters as the width for
Cell
my
and 270
milli-
monitor.
Count
The number
of cells in the default colormap
$count = $widget->screencells
My Windows
95 machine has 64
retrieved
is
by using screencells:
( )
cells in its default
colormap.
Screen Depth To determine
the
number
of bits per pixel your screen has, use the
screendepth
method: $depth = $widget->screendepth()
The depth of
my Windows
95 machine
is
16 bits per pixel.
Color Type The type
of color
is
defined by
class,
and
it
will
be "directcolor", "gray-
scale", "pseudocolor", "staticcolor", "staticgray", or "truecolor". To determine the class for the screen that contains the widget, use screenvisual: $type = $widget->screenvisual
To determine
(
)
the class of color for the widget
$type = $widget->visual
itself,
use visual:
( )
To find out the entire list of visualsavailable method:
classes available for the current setup, use the
©list = $widget->visualsavailable
Each element instance,
color
on
16".
in
@list describes
my Windows
the visual
and the color depth
for that visual. For
95 machine, ©list contained only one item: "true-
;
;
;
;
300
Chapter
Methods for Any Widget
1 6:
Server Type The type of
server
is
available through the
$server_type = $widget->server
My Windows
( )
95 has a server type of "Windows 4.0 67109975 Win32".
Widget Viewable?
Is the
A
server method:
widget
You can
is
determined viewable
ask the widget
$isviewable
viewable
itself if
if
it is
the widget
$widget->viewable
=
returns
all
of
its
ancestors are mapped.
( )
the widget can be
1 if
and
viewable by using the viewable method:
viewed and
if
not.
Atom Methods Each widget
is
name (you can
assigned a name, which get
it
for
These methods are used
To
an atom. The atom has a
called
is
name method) and
each widget by using the
internally to
string
a 32-bit ID.
handle things such as the selection mechanism.
name
get the 32-bit ID for a given widget, send the
atom
of the widget to the
method: $id = $widget->atom($widget->name(
You can do so,
the opposite
)
)
and use the ID
to get the
name
of the atom back.
To do
use the atomname method: $naine = $widget->atoninaine($id)
;
Ringing a Bell To make
the computer
$widget->bell
( )
beep
at the user, call
bell:
;
Clipboard Methods The following methods manipulate the dows clipboard (either Unix or Win32).
To add
data to the clipboard, use the
internal
call
a value.
Win-
)
clipboardAppend, you can
-format option with
also the
clipboardAppend method:
$widget->clipboard;^pend( "data to add"
When you
Tk clipboard and
The -format by
specify a format by using the default
is
"STRING", but
it
can
Selection
also
Methods
301
be "ATOM". Another option can be specified, -type, which takes a
as
"STRING" or "FILE_NAME".
To
clear out the clipboard, use
$widget->clipboardClear
Any To
(
string
such
clipboardClear:
)
data in the clipboard will be removed.
find out
what
is
in the clipboard, see the
selectionGet method
in the sec-
tion entitled "Getting the Selection."
Selection
Methods
Some widgets allow
the user to
tion
make
and
a selection in the text, entry,
a selection. For
listbox widgets.
example, the user can make
You can manipulate
the selec-
X
selection)
by using the following methods.
Clearing the Selection To
from any widget
clear the current selection
(this will also clear
an
use SelectionClear: $widget->SelectionClear
You can
specify a
;
-selection
BOARD". The default
is
option,
which takes
either
"PRIMARY" or "CLIP-
"PRIMARY". Using "CLIPBOARD" clears out the clipboard
as well.
Getting the Selection To determine what
the current selection for the application
$selection = $widget->SelectionGet
You can
also specify the
is,
use SelectionGet:
( )
-selection option with
the
SelectionGet method:
$clipboard = $widget->SelectionGet (-selection => "CLIPBOARD");
The -selection method takes either "PRIMARY" or "CLIPBOARD". The default is "PRIMARY", so if you don't specify -selection, you will get back the value that represents the current selection in the application. Using "CLIPBOARD" will return the value in the clipboard.
Assigning a Callback You can
call
invoked
when
SelectionHandle
to assign a callback that will automatically
the selection associated with
$win changes:
$widget->SelectionHandle($win => \&subroutine)
be
;
;
;
302
Chapter
When $win owns
specify the options -format, -type,
with the same possible values
shown
SelectionHandle with an empty callback
is
Methods for Any Widget
the selection, the callback will be invoked (in this example,
You can
siibroutine).
1 6:
in the
and -selection
preceding code example.
If
you
call
string as the callback, the previously assigned
removed.
Determining Owner You can find out which widget on the screen currently owns the selection by calling SelectionOwner (a widget owns the selection if it has something selected in it): $widget = $widget->SelectionOwner
You can BOARD"
( )
;
-selection option with who owns the
also specify the
as the value to determine
"PRIMARY" or "CLIP-
either
selection, or the current clip-
board value, respectively.
Owner
Setting the To
force a widget to
own
the selection, call
SelectionOwn:
$widget->selectionOwn()
You can
also specify
which type of
selection to force
by using the -selection
option with "PRIMARY" or "CLIPBOARD". Finally, you can specify a -command
option with an associated callback that will be invoked tion
is
when
that widget's selec-
forced away.
Destroying a Widget You can
destroy
Tk: Exists :
is
by
widget
a
calling
destroy on
the
widget
(using
if
recommended):
$widget->destroy() if Tk: Exists ($widget) :
If
the widget
is
a parent of
any other widgets, the other widgets are destroyed as
well.
Focus Methods When
your application
is
running, you can force a widget to have the keyboard
focus by calling focus on that widget: $widget->f ocus
You might want start
typing
first.
(
to
)
do
if you have an entry widget into which the user should focus right before MainLoop causes the widget to get the
this
Calling
Grab Methods
303
you press the Tab key, the focus automatically changes from the next (remember that you can tell when a widget has the focus
focus right away.
one widget
to
If
by the highlight rectangle around
it).
There are several methods that allow you to
manipulate the focus.
To make
the focus follow the
mouse around, use focusFollowsMouse:
$widget->focusFollowsMouse(
)
method is buggy under both Windows 95 and Unix. A patch just recently came out for Tk8, so if you want to use this method and it isn't working, make sure you get the patch.
This
To
find out
which widget has the
$who = $widget->f ocusCurrent
To
(
focus, call
focusCurrent;
)
even
force a widget to have the focus
if
the application
isn't
currently active,
f ocusForce:
call
$widget->focusForce()
This
To
is
not a nice thing to do, so
find out
none of the widgets
To
not use
which widget had the focus
$which = $widget->f ocusLast If
try to
in the
find out the order in
(
it.
last, call
f ocusLast:
)
window
has the focus, the toplevel
which the focus
will
is
returned.
change, you can use the focusNext
and focus Prev methods: $nextwidget = $widget->f ocusNext $prevwidget = $widget->focusPrev() ( )
Grab Methods When
a
mouse
input to
window does
a "grab"
it
window
means
that
it
holds
all
of the keyboard and
windows in the application to receive input. There is also a global grab, which means that no applications in the entire system can get input except the one window that has done the itself.
global grab. These
To do
methods
will
not allow any other
are usually called from a toplevel widget.
a local grab for the widget, use grab:
$widget->grab(
A
That
)
means that you can interact with other windows in the system but not with other windows in the application. To do a global grab, use grabGlobal: local grab
$widget->grabGlobal
( )
; ;
;
;
;
304
Chapter 16: Methods for Any Widget
$widget->grabGlobal
To
(
)
"ungrab", call grabRelease:
$widget->grabRelease
To
find out
(
)
;
which widget has done
$who = $widget->grabCurrent
To
a grab, call
( )
find out the current grab state of a
$status = $widget->grabStatus
The grabStatus method
©windows
=
$widget,
$widget->grabs
Interapplication
call
grabStatus:
;
( )
returns a string that
To find out all the windows grabs to get a list back:
grabCurrent:
is
that are currently
"none", "local", or "global".
under the influence of grab, use
()
Communication
You can
use the send command to have Perl/Tk (and even Tcl/Tk) applications communicate back and forth. The arguments include an application to talk to and the
command
to execute in that application.
$widget->send( "application" => callhack)
You can
also specify the option -async,
which
will return control
immediately
instead of waiting for the callback to execute.
By
default,
your application
an error to another application trying to
will return
you want to actually receive communications from other applications, define Tk :: Receive $widget "coitimand") and be very careful with what you do with the command string. Allowing any application to send communicate with
it.
If
,
(
unknown commands
When script
to
your application can be dangerous.
doing interapplication communication, with the
-7" switch,
which forces
Waiting for Events to At certain points in your application, pens. For instance,
if
you
is set.
To have
a
program wait
it
is
a
good idea
your Perl
Happen it
makes sense
to wait until
something hap-
window and want you can use waitVariable to
until a variable's
$widget->waitVariable(\$var)
to run
checking.
create a ColorEditor
color the user selects to a variable, variable
taint
value
it
is
changed,
call
to assign the
wait until the
waitVariable:
Waiting for Events to Happen
305
Processing will continue as soon as the value contained within $var
something
different.
To
wait until a
$widget->waitVisibility(
To
wait until a widget
$widget
visible,
is
is
changed
to
use waitVisibility:
;
)
destroyed, call waitWindow:
is
$widget->waitWindow()
When you
call
these methods, nothing will
happen
in
your program
until the
requested for event has taken place.
An
alternative to
waitWindow
widget methods are
still
$widget->OrLDes troy (sub
File There
is
available ...
{
OnDestroy, where you specify a
when you });
a special
is
method
when
a
shows how
it
notified
in Perl/Tk called
file is
fileevent. You can use
readable or writable. Here
meant system because we use the Unix tail command):* that
use Tk; open (FH,
can be used
(this
code
"tail -f -n 25 text_file|")
|
is
an example snippet of
die "Could not open file!\n";
-width => 80, -height => 25) ->pack( -expand => 'readable', [\&insert_text] )
sub insert_text {
my $curline; if
($curline = )
{
$text->insert end' $curline) $text->yview( 'moveto' 100); (
'
,
,
}
else {
$mw->f ileevent (FH,
'
readable
" '
,
" )
}
}
Thanks
to
my
friend Phivu
Nguyen
for sharing his
code with me.
watch
be executed on a Unix
|
(FH,
to
is
;
$mw->fileevent MainLoop
it
to
my $inw = MainWindow->new() my $text = $mw->Scrolled( "Text"
*
The
Events
and be code
callback.
use OnDestory:
1)
;
;
Chapter 16: Methods for Any Widget
306 This short program
an
around and waits
sits
box with
insert into a text
the
until a file is readable and then does newly read information. You can also use
'writable'. $inw->fileevent (FH, If
you get
'writable',
callback);
rid of the callback portion, the callback will
callback with an
empty
string (" ")
and the callback
be returned. Replace the
removed.
is
Parsing Command-Line Options it is standard practice to specify command-line options when you are invoking an application, especially a graphical program. Starting your program as myscript -geometry "80x40" would not be unusual. To have Perl/Tk automatically parse and apply these command-line options for you, just call CmdLine immediately after you create your MainWindow.
In the Unix world,
$inw->CmdLine
In Tk4,
if
)
;
you want
and leave some ments you want
—
(
for it
to
have CmdLine stop processing command-line arguments
you
to deal with,
add a double dash
to leave for you; for instance,
(
—
)
before the argu-
myscript -geometry "80x40"
-rayopt.
In Tk8, the processing of options will stop
when
the
first
unknown
option
is
found.
Another way to deal with command-line options
is to use the Perl Getopts modProgramming Perl (O'Reilly, 1997) to find out how to use the methods available in Getopts. The methods inside Getopts don't handle the options for you; it just puts them in a structure that's easier to deal with.
Take
ules.
a look in
Tim.e Delays when you'll want to be able to delay the program a bit before going on, or maybe you'll want to execute the same command every minute. To have the program sleep for x number of milliseconds, call after with the number
There are times
of milliseconds: $widget->af ter {milliseconds)
To
;
many
specify a callback that will be called after so
ing,
send a callback as the second argument
to
after:
$id = $widget->af ter (milliseconds, callback) #
i.e.
$id = $widget->af ter (1000, \&do_something)
milliseconds instead of wait-
307
Time Delays
If
you want to execute af terldle:
a subroutine after the
program has been
idle for a while,
call
$id = $widget->afterIdle(caIIjbacA:)
To
cancel the
call
to
after
;
or afterldle,
use afterCancel with the $id
returned by after: $widget->afterCancel ($id) You can also do this: $id->cancel #
( )
You can have
the
program repeatedly
call
the
same callback by using
the
repeat
method: $widget->repeat (milliseconds, callback)
;
# i.e.
$widget->repeat (600, \&update_status) If
you destroy $widget, any
celed for you.
calls to
after and repeat
are automatically can-
Configuring Widgets with configure and cget Every widget included
(and some not included, but
in the Perl/Tk distribution
available separately) can use the
configure and cget methods. No matter
the
widget, the arguments to these functions are the same, and the results passed back
have the same format.
The configure method allows you the widget.
It
to assign or
change the value of an option to
can also be used to retrieve the current value of the option. The
cget method cannot assign than that of configure.
values, but simply retrieves
them with simpler syntax
The configure Method The
basic format of the
$widget->conf igure
(
configure method [
is
as follows:
option -> newvalue,
Depending on the arguments passed
to
it,
...
]
)
;
configure method can do
the
three
things:
change the values of the options
$widget
•
Set or
•
Get the current value of any option for $widget
•
Get the current values for
To
set or
change the value
have appeared
in the
all
for
for
of the options for
$widget
an option, send the option pair exactly as
it
would
widget creation command:
$widget->conf igure -option => newvalue); (
309
;
310
;
;
Appendix A: Configuring Widgets with configure and cget
Whatever
effect the option
has will take place immediately. To see the current val-
ues for a single option, send the option you are interested
depends on whether configure
return value
configure
context. In the following line,
value
is
being assigned to an
called in
is
in as the
called in
is
list
list
argument. The
context or scalar
context (since
its
return
array):
@info = $widget->configure(-highlightthickness) In
context, an array of scalars
list
is
returned.
The
results of this call
-highlightthickness highlightThickness HighlightThickness
The following
2
look
like this:
2
five values are in the returned array:
Option name Option name from the option database (also as appear in the .Xdefaults file)
1
2
Class in the option database
3
Default value of the option
4
Current value of the option
Often, call
you're interested in
all
configure
is
would
it
the current value of the option.
by
in scalar context
If that's
the case,
assigning the result to a scalar:
$val ~ $widget->configure -highlightthickness print "$val\n"; (
The
If
result
would
you want
)
be:
to see the
list
of values for
all
of the options the widget supports, use
this format:
@config
@conf ig
=
$widget->configure{)
now
is
an array of
to utilize Tk::Pretty,
which
arrays.
will
do
The all
easiest
the hard
then put the information into a readable form: use Tk; use Tk: Pretty; :
$widget = $inw->Button;
©config = $widget->configure; print Pretty ©config;
way
to print out this information
work of
traversing the arrays
is
and
The configure Method
The
result
311
as follows:
is
-activebackground activeBackground, Foreground, ttececec ttececec -activeforeground' ,activeForeground, Background, Black, Black] -activeimage activelinage, Activelinage,undef ,undef '-anchor' 'anchor' Anchor, 'center' -background background Background, #d9d9d9 center #d9d9d9 -bd '-bitniap' 'bitmap' Bitmap, \indef,undef] borderWidth] '-bg' 'background' -borderwidth borderWidth, BorderWidth, 2,2], -command command Command, undef, bless [CODE (0x8189888) ,Tk: Callback) '-cursor' 'cursor' Cursor, undef ,undef -disabledforeground' ,disabledForeground,DisabledForeground, #a3a3a3 #a3a3a3 -fg' foregroiind' -font font Font, -Adobe -Helvetica-Bold-R-Normal *-i20-*-*-*-*-*-* -Adobe-Helvetica-Bold-R-Normal *-120-*-*-*-*-*-* -foregroiind' 'foreground' Foreground, Black, Black] -highlightbackground' ,highlightBackground, '-height' 'height' Height, 0,0] HighlightBackground, #d9d9d9 -highlightcolor ,highlightColor, #d9d9d9 HighlightColor, Black, Black] -highlightthickness highlightThickness HighlightThickness,2,2] '-image' image' Image, undef undef] ,[' -justify justify' Justify, 'center' 'center' -padx' ,padX, Pad, 3m, 9] -pady ,padY, Pad, Im, 3] -relief 'relief Relief 'raised' 'raised' -state' 'state' 'normal -takefocus takeFocus, TakeFocus, undef, undef State, 'normal -text text Text undef Do_Something] -textvariable textVariable Variable, undef undef -underline' 'underline' Underline, -1, -1] -width' 'width' Width, 0,0], -wraplength' ,wrapLength,WrapLength, 0, 0] [
'
[
'
,
'
,
'
'
'
'
[
]
'
,
]
[
'
'
]
[
'
,
]
,
,
'
[
[
'
[
'
'
'
,
,
,
,
'
,
[
,
'
'
'
]
[
,
'
,
]
'
—
,
'
'
'
,
'
'
,
,
'
'
—
[
'
]
,
'
,
,
[
,
[
,
'
,
[
,
'
'
'
[
'
]
'
,
'
'
,
'
[
,
'
[
,
,
]
[
,
'
,
,
]
]
'
,
]
[
,
'
,
]
,
[
,
'
,
[
,
'
'
,
,
'
[
,
'
[
'
'
[
,
'
'
,
'
,
,
'
,
'
'
,
,
,
'
[
'
,
,
'
]
]
'
[
:
]
'
,
,
(
]
[
'
'
,
,
'
'
,
,
'
'
[
'
,
,
,
'
,
,
[
,
'
,
'
,
[
,
'
,
,
'
,
'
,
may look nasty and ugly, it distinguishes between the different you by adding the and characters and the commas that separates them. Usually, you would only look at this list for debugging purposes. The default values for each widget are listed at the end of this appendix.
Although lists
of
this list
lists
for
]
[
The cget Method Instead of using
configure
to retrieve values,
you can use the cget method:
$widget->cget (-option) It
only returns the current value (or address
option rather than the entire
list
ing for "configuration get." Here
that is
if
the option stores a reference) of the
configure
an example of
print $b->cget (-highlightthickness) ## Prints this:
,
returns.
how
"\n";
2
# return reference print $option_menu->cget (-textvariable) "\n"; # return actual value " \n" print $ { $option_menu->cget -textvariable } :
,
:
(
)
# or...
$ref = $option_menu->cget (-textvariable) print $$ref, "\n";
,
Think of cget as stand-
to use cget:
;
312
Appendix A: Configuring Widgets with configure and
cget
Default Values for Each Widget in Table
Form The following tables contain all of the options for each standard widget (in Tk8). The five columns represent the five values returned in the arrays for each option when configure is used. Note that column 5, "Current Value," will probably not
mean much to you, but I've included when you run the same code. The information
in the tables
( )
for
completeness because you'll get
was created by using
the correct widget in for Widget): $w = $inw->Widget->pack; @conf ig = $w->conf igure print Pretty ©config;
it
this
code snippet
it
back
(substitute
Default Values for Each Widget in Table
Form
313
4J
4J
^
ic V t 3
u
0)
S
s
^
^
^
^ O o p ^ 4J d md PQ
^
r-H
4-)
4J 4J
(D
jj
^
g m
g
4J
4J
W
W
q3
^^ OJ
Q)
4J
a
^ ^
s U
^ m ^
V.
Q) r-l
s 4J w
4-1
4-1
4-1
0)
0)
0)
T!
Ti
T3
^
^
^w H Q CO
^
U (d
h
^
^
^
5
^ -d Ha
R
^
'ii
o
Eh
4-)
4-)
4J
4J
S
00
—
r-^
^
5
PQ
pQ
u
rH
(1)
CO
P
dJ
CO
CO 4H CO -rl
CO
0)
3
u
4J
M-l
W
W
T3
^ ^
B
4-)
0)
u ^4
^
^
CD
o
^
CO
4J
4-1
4-)
4->
TS
•H
CO
j3
p
^ '3 Hd
m
r-l 4-1
4-1
1
CO
1
0)
4-)
i 4J
1
OJ
4-)
4-)
•d
Tl
^
CO
3
lU
Q i 1 4J
^
OJ
S
(C3
•H
0)
o
1
4H
-H x;
QJ
H
&i
4-)
Htn H w K ^
tn
-H
•H
lU
CO :=!
h3
Ti
02
u
fe
^
^
-H
•H
4-)
4J
U
u
O
p o
9i
Sh
M
^ ^
^
CO CO
^
Ti
5
5
T3
•H
H
S
IS
a H^ ^ M^ 13 M§, ^H -o u U U u u § ^ ^ ^ B 4-)
o
-H
S^
(d
4-)
d g H o u
o M ^ s
H
d)
rH
^ 0)
73
CO
^
4J
^ (U
M o
c
^ o
4H
4H
4-1
4-)
01
^tn ^tn
Di H rH
•H rH Xl
X3
•H
tn
tn
^
-H XJ
xl
u
'd
p O
o
o
tn
^ ^ c o *^
g
p fe
s cq
U
(0
a ^
o
>
•H
4-)
r 1
0)
^
(1)
Cn
T5
4-1
M
B o
•H
m
-r-(
OJ
QJ
>
>
H H 4J
4.)
^ 1
^ '
M o ^u § '
a
^
p
4^
u
4!3
^ s '
1
B 1
•H 1
S s
4H Ti 13
Q)
(ri
T!
g K o u
U
^ 1
d
o 4J
1
^^
rH
W
13 (0 4-1
t3 1
1
OJ r-\
^
4-1
CO •'^ 1
-H
0)
4-)
tn
X!
CO
1
•n
4H H 4J
5!
M o rH O u
Xu
2!
13
S-l
>1
4H (U
CO CO
1
>!
-H rH X! •H
'd '3
u
u
4J
X!
o
^
nJ 4-1
d
-d
^
4H 1
tn
tn H rH
(U
XI
tn
•^
rH Ti x^ g
O
n o
4H
1
4J
XI
tn
U
fi
1
H Htn ^ 1
4-)
4J
XI
X^
4-1
X!
4J
tn
tn
•H
x;
H o u OJ
^u
1
_ 3 o
0)
•H rH Xl tn
tn
-H
-H
XI
Xl
1
>i
1
CO
n 13
.g 1
1
M
Appendix A: Configuring Widgets with configure and cget
314
u 3
u 3 13
> 4^
c V h
CU
0)
u
u
(d
(d
1'W 1o
^
4-)
4-1
4J
4J
3 u fc
U
-d
rH
OJ CO
(rt
iH (fl
rH
iH
M
g f^ o a
3
m
U
14H
0)
0)
-d
T)
4H 4J
d
5? T-K
^
n
p9
1
^
o o
o
rH
^^
4->
in
CO
CN
^
0)
u 3
V
—3 rt
> 3
u (d
1 1 v^
4-)
1 4J
4J
4J
PQ
(jQ
3
ri H
vJ2
8 o
M-l
dJ
(1)
fe
-H
4J
0)
rH
(d
5
0)
y 3 d 5 -d
-H 13
4-)
> 4J
rH
W
0)
i
J A 4J
A:;
u
CO
^4
4J
4J
u CD
c c
1
CO
.9
a
8 o
4-1
o
0)
rH (d
(0 1
HH 0)
•H rH 4J
(d CO
1
1
>
4-)
4-)
1
1
^4
A
1
rH
4-)
%
0)
04 1
0) 4-)
5
0)
-H
'd
(d
u a 3 3 O
^
8
-d
M
0)
AJ
U
^d iH
5
Ti
-d •H
3 o
a
H.
o
s>
0) CO
-H
M O
4H
CO
o rH o
C O U
^ 6
a
^di 4.)
^bi •H
^
•H
3Cn •^
1
0)
T)
Ai
O
iri 1
^
^ ^ ^ ^
§
4J
5 •H
^ ^ 1
316
Appendix A: Configuring Widgets with configure and cget
4J
a
O
to
mo
W M
-H
(U
M-l
u
T^
o
u o
o
Io
Iu
Iu
1 Q)
d
1O
O •H
u
4->
U
D>
(0
o
c o
0)
u o
a
O
T)
•H JJ
u
a
o
I
u
5 s
5'
Default Values for Each Widget in Table
Form
317
u 3
S
1
1
rH
(d
1
1
Appendix A: Configuring Widgets with configure and
320
4-)
u 3
0)
a
(C
ca 4-1
u
^
t
M
o
C u 3
4-1
S 00 ^"^ u
•g
0)
5/
4->
4J
m u
M-l
4-1
^ -g
i 4-1
4-1
•H
3
Id
0)
•H '3
"3
rH
(d
rd
-d ca 05
u M
1
r-l
•H
c i 4-1 (1)
^
>j
-H
'3
rH
a a
S
S
to CO
u
1u
1
M
U
c c o •o
a
^^ ^ H
5
'd
4J
-d •H
^
^u ?
o Ot
1u
-S ll
S 1
g
1
1
u
4-)
)~i
4J
^
a
^ V
i
•H
^ i13 a a
•H
-H 1
(U
rH
T)
1
1
'S
^
•H
§
4J
B
4J
4J
4J
1
1
1
•H rH 0)
a 1
1
Default Values for Each Widget in Table
Form
321
4->
o
x>
3
CQ
MH
'B
>
CO 4^
4_)
a u k4
Eh
^
u
u r-i 1
W m rH
O o
^
4-1
-H 0)
CO
u 3
> 3 rt
u
Q rH 1
o o d
V s rS c
^ m
f1
u H rH
Vh
^
(1)
J-)
v.
Tl -H
r^
'^
T)
4-)
(1)
c«
% hJ
Pi frt
D s ^
a u
t:!
C^
a («
ii
3
S
S
Eh
u 3
V 3
4-)
a >
•S.
Cn
13
>
•H
e
^
rj
c u H 3
Cn
•H
s
y
u
g 4J SP
iH
U
0)
MH ii '§
^ o
^ ^ o
MH
O
J '2
4H Jj •O
H 4J
4-)
^Cn
X! Cn
•H
•H
rH
^Cn
rH Xi
•H
•H
di
s
"5
S 4J 5P
13 •H
g
^u
0)
^ o
m >
•H
-H
•H
4J
4.)
4J
(0
^
1
'
^ '
O
1U
}H
rH
H g
^
-9
'S V4
^ s s ^ 1
MH
-H
a;
>
1 o
5 d
13
'
1
1
O
4-)
tH
^cn
fl
5 5 M
S
Eh
i 3 ^U Q
u
4-)
§i
u 3
§
0)
1
4-)
a o
cn
1
MH
14H
1
'
Default Values for Each Widget in Table
Form
323
u
u
Ti
1 u
'^
^ X c>
^ a
fl)
IH
O
fa d)
(1)
> -H
H>
4->
4-)
C) (C
t) (0
"d
'd
^^ s
s
'^
T?
^ s s •^
O
o u
s
^
324
Appendix A: Configuring Widgets with configure and
W W (U
4-1
-H
U
rH Xi CO
'd
1 u O
"^ 4J
-a 0)
rH
H iH
•H
H
^D) ^Di
^
CO
m
'^
u
& 4-)
9^
1
s
u o
-H
% 3
'd
^
f?
OJ
rH 0) -1
^
If)
;c!
h-1
•H
4J
Ui
rH
T)
(Tl
^
t
•g
u
i
c c o
^ 4J
(1)
^
-H
^
rH
rH (1)
A'
1
^
T)
hi
0)
fl
:3
rH
1
^ ^ 4J H -0 1
1
rH Ul
1
I
^
326
Appendix A: Configuring Widgets with configure and cget
V 3
d)
V r^
o 1C ^ V P t 3
£ m u
u
1
r-\
Q C
rH
"3
4J
3
U rH
•^
1
1 5J
Q)
4-)
4-)
fp
5?
^
^
0)
1
1 1 U
'0 1
u
m ij d
-H 4-)
^ rH
CN
^
4J
T)
rH
OJ to
frt
•H
fO r-i 14H
00 rH
rH
rH
n
s
g ^ g
^
MH
5/
Q)
4J
T)
CO
rH
V 3
4J
&
TJ
u
§
Cfl
0)
U
fe
a y>
^u
U
3
4-)
4-)
3 vH
3
o
rH
Q
pQ
PQ
13 4J to
^
w
U
c •H
rH
pQ
Ig
(d
4.)
4J
to
CO
^
^
H
^u
rH
%U 1 o 4J PQ ^tn 4J
^ •U
^ ^ ^ ^
^
u
U
>i M-l
&
CO CO 0)
B u
?
328
Appendix A: Configuring Widgets with configure and cget
4-)
C o
^
1c u jj
5 o c
to
o
CO 4J
^
4-)
rH
T) •H
•a
X
Ai
4J
73
CO
O
g
rH
^u *H
•H
r-l
CN
cn 0}
•H
4-)
4-)
AJ
OQ 4J
en
4-)
m
B o
V g
1
)H
73 -H
CJ
4H
4-)
>i
^ 73 a a
0)
u
-H rH
rH
0)
0) 0) (0
4:3
73
4J
73
73
u
1
•H 4J
c c o
U
5
73
O
^U
0)
^ o
n3
CQ
M
4-)
u 4J
Qi Cn
I
1
1
1
^
M-l 1
1
1
a o
M 1
§
(U
4-)
k
4J
•H
-H rH Xi D)
3M 5
H
3Cn
4-1 1
CJ
3 > U
1
1 ^Di 0)
O rH O u
•H
4-)
73
0)
iH
tj •H
>H
1
11
?l
OJ to
•H 1
1
1
'i->
>H 0) to
.2 1
4H 4H
1
1 S 73 4->
CJ
4-)
4-)
^
1U
4H
U
(U
u
0) to
0) to
0) to
-H rH
rH
C!
c
2
0) to
•H 1
•H 1
'§
^
-H 1
1
1
1
^
0)
1
Default Values for Each Widget in Table
Form
329
XJ
s Eh
u 3
^
IS
•H rH 41
V 3
4-)
u
1a
tn
•H
U
MH 4-)
W
f^
o ^ o o o
d
8
MH -d
B
00
MH
0)
0)
Ti
TJ
u (0
^
?^
4J 4J
u 3
•i
U
rH
0)
rH
4J
rH
a g
W
1
C^
0)
-d
B
4J
S tn -y
u 3
(U
u 3
^en •H
? 3
! 1
:3
3
^ H
!
0}
^
o
O
u ^ ^01 ^01 4->
4-)
•H
•H
rH Xi
rH
•H rH
4-)
H
^d) •H (U
Ho
^01
^
-g
i
Q)
^
u o •-\ o
01
H
b K X
^01 ^01 •H
m
g u
o
c
>;
-H ffi
u o o
u
rH
3
^
4H
4H
Q)
0)
0)
0)
•H
-g
r-H
^ ^
(V
B
B
^
Pi
8 o
r-i
b
4H
d)
0)
^ M Eh
'S
s a> u u
B
(0
3 a) CO
Xi
V
CO
-d
•H
•H
D > S
1u *H
-g
g
^
u ^
u
o
o
S
^ S
-H
•H
•H
fe
§,
rH
rH
Q)
0) Vh
rH jd 0)
•^
•^
CO
0)
4-)
9^
4H 4H
U
X3
^
CO
o w 6
U O 4-1
o 4-1
di
H ^
0)
8
01
^01 ^01
4H
3
4H 0)
g
4H iJ -g
•^
4H J^ TJ
•H
B
S
0)
rH
s (U u u
o
rH 4-1
QJ
(0
3
J^
c 4-)
0) CO
CO
3
>
§ TJ •g
w V
u
i
H
^Qu
M 5^
4H 0)
% ^ ^ p,
•H rH
s U V
s o 0)
0)
rH 4-)
CO 1
1
rH
4H
1
3 0)
CO
•H
•H
4-)
>
1
1
1
i -d 1
operating System Differences
Perl
was
Unix systems. The Tk module was meant
originally written for
X Window
with the
System, which
is
the graphical user interface associated with
Unix. Since then, Perl has been ported for use
on many other
platforms, including
Macintosh and Microsoft Windows (both 95 and NT). The same
module, although the ports for
have Perl available on
all
it
for use
followed along a
bit
more
is
Tk
true of the
now we X Window
slowly. So
platforms and Perl/Tk available for both the
System (which can be emulated or run on many different platforms) and Microsoft
Windows. There are very few differences between
Window System and how ences
come about because
functions that the
how
Perl/Tk operates on the Unix
Microsoft
X Window
Windows
doesn't have
System has. Throughout
this
all
of the different
book, you
may have
seen references to a method that didn't work on Windows 95 or that worked ferently
One
on Windows
big
Appendix
difference C,
Fonts,
95.
I
X
operates on Microsoft Windows. Most of the differ-
it
won't be covering
all
dif-
those minor differences again.
between Unix and Windows
is
how
to
specify
fonts.
covers font specifications in detail; see that appendix for
information for both Unix and Windows.
Unix book should work well under Unix systems. There might be subtle differences between the different flavors of Unix (such as what type of value you get back on a Solaris machine compared to the values you get back on a Linux machine), but nothing that will cause your program to crash.
All of the
methods
All of the
screen shots for
listed in this
system running the
this
book, except where noted, were taken from a Linux
X Window
System with Motif-style windows. The
window
331
Appendix B: Operating System Differences
552
manager I
used
I
was fvwm, but
specifically
don't cover the differences
style of the
dow
the style of
windows
between window managers and
window. There are many other books
System and the window managers
it
is
how
similar to
mwm.
they change the
available that discuss the
X Win-
uses.
Windows NT and 95 When you
window
create a Perl/Tk
comes up looking For instance,
it
will
have a small x
cation. Just to the left of that
To
the
left
for
x
all
of the Maximize button
be a small button
X Window
window
95, the
that
maximizes the window.
a small bar that will iconify the application.
is
that gives options to minimize,
standard features of an
in the
Windows
or
in the upper-right corner that will kill the appli-
will
In the upper-left of the application
menu
Windows NT
your other windows do for those operating systems.
just like all
is
a small "Tk" that,
clicked, will display a
if
maximize, or close the application. These are
MS Windows window. The same
System version of a Tk application;
it
functionality
just
looks a
is
little
present
different
(see Figure B-1).
Exit
Exit
Figure B-1.
Exit
A Win52 window and an X Windows window
Windows 95 Problems I
used both a Windows 95 machine and a Windows
NT
4.0 (Service
Pack
3)
some minor problems running applications under Windows 95. Windows NT did not seem to have the same problems, so if I had a choice between 95 and NT, I would develop and run Perl/ Tk on Windows NT. Here is a list of some of the problems I ran into while I was testing Perl/Tk applications under Windows 95 (note that these are not necessarily reproducible 100% of the time; I just wanted you to be aware that I did run into some minor problems): machine
•
I
created a
click •
to test the
on the
code
in this
book.
MainWindow with one
I
did find
button, resized the
window, and couldn't
Exit button.
The same scenario as the preceding after it was resized caused the button
item; clicking to
be pressed.
anywhere
in the
window
Windows NT and 95
•
When
I
333
tabbed between applications, clicked in another application, and then
went back
to the
icon in the
start
Tk app,
it
didn't recognize the
bar seems to
(There doesn't seem to be any solid
fix this.
reproducible cause and effect for loss of •
The -underline option doesn't seem underline a as a
•
menu
letter in a
mouse. Clicking on the app
mouse
to
recognition.)
work properly when
I
attempted to
option, so the corresponding key could be used
keyboard shortcut.
Some methods (most
of which you wouldn't use because they are obscure)
These were noted throughout the book as
didn't return a reasonable value.
they were discussed. •
When
I
clicked in a text widget to give
it
the keyboard focus and then clicked
elsewhere, the text widget didn't give up the focus. switch between widgets within the doesn't
seem
and won't •
When
I
to
want
to give
up
window once
the focus (the cursor stays as an
interact with the button at
tried to display a
option), the
photo
You can use
as
Shift-Tab to
text has the focus, but I
it still
bar cursor,
all).
an image
in a button (by using the
-image
photo looked garbled.
Other than these minor problems, most of which probably wouldn't apply to a run-of-the-mill application, everything
worked
well.
Selections
X Window
System, the user can select text by simply highlighting it. In Windows, you have to highlight the text and put it in the clipboard by typing CTRL-C (for Copy), pasting it back with CTRL-V or the equivalent for the In the
Microsoft
application you're running. Perl/Tk does not interact with the clipboard like
this.
There are several widgets that have an -exportselection option (such as
list-
box and text) and still work as indicated; if they won't copy the selected text to the clipboard.
are set to zero, however, they
Fonts
This appendix describes
how
to use the
new methods
in
TkS.O to create and main-
-font option. You can still some methods to create your own named fonts and perform operations on them. First I'll go over the simple way to use a font string, which works in both versions. Then we'll get into the more comtain fonts. In Tk4,
you could only pass
a font string to
pass a font string in TkS.O, but you can also use
plicated
methods
available with TkS.O.
The Font String When cates •
there
which
Specify the
explained •
•
name
you need to pass ways to specify a font
for a widget,
a string that indistring:
fontCreate method (fontCreate
of a font with the
later in this
Use the name of in
is
chapter in "Font Methods").
them and
can be interpreted by the graphics display
a font that
Unix system running
X Windows).
are very hard for
specify a font in a string,
your system.
334
-font option
Use a string that describes the font and follows a predefined format (see Appendix B, Operating System Differences); for example, "Times 12 Normal."
cally a
To
a
is
font to use. There are several
you
humans first
to
have
These
strings usually
have
(typi-
asterisks
comprehend. to
know which
fonts are available
on
335
The Font String
Determining Available Fonts In Unix,
you must specify
by using
fonts
a long, drawn-out syntax with a lot of
asterisks that represent families, size, type,
you can get
a
and so on. In the
X Window
System,
command
of Unix fonts by running the
list
xlsfonts > font_file
The file named f ont_f ile will now contain a huge list of fonts that you can use on your system. Be careful when picking fonts from this huge list. If you are going to be running your application from more than one system, the font you pick might not be available on all systems. you use Microsoft Windows, you'll have a different way of seeing what fonts are available. Click on the Start menu and select Settings -^ Control Panel. Once the Control Panel appears, double-click Fonts and a window similar to the one shown If
in Figure C-1 appears.
i\
Anal
Italic
13
Arial
Narrow
j] Bookman Bookman
^
Old Style
Q
Arial
Narrow Bold
|t|
Buccaneer Regular
|r] Antique Olive Bold
1'^ Arial
Narrow Bold
|%1 Antique Olive Italic
ffl Arial
Narrow
S Q @ 3
@
j^iAlbertus Extra Bolcl
Medium
I't]
Albertus
Q
Antique Olive
92
Aria!
Vt\ Burton's
Italic
N]
Italic
Nightmare
Celtic Gaelige
Regular
Black
gBard
Bold
[^Bookman
Old Style
gCG Times Bold
[^ Bookman
Old Style Bold
^ CG Times
Italic
;
Century
Arial
Anal Bold
Italic
Schoolbook m M CG Times
augie
Bold
Italic
font(sl
95 System
system has most of the standard fonts and a few that
Internet,
Old Style Bold
Aria!
Figure C-1. The Fonts from a Windows
My
Sirrilatityl
to specify them.
If
I've
downloaded over the
want to use these fonts I have to know how you double-click on a font name, another window appears and
such as augie and Bard.
If
I
displays detailed information about the font (see Figure C-2).
The information about
the font includes
drive (64K in this case), sizes.
The
Arial font starts at 12 points
option to specify
name
what version
of the font
this font for a (Arial),
it
how much is,
and
its
and goes up
space
name.
it
It
takes also
to 72 points.
up on
lists
To use
the
widget (for instance, a button), you need to
the size,
and the type (normal,
bold, or
the hard
the available
italic).
-font
know
the
With these
;
336
Appendix
B Aiiai (TiueType)
C:
Fonts
«FF^
Done
Rtint
Arial (TrueType) Typeface name: Anal
Version:
64 KB MS core font: V2. 00
Typeface
© The Monotj^e Corporation pic
File size;
Data © The
Monotype Co
ab c d e fg h
ij
kl
mnopq
r stu
vwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
J
1234567890.:, ;("*!?') 12
The quick brown
18
The quick brown
24
The quick brown
fox jumps over the lazy dog.
fox
jumps
V.
ovi
fox jur
Figure C-2. The Arial font details
three pieces of information, That's
all
there
is
to
it.
To
you can build a
font string:
"Arial
create a button with this font, use the
$nTW->Button(-text => "Exit", -command => siib { exit -font => "Arial 24 normal ") ->pack ()
24 nonnal' -font option:
},
Figure C-3 shows a button with the default font, and one with a larger font.
Figure C-3-
If
the
A
name
default size font button
and one
of the font has spaces in
the string the
it
with Arial
24
such as Times
New Roman, you
still
build
same way:
-font => "Times New Roman 12 normal"
* "
You might
also see a font specified with curly braces
{Arial} 12 {normal}
").
The
around the name and the
curly braces arc not required.
style of the font (e.g.,
Font Methods
You might
337
see an error on the console
when
using
this
type of font specification:
SplitString 'Times New Roman 12 normal' at script line
You can
7
I know, there is no easy way to get rid Tk module will deal more gracefully with this error no longer appears).
ignore these errors, and as far as
of them. Hopefully, later versions of the this (initial tests
I
don't
with Tk 8.0
recommend changing
because
you'll
that
on any of the standard widgets is available. The only place the text widget, and then only if
the font for the text
have to worry about whether the font
you might absolutely have you
show
to
change font
is
in
are actually going to format the text.
One more
thing:
There
is
a Tk::Fonts
module
available, but
it
doesn't
work
cor-
under Microsoft Windows (95 or NT). If you are using X Windows, you should play around with the Tk::Font a bit; it does have some useful features. rectly
Font Methods The following methods which contains Tk8.0.
are available only with the newest version of Perl/Tk,
Create The f ontCreate method
creates a
$widget->f ontCreate
$naine =
( )
new
font.
;
$naine = $widget->fontCreate(for2tr2an7e)
You can where
either specify a font
X is
a
name
or
;
one
will
number. You can specify options
be generated
in the format "fontJ^f
for the font:
$name = $widget->fontCreate(-size => 12); $name = $widget->fontCreate(fontname, -size => 12)
The options you can use
to create a font are as follows:
-family => name The family name can be "courier", "times", or "helvetica". If you specify one of these, the closest match on your system will be used. You can also specify the
name
of a font that
"Moon Runes"), but
it
-size => amount The amount specified for the be. If the amount is positive, negative, the font will pixels.
is
specific to
your machine
(for
example,
might not show up on other systems.
how
you want the font to If the amount is be sized by using the absolute value of the amount in font size indicates
big
the font will be sized in points.
;
;
;
;
;
338
Appendix
-weight => "normal" "bold" The -weight option determines
C:
Fonts
|
the thickness of the font.
-slant => "rcatian" "italic" The slant of the font is how far it tips over to one side. By default, "reman" means that the font is upright. Specifying "italic" as the value for -slant |
will
the font to the right slightly.
tilt
-underline => If you want
1
|
the characters to be underlined, specify
1
for the
-\inderline
option.
-overstrike => 1 A line is drawn through |
the text
when -overstrike
has a value of
1.
Configuring You can change
by using the fontConf igure configure method does on any widget:
the options associated with a font
method. This method works
just like a
%optionsNvalues = $widget->fontConfigure(fontna7ne) $value = $widget->f ontConf igure (fontname, -size) $widget->fontConfigure(foI:tJ:ame, -size => 24); # Change size to 24
You can use
the
same options with
f ontCreate
and fontConf igvire.
Actual Information If
a specified font size
another font is
size, or
actually displayed
and
their values, call
is
not available on the user's system, the system substitutes
even
a different font altogether.
You can
by using the f ontActual method. To get f ontActual with just a font name:
find out a
list
of
which font all
options
%vals = $widget->f ontActual (fontname)
To
get the actual value for just
one option:
$value = $widget->fontActual(fontname, -size)
Again,
the options used in f ontCreate can be used with f ontActual.
all
Deleting To
one or more
delete
fonts,
use the f ontDelete method:
$widget->fontDelete(fontname) $widget->f ontDelete (fontl, font2) If
the font
the widget
with the the
new
is
currently being used
isn't
name
using
it
anymore.
;
by a widget, If
you
it
will not actually
re-create a font
be deleted
until
by using fontCreate
of the original font, the widgets that use the original font will use
font information.
Font Methods
339
Text Size You can
find out
how much
space a text string that uses a particular font would
take by calling f ontMeasure.$pixels = $widget->f ontMeasure (fontname,
The value returned
$pixels
into
is
texts tring)
;
only an estimate because characters such as
"\t" or "\n" aren't expanded before the measurement
is
taken.
Font Metrics between lines, and fontMe tries method to fontMetrics with only a font
Metrics are details about a font: the ascent, descent, space
whether or not the font
is
proportional.
get this information about a
name
you
gives
all
named
You can use
font. Calling
the
the metrics and their values for that font:
%values = $widget->fontMetrics (fontname)
You can
also find out the value of a specific metric
$value
Note
$widget->f ontMetrics
=
you cannot change
("
fontname"
,
by passing
it
in as
an option:
-ascent);
They
when
the font
is
Measures the highest part of the font above the baseline. Amount returned
is
that
a font's metrics.
are calculated
created.
The
valid metric options are as follows:
-ascent in pixels.
-descent Measures the lowest part of the font below the baseline. Amount returned
is
in
pixels.
-linespace Measures the distance between two
Amount
returned
is
lines
of text that use the
same
font.
in pixels.
-fixed Returns
1
if
the font
is
amount of space, such
a fixed width font
(all
as in Courier). Returns
characters take if
the font
up
is
(each character takes up a different amount of space based on
skinny
it is;
the letter
"I"
takes
up
less
space than "M").
the
same
proportional
how
fat
or
;
Appendix
3*^0
Families
& Names
To
all
find out
the font families that exist
on
To determine
=
$widget->f ontFamilies
the
names of
all
( )
;
the fonts that are defined, call f ontJSFaines:
©names = $widget->fontNames
()
Fonts
a particular $widget's display, call
fontFamilies: ©families
C:
Index
Symbols ,
-
menubutton widget, 222
(comma), 6 (minus sign), 36-37
overview, 52 pack, 19 place, 48
=>, 6
\
radiobutton, 96
36
195
text item,
A
anonymous
appearance, widget (see
accelerators, 231 activate
method, 150
add method, 243-244 adding text, 197 Addltems method, 227, 234 addtag method, 201 Advertise method, 285 after method, 306 afterCancel method, 307 afterldle method, 297, 307 aligning text, 178
style)
application grid,
activating scrollbar elements, 136
all tag,
subroutines, 63
267
name, 265, 295 applications, communicating among, 304 appname method, 295 arcs creating,
option
188
188-189
list,
arrows line item,
191
scrollbar,
132
aspect method, 262
199
allocation rectangle, 22-28
expanding, filling,
Alt key,
19,
assigning) 19,
25
24
274
anchoring widgets allocation rectangle, 27
basic button, 58
bitmap item, 190 checkbutton, 83
createWindow method, 198 image item, 191 label,
103
assigning callbacks (see callbacks,
atom, 300 (see also widgets,
name)
atom method, 300
atomname method, 300 automatic
window
resizing, 32
B background color (see
color, options)
basic button
anchoring, 58
341
342
Index
basic button ^continued)
anonymous
subroutines, 63
bisque method, 293
bitmap
border width, 58 callbacks, 58, 62-64
189
creating,
displaying
color options, 58-59, 72-74
bitmap item, 190
configuring, 79
checkbutton, 84
creating, 57
label widget, 103
cursor options, 58
menubutton widget, 222
disabling, 64
radiobutton, 96
item option
displaying
list,
images, 59, 61
options, 190
text, 60,
setting
(i(i
name and
location, 58
(see also image)
79
flashing,
189
border width
focus, 59 font, setting, 58,
66
basic button, 58
height, 59
canvas widget, 186
invoking, 79
checkbutton, 84
keyboard mapping, 72
entry widget, 109 frame widget, 252 label widget, 104
naming conventions, 12 option
list,
58-60
padding, 59 relief,
size,
listbox,
menu
59
143
widget, 239-240
menubutton widget, 222
70
state,
59
radiobutton, 96
style,
68
scale widget, 211
59
justification,
text
wrapping, 60
tags,
underlining characters, 59
toplevel widget, 258
width, 60
bbox method canvas widget, 183, 202 listbox,
bounding box, 151 (see also bbox method) browse mode, listbox, 144 buffering, space, 38
151
Button method, 57 button (see basic button, checkbutton, or
text widget, 173
method, 300 bind method, 270-272 canvas widget, 184 bell
radiobutton)
ButtonPress event, 276
ButtonRelease event, 276
label widget, 107 listbox,
164
widget, 155
variable options, 59
152
c
uses, 280
using with text tags, l68 valid
129
scrollbar,
text
argument
list,
271
binding events, 270-280
items using tags, 201
bindtags method, 280
callbacks
arguments sent back, 272 assigning basic button, 58, 62-64
canvas widget, 187 checkbutton, 83-84, 87
Index
343 entry widget, 111
scrollable region, 183
menu
scrollbars with,
widget, 239, 241
138
radiobutton, 96
scrolling options,
scale widget, 211, 213
tags,
text indexes with,
130, 133
scrollbar,
uses, 181
text widget, 157 bind method, 272
width, 187
canvasBind method, 184, 201 canvasx, canvasy methods, 202
stop processing, 279 (see also subroutine)
Caps Lock key, 274 Perl)
Canvas method, 182 canvas widget, 181-209 adding
caret symbol, 36
cascade
menu
adding, 235 item, 229
194
text,
cascade method, 235
188
arc item,
196
translating coordinates, 202
selection, 301
Camel book, 64 (see also Programming
185
199-201
bind method, using, 184
cascading menu, 247
binding, 201
cells
method, 292
bitmap item, 190
cget
method
bounding box coordinates, 202
basic button, 79
callbacks, assigning, 187
canvas widget, 198
color options, 186-187
entry widget, 118
configuring, 198
format, 311
coordinate system, 182
frame widget, 256
creating
label widget, 108
bitmaps, 189
listbox,
canvas, 181
menu
147
widget, 243
cursor options, 186
menubutton widget, 233 optionmenu widget, 249
deleting
overview, 309
188
items,
radiobutton, 100
items, 203 tags,
display
204 list,
scale widget, 2l6
changing, 203
scrollbar,
134
example, 206
character spacing (see marks)
focus, setting, 187, 204
checkbutton, 81-93
height, 186
anchoring, 83
indexes, text item, 196
bitmap, displaying, 84
inserting other widgets
in,
197
border width, 84
item type, determining, 204
callbacks, assigning, 84
items, moving, 202
color options, 83-85
line item,
option
configuring, 92
191
list,
184-187
creating, 83, 234
oval item, 193
cursor options, 84
polygon item, 194
flashing, 93
rectangle item, 194
focus, 85
relief,
187
scaling,
font, setting,
height, 84
205
scroll options,
187
84
544
Index
label widget, 103-104
checkbutton ^continued) image, displaying, 84, 90
line item,
indicator
listbox widget, 143
color, setting,
menu
89
192
widget, 239
displaying, 84
menubutton widget,
hiding, 89
oval item, 193
storing status, 85
postscript method, 204
222, 225
invoking, 93
radiobutton, 96-97
on and
scale widget, 211-212
option
off values, 88
83-85
list,
overview, 81
129-130 195
text tags, l64
85
relief,
scrollbar,
text item,
155-157
state,
85
text widget,
style,
91
toplevel widget, 258
text justification,
turning
on and
84
off,
scrollbar,
93
underlining characters, 85
130
setting for application,
count, 292
width, 85
cell
with menubutton widget, 228
determining
wrapping text, 85 Checkbutton method, 83 checkbutton method, 234
circle tag,
frame widget, 252 204
postscript,
toplevel widget, 259, 266
problems, 255
Colormap
199
292
if full,
options
child widgets, 6, 290
children method, 290
293
colormap
event, 276
Circulate event, 276
colormapfull method, 292
method, 291 with frame widget, 256 client method, 265
colormapwindows method, 266 columns
class
classes,
clipboard, manipulating, 300
clipboardAppend method, 300 clipboardClear method, 301 Cmd-Line method, 306 coding
style,
setting,
38
spanning, 37-38 (see also grid)
comma, 6
command method,
234, 266
command-line options, 306 communication among
8
color basic button, 72-74
applications, 304
corruption, 255
widgets, 133
depth, 253, 259, 292
compare method, 173
highlight rectangle, 78
composite widget, 281-289
listbox,
advertise, calling, 285
145
options arc item,
alias, creating,
188
286
configure, calling, 286
on
basic button, 58-59
creating based
bitmap item, 190 canvas widget, 186-187
defining options, 287
checkbutton, 83, 85
example, 282
entry widget, 109-110
frame widget, 252
a frame, 284
delegates, calling, 286
file
location,
283
ConfigSpecs method, 286
345
Index
counting items in a listbox, 150
Configure event, 276
method
configure
createArc method, 188
basic button, 79
createBitmap method, 189
button widget, 313-314, 316-317,
createlmage method, 190
319-323, 325, 327-329
createLine method, 191
canvas widget, 198, 312 checkbutton widget, 316
createOval method, 193
entry widget, 118,317
createRectangle method, 194
format, 309
createText method, 194
frame widget, 255-256, 319 label widget, 108,
320
147
listbox,
createWindow method, 197 creating
basic button, 57
listbox widget, 321
menu
createPolygon method, 194
widget, 243, 322
canvas widget, 181 checkbutton, 83
menubutton widget, 221, 233 optionmenu widget, 249
entry widget, 109
overview, 309
label widget, 103
frame widget, 251
radiobutton, 100
listbox,
radiobutton widget, 323
menu
scale widget, 21 6, 325
menubutton, 220
scrollbar,
optionmenu widget, 248
134
scrollbar widget, 327
328
text widget,
141
widget, 238
toplevel widget, 329
ovals,
193
polygons, 194 radiobutton, 94 rectangles, 194
configuring basic button, 79
scale widget, 210
canvas widget, 198
scrollbar widget, 128
checkbutton, 92
text widget,
entry widget, 118
toplevel widget, 257
label widget,
menu
108
widget, 243
menubutton widget, 233 optionmenu widget, 248
widget, 6-7 current tag, 199 curselection method, 149
cursor
radiobutton, 100
changing, 75
scale widget, 216
insert,
scrollbar,
127, 134
toplevel widget, 260
154
115, 119
options basic button, 58
Construct method, 284
canvas widget, 186
container
checkbutton, 84
frame widget, 252
entry widget, 109-110
frames, 107
containing method, 297
frame widget, 252 label widget, 104
Control key, 274
menu
coordinate system, canvas widget, 182
menubutton widget, 222
coordinates
radiobutton, 97 scale widget, 211
event, 278 setting,
48
translating,
widget, 239, 241
scrollbar,
202
coords method, 202, 2l6
130
text widget,
156
toplevel widget, 259
346
Index
cursor {continued)
double modifier, 274 dtag method, 204 dynamic document list, 236
positioning, 196 setting
143
listbox,
text widget,
155
embedding widgets, 176
D
enlarging widget, 38
databases, option, 293
Enter event, 276
debars method, 196
entering passwords, ll6
debug function, 179 debugging code, 13, 179
Entry method, 109 entry widget, 108-123
defining event sequences, 273
assigning content to a variable, 111
deiconify method, 258, 262
delaying a program, 306
border width, 109 color options, 109-110
Delegates method, 286
configuring, 118
delete method, 172
creating,
canvas widget, 203 entry widget, 118 listbox widget,
menu
148
widget, 243-244
172
text widget,
deleting text, 118
determining contents, 119 focus. 111 font, setting,
110
indexes, 112-114
deleting
items from
inserting text, 120
canvas widget, 203 listbox,
menu
109
cursor options, 109-110
option
list,
password
148
items, 244
relief,
109-111
110
tags,
204
relief options,
text,
118, 172, 196
scrollbar use,
text tag,
170
state,
method, 136 deltag method, 204 delta
116
entry,
112
117
110
text justification,
demo, widget, 72
selecting,
depth method, 292
110
114
translating index values, 119
deselecting radiobuttons, 100
uses,
designing windows, 14
variable options, 111
Destroy event, 276
width, 111
destroy method, 302 destroy versus
exit,
108
with
12
listbox,
destroying widgets, 302
152
scrollbars,
137
Dialog widget, 281
entrycget method, 233, 243
disabling buttons, 64
entryconfigure method, 234, 243
display
list,
changing, 203
displayed values, 214
Ev method, 278 event button number, 278
displaying
menus, 245
coordinates, 278
widgets, 9
defined, 9
distances, screen, 295
height, 279
dlineinfo method, 173
keyboard information, 279
document
loop, 10
list,
dynamic, 236
347
Index
sequences, defining, 273
font, setting
type, 275, 279
basic button, 58
width, 279
checkbutton, 84
Exists
method, 295
exit versus destroy,
entry widget, 110 label widget, 104
12
exiting the application,
12
expanding allocation rectangle, exporting
listbox, 19,
109
text,
Expose event, 276 extended mode, listbox, 144
25
menu
143
widget, 239-240
menubutton widget, 222 postscript method, 205 radiobutton, 97 scale widget, 211 text
fileevent
item, 195
method, 305
tags,
l64
filling
allocation rectangle, 19, 24 listbox,
156
font string, 334
14
find method, 201
finding tags, 201 flash
text widget,
method,
79, 93, 100
flashing
basic buttons, 79
checkbuttons, 93 radiobuttons, 100 focus
fontActual method, 338
fontConfigure method, 338 fontCreate method, 334
fontDelete method, 338 fontFamilies method, 339
fontMeasure method, 338 fontMetrics method, 339
fontNames method, 339 fonts
basic button, 59
canvas widget, 187 checkbutton, 85
configuring, 338 creating,
338
families,
339
entry widget. 111
frame widget, 253, 255 label widget, 104 listbox,
widget, 239
menubutton widget, 223 options, 77
radiobutton, 98 scale widget, 212 scrollbar, setting,
130
204
text widget,
metrics, 339
specifying in buttons, 66
144
manipulating, 302
menu
337
deleting,
157
toplevel widget, 259, 267
focus method, 119, 204, 302
focusCurrent method, 303
focusFoUowsMouse method, 303 focusForce method, 303
Focusin event, 276 focusLast method, 303
focusmodel method, 267 FocusOut event, 276
text widget,
157
module, 66 withTk8.0, 334 foreground color (see color, options) fpixels method, 296 fraction method, 136 Tk:: Fonts
Frame method, 251 frame method, 267 frame widget, 251-256 adding a
label,
254
border width, 252 color options, 252
colormap options, 252
problems, 255 creating, 251
cursor options, 252 defined, 7
348
Index
frame widget {continued)
spanning, 38
height, 252
option relief,
sizing text widget,
252
label,
252-253
list,
253
specifying rows
width, 253
turning
on or
and columns, 39
off,
143
grid method, 267
frames, container, 107
functions
157
grid, setting,
method names)
(see the individual
158
space buffer, 38 spanning columns/rows, 37, 39 special characters, 36
253
style,
38
setting,
focus, 253, 255
gridColumnconfigure method, 43 gridForget method, 46 gridlnfo method, 46
geometry manager deciding which overview,
9,
gridLocation method, 46 to use, 56
15
(see also pack, grid, and place)
geometry method, 260, 296 get
method
gridPropagate method,
GUI design considerations, 14 reasons to use, 2
148
scale widget, 216 scrollbar,
H
136
text widget,
251
group method, 268
entry widget, 111,119 listbox,
A(),
gridRowconfigure method, 43 gridSize method, 47
hanging indent, l65
172
getNames method, 175
height
Getopts modules, 306
basic button, 59
gettags method, 201
button, 70
GIF support, 6l grab method, 303 grabCurrent method, 304 grabGlobal method, 303 grabRelease method, 304 grabStatus method, 304
canvas widget, 186
event, 279 frame widget, 252 label widget, 104
graphical user interface (see GUI)
listbox,
graphics (see image)
menubutton widget, 222
Gravity event, 277
postscript
gravity,
checkbutton, 84
createWindow method, 198
mark, 175
method, 205
radiobutton, 97
34-47 columns
setting, place,
grid,
setting,
143
text widget,
toplevel widget, 259
38
widget, specifying, 53
spanning, 38 configuring columns and rows, 42 creating an
empty
48
156
cell,
37
height method, 296
Hello World example
determining widget location, 46
anonymous
getting configuration information, 46
button
options, 38
callbacks, 62
padding widgets, 41 propagation, A6 removing widgets, 46
overview, 10-11
in,
subroutine, 63
57
positioning widgets, 20 highlight rectangle, changing, 78
349
Index
85
status, storing,
iconbitmap method, 263 iconify method, 263
(see also cursor, options) insert
iconmask method, 264 iconname method, 264 iconposition method, 264 iconwindow method, 264 icursor method, 119, 196 id method, 292 ID string, widget, 292 identify method, 137, 2l6 image
method
canvas widget, 196-197 entry widget, 120 listbox,
menu
147
widget, 244
text tag,
166
text widget,
items in a listbox, 147
menu text,
displaying
items, 244 120, 171, 197
installing the
basic button, 59
image item, 191
menu
checkbuttons, 93
in basic buttons, 61
menu
90
items, 245
radiobuttons, 100
label widget, 104
©ISA array, 282 ismapped method, 295
menubutton widget, 223 radiobutton, 97
itemcget method, 199
191
item,
5
basic buttons, 79
item, 232
in checkbuttons,
Tk module,
invoke method, 79, 93, 100, 245 invoking
checkbutton, 84 in a
155, 171
inserting
190
creating,
115, 119
insert cursor,
itemconfigure method, 199
indentation, setting, l65
index method canvas widget, 196
/
entry widget, 119
JPEG
file
listbox widget, 150
jump
scroll,
menu
justification, text
widget, 245
text widget,
172
support, 61
130
basic button, 59
checkbutton, 84
indexes
bounding box, 151 comparing values, 173
entry widget, 110
entry widget, 112-114
menubutton widget, 223
label widget,
radiobutton, 97
147
listbox,
menu, 242 text,
text
196
text widget,
I6I-I63
into numerical equivalent,
195
165
150
K
values, 119, 172, 245
indicator
keyboard
checkbutton, 89
information, event, 279
97
displaying, 84
options, status,
item, tags,
widget, 160
translating
color,
104
menubutton widget,
97
223, 225
mapping, 72 KeyPress event, 277 Key Release event, 277
350
Index
143
height,
indexes, 147
Label method, 103
inserting items,
102-108
label widget,
anchoring, 103
relief,
bitmap, displaying, 103
resizing,
color options, 103-104
scolling methods, 151
container frames, 107
selection options, 144, 149-150
cursor options, 104
turning grid on or
focus, 104
off,
with
image, displaying, 104
entry widget, 152
103-105
scrollbars,
padding, 104
Listbox
104-105
relief options,
138 (see Iistbox)
widgets, 33 lower method, 203
status messages,
106
text justification,
method
listing
104
setting font,
M
104
wrapping, 105 underlining characters, 104
MainLoop method, 257 MainLoop routine, 10-12
MainWindow
103
class,
257
variable options, 104
MainWindow method,
width, 105
MainWindow
Map
labels
12, 15
widget, 7
event, 277
frame, 254
mapping
frame widget, 252
margin, setting, 165
scale widget, 212, 214
markGravity method, 175
keys, 72
LabEntry widget, 281-282
markNames method, 176
Leave event, 277
marks, 175-176
line
markSet method, 176 markUnset method, 176
creating,
191
item options, 191
Smaster, 46
spacing, text widget, 157-158
maxsize method, 261
iistbox,
menu
141-153
active versus selected,
border width, 143 color options, 143, 145 configuring, 147
counting items, 150 creating,
l4l
cursor, setting,
143
150
displaying, 245
indexes, 242 uses, 218
Menu method, 238 menu method, 235 menu widget, 238-250 assigning callbacks, 239, 241
deleting items, 148
border width, 239-240
example
cascading menu, 247
filling,
143
width, 144
height, 104
uses,
144
scrollbar, assigning,
103
list,
146
146
retrieving elements, 148
configuring, 108
option
143
relief style,
border width, 104
creating,
147
options, 142
script,
152
color options, 239
141
focus, setting, font, setting,
144
143
configuring, 243 creating, 238
351
Index
cursor options, 239, 241 deleting
menu
items, 244
metrics, font, 339
minsize method, 261
example, 247 focus, setting, 239 font, setting,
methods (see the individual method names)
239-240
indexes, translating values, 245
menu invoking menu inserting
minus
sign,
36-37
modifier, 273
modules, Perl/Tk
items, 244
Getopts, 306
items, 245
Tk::Dialog, 257
item type, determining, 245
Motion event, 277
option
mouse cursor, changing, 75 move method, 202 moving items, canvas widget, 202
relief,
style,
239
list,
239 240
menubar, creating, 236 Menubutton method, 220 menubutton widget, 219-238 accelerators, 231
multiple
application, 265, 295
border width, 222 cascade menu, 235 item, 229
checkbutton item, 228 color options, 222, 225
command
145
name
bitmap, displaying, 222
menu
listbox,
TV
anchoring, 222
cascade
mode,
widget, determining, 291
name method,
291, 300
naming conventions, widget, 12 nearest method, 151
new method,
257
next method, 303
item, 227
configuring, 233 creating, 220
o
cursor options, 222
offsetting text,
examples, 236
on and
focus, setting, 223 font, setting,
222
l65
off values
checkbuttons, 88 radiobuttons, 98
height, 222
OnDestroy method, 305
image, displaying, 223
operating system differences, 145, 331-333
indicator options, 223, 225
option databases, 293
items, adding, 234
Optionmenu method, 248 optionmenu widget, 248-249
option
list,
221-224
padding, 223
configuring, 248
radiobutton, 235
creating,
radiobutton item, 227
overview, 281
relief,
248
ordering widgets, 29
223
separator, 235
organizing widgets (see geometry manager)
separator item, 231
orientation
state,
scale widget, 212-213
223
scrollbar,
text justification,
223
wrapping, 224
130
oval item options, 193-194 ovals, creating,
193
underlining characters, 224
overrideredirect method, 268
width, 224
overstrike, l65
Meta key, 275
owner, determining, 302
352
Index
quitting,
allocation rectangles, 22-28
anchoring widgets,
19,
using in Perl
27
Unix, 331
widgets, 33
Windows, 332
19
list,
ordering widgets, 29
overview, 9
packing order, 19 padding widgets, 19, 29 positioning widgets, 20
Photo method, 6l pictures (see image) pixels method, 295 place, 47-56 absolute coordinates, 49
anchoring widgets, 52
screen distances, 31
getting configuration information, 55
sizing text widget, 158
unpacking widgets, 32 with frame widget, 251 packForget method, 32 packlnfo method, 32 packing order, 19 packPropagate method, 32, 108, 251 packSlaves method, 33 padding
options, 48 relative coordinates,
specifying height
placeForget method, 55 placelnfo method, 55 placeSlaves method, 55 placing widgets (see place) pointerx, pointery, pointency methods, 298
Popup method, 245
label widget, 104
menubutton widget, 223
positionfrom method, 268 positioning
156
cursor,
widgets, 19, 29
window method,
50
and width, 53
polygons, creating, 194
basic button, 59
text widget,
1
with
getting configuration information, 32
option
scripts,
versions, 2
automatic resizing, 32 listing
12
reasons to use, 3 Tk::Fonts module, 66
pack, 16-34
196
widgets, 20, 22, 297
178
(see also pack)
parent method, 291
post method, 218, 245
parent widgets
postcascade method, 247
determining, 291
postscript method, 204
overview, 6
PostScript output, canvas widget, 204
with frames, 251
PPM/PGM
password entries, ll6 pathname method, 292 pathname, widget, 292
file
support, 61
prev method, 303 print, printf,
13
Programming
Perl
Perl, 64, 282,
protocol method, 265 history,
1
reference, general,
Tk extension
x
(see Perl/Tk)
Q
8
Quick Draw program, 207 quitting an application, 12
Perl/Tk
coding
style,
debugging
a program,
13
R
334 Getopts modules, 306 fonts,
history,
radiobutton, 93-100
1
installing,
anchoring, 96 1,
5
modules (see modules,
assigning callbacks, 96 Perl/Tk), 257
306
353
Index
label widget, 105
bitmap, displaying, 96
146
border width, 96 color options, 96-97
radiobutton, 97
configuring, 100
scale widget, 212
listbox,
creating, 94
scrollbar,
cursor options, 97
text
100
flashing,
font, setting,
toplevel widget, 259
97
height, 97
highlight rectangle, 97 indicator
97
color,
97
status,
invoking, 100
menubutton widget, 235 on and off values, 98
resizing
146
listbox,
retrieving elements
from a
listbox,
rgb method, 293
97
selecting
removing widgets, 46, 55 Reparent event, 278 repeat method, 307 reqheight method, 296 reqwidth method, 296 resizable method, 261
window, automatic, 32
96-98
list,
overview, 81 relief,
165
tags,
widget, 156
focus, 98
option
129-130
and
deselecting, 100
RGB
value, 293
menu example, 247
state,
98
right-click
style,
99
rootx, rooty
97
text justification,
method, 297
rows 38
underlining characters, 98
setting,
variable options, 98
spanning, 38
width, 98
(see also grid)
with menubutton widget, 227
wrapping,
text,
98
Radiobutton method, 95 radiobutton method, 235 raise
method, 203, 258
range of values, scale widget, 213 rectangle
Scale method, 206, 210 scale widget, 210-217
assigning callbacks, 211
border width, 211
changing
allocation (see allocation rectangle) creating,
194
highlight, 78, 97 relief
size,
215
color options, 211-212 configuring, 2l6 creating,
210
cursor options, 211
canvas widget, 187 checkbutton, 85
determining coordinates, 2l6 focus, setting, 212
entry widget, 110 font, setting,
frame widget, 253 label widget, 104 listbox,
menu
143
widget, 239
menubutton widget, 223
label options, 212, 214
option
211-212 212-213
range of values, 213 relief,
entry widget, 112
list,
orientation,
options basic button, 59
211
identifying parts, 216
212
setting value, 2l6 slider options,
212
148
354
Index
scale widget {continued)
method
Scrolled
212
state,
canvas widget, 181, 184, 203 scrollbar widget, 125-128
uses, 210
value increments, displaying, 214
scrolling
variable options, 212
canvas widget, 206
width, 212
listbox,
scaling the canvas widget, 205
151
121
text,
scan method, 152
search method, 174
scanDragto method, 121, 179, 206 scanMark method, 121, 179, 206
searching text widget, 174
scanning
sel tag,
canvas, 206 text,
see method, 150, 173
selectFrom method, 197
121
screen
selecting
distances
items in a listbox, 144
converting, 295 units,
radiobutton, 100
31
text
canvas widget, 197
information, 298
screen method, 298
entry widget, 114
screencells method, 299
selection
screendepth method, 299 screenheight method, 298
method, 121, 149
mode, 143
screenvisual method, 299
options, listbox, 149-150
screenwidth method, 298
selectionAnchor method, 150
scrollable region, canvas widget, scrollbar,
164, 167
selectClear method, 197
183
124-140
SelectionClear method, 301 selectionClear method, 149
SelectionGet method, 301
activating elements, 136
arrows, 132
SelectionHandle method, 301
assigning callbacks, 130, 133
selectionlncludes method, 149
border width, 129 color options, 129-130
SelectionOwn method, 302 SelectionOwner method, 302
communicating with other widgets, 133
selectionPresent method, 122
configuring, 127, 134
selectionRange method, 122
creating,
selectionSet method, 149
128
cursor options, 130
selectionTo method, 122
defining, 124, 135
selectTo method, 197
examples, 137
send method, 304
focus, setting, 130
separator, creating, 235
option
list,
129-130
separator item, 231
separator method, 235
orientation, 130 relief,
129-130
slider,
132
style,
server method, 300 server type, 300
131
set
method, 135, 2l6 method, 293
using one with multiple widgets, 138
setPalette
width, 130
setting tab stops,
with
Shift key,
entry widget, 117, 137 listbox, text, or
single
canvas widgets, 138
scrollbar, assigning to widget,
Scrollbar method, 128
144
159
274
mode,
listbox,
method, 150 size, widget, 296 sizefrom method, 269 size
144
Index
355
sizing
158
text widget,
tab stops, setting, 159
toplevel widget, 260 tabs, setting,
widgets (see pack) slider
arc item, scale widget, 212
132
scrollbar,
spacing
line item,
157-158
spanning rows and columns, 39 state
basic button, 59
checkbutton, 85 entry widget, 110
menubutton widget, 223 radiobutton, 98 scale widget, 212 text widget,
157
toplevel widget, 265 status label,
106
stipple pattern
arc item,
189 192
line item,
oval item, 193 text item,
195
text tags,
l64
193
oval item, 193 text item,
195
tagAdd method, 166, 168 tagBind method, l69 tagCget method, 168 tagConfigure method, l67, 172 tagDelete method, 170 tagLower method, 170 tagNames method, 171 tagNextrange method, 171 tagRaise method, 170 tagRanges method, 171 tagRemove method, 170 tags
canvas widget, 199-201 finding, 201 text,
stored values, 214
189
bitmap item, 190 create Window method, 198 image item, 191
character (see marks) line,
157, 165
names
tag
Tcl/Tk,
164-171 1,
4
tear-off items, 224
storing indicator status, 85 text style
adding, 197
basic button, 68
checkbutton, 91
frame widget, 253 menu widget, 240
deleting,
exporting, 109 in a
radiobutton, 99 scrollbar,
canvas widget, 194
indexes, 196
131 inserting,
subroutine
anonymous, 63 references, 64
syntax options, 6
screen distances, 31
120, 171
item indexes, 196 justification (see justification, text)
scanning, 121
(see also callbacks)
Sub widget method, 184 SUPER: :bind, 184 SUPER: :Populate, 285 switches, search method, 174
118, 196
entering, 108
scrolling,
121
selecting,
197
selection options, entry widget, 114 tags,
164-171
adding to existing
text,
border width, l64
changing
priority,
color options, 164 configuring, l67 creating,
l67
170
168
356
Index
deleting, 170
Tk Tk
example, 166
Tk::bind, 184, 201
text, tags
{continued)
font, setting,
l64
justification, text,
option
list,
relief,
165
(see Perl/Tk)
Tk::break, 279
l65
Tk::Button, 280
164—165
Tk::Dialog, 257
module, 66 284
Tk:: Fonts
removing tag from stipple pattern,
text,
170
164
Tk:: Frame,
Tk::JPEG, 61
284
underlining characters, l65
Tk:: Widget,
using bind method, l68
Toplevel method, 257
wrapping,
toplevel method, 291
text,
165
widget, 154-180
toplevel widget, 257-269
assigning callbacks, 157
application grid, 267
border width, 155 changing appearance, l64
border width, 258
color options, 155-157
colormap options, 259, 266 command property, 266
creating,
color options, 258
154
cursor options, 156
configuring, 260
cursor, setting, 155
creating, 257
debugging, 179
cursor options, 259
deleting text, 172
defined, 7
embedding other widgets, 176
focus model, 267
example, l60
focus, setting, 259
font, setting,
height, 259
156
icon
font use, 157 grid, setting,
bitmap, 263
157
height, 156
mask, 264
indexes, l6l-l63
name, 264 position, 264
inserting text, 171 justification values,
line spacing,
160
option
157-158
option
155-157
list,
padding, 156
setting tab stops,
tabs, tag,
260
262
265
width, 259
138
window
searching contents, 174
159
transient
158
properties, 265
method, 269
translating to
RGB
triple modifier,
157
state,
title,
uses, 257
scrollbars with,
sizing,
setting sizing, state,
156
relief,
258-259
list,
259
relief,
marks, 175-176
value, 293
275
type method, 204, 245
157 166
u
uses, 154
width, 157
underlining characters
wrapping (see wrapping, Text method, 154 time delays, 306 title
clipboard, manipulating, 300
method,
11,
text)
basic button, 59
checkbutton, 85 label widget,
262
104
menubutton widget, 224
357
Index
radiobutton, 98
165
text tags,
Unix fonts,
257-269
widgets anchoring, 27, 52
66
using Perl/Tk with, 331
Unmap
154-180
toplevel,
color values, 73
124-140
scrollbar, text,
event, 278
unpacking widgets, 32 unpost method, 247 update method, 297
checkbutton, 83 place, 48 children, determining, 290 creating,
demo
6-7
with
Tk module, 72
destroying, 302 displaying, 9
embedding, 176 value displayed versus stored, 214 increments, scale widget, 214
enlarging, 38 height, setting, 48
197
item,
range, scale widget, 213
listing,
variable options
33
name, 291
basic button, 59
entry widget. 111 label widget, 104
(see also atom)
naming conventions, 12 ordering, 29
radiobutton, 98 scale widget, 212
versions of Perl/Tk, 2
viewable method, 300 virtual desktop,
297
Visibility event,
278
visualsavailable method, 299
vrootheight method, 298
vrootwidth method, 298
organizing (see geometry manager)
padding, 29, 41 parent and child, 6 parent, determining, 291
pathname, 292 placing (see place) position, 297
positioning, 20, 22
(see also pack)
removing, 46, 55
w
resizing, automatic, 32
waitVariable method, 304
screen information, 298
waitWindow method, 305
size,
widget types
sizing,
basic button, 57-80
determining, 296 19
(see also pack)
canvas, 181-209
space buffer, 38
checkbutton, 81-93
specifying width
composite, 281-289
unpacking, 32
10&-123
entry,
frame, 251-256 label,
102-108
listbox,
141-153
and
height, 53
width, setting, 48 Widgettype method, 6 width arc item,
189
MainWindow, 7 menu, 238-248
basic button, 60
menubutton, 220-238 optionmenu, 248-249 radiobutton, 93-100 scale, 210-217
canvas widget, 187
button, 70
checkbutton, 85
createWindow method, 198 entry widget. 111
About the Author Nancy Walsh
a consultant for Sybase, Inc. She spent too
is
University of Arizona, changing majors a multitude of times
with a B.S. in computer science. Continuing on in Perl
and Java
few
in the last
ending up
she has worked mostly with
life,
Nancy has numerous hobbies, which hand and machine quilting), stained glass
still,
include quilting (pieced and applique,
(anything that doesn't break yet), martial arts (she
Kwon
years at the
finally
years.
In the family tradition of not sitting
black belt in Tae
many
and
Do), amateur radio
(QRP
approximately halfway to a
is
mostly),
and reading (anything
with words).
Colophon Our look
is
the result of reader comments, our
own
experimentation, and feed-
back from distribution channels. Distinctive covers complement our approach
to technical topics, breathing personality
and
life
distinctive
into potentially dry
subjects.
The
bird
on the cover of Learning Perl/Tk
hollandiae). This large, flightless bird steppes.
The emu
is
one of the
cousin the ostrich. Adult
is
is
a juvenile
emu {Dromaius
novae-
found throughout the Australian bush
largest birds in existence,
emus stand about
5 feet (1.5
second only
to
m) high and weigh up
its
to
120 pounds (55 kg). The grayish-brown emu's small wings contain only six or
seven feathers. They are hidden by the long, hairlike rump plumage. Emus have
which they use as defensive and offensive weapons limb can be broken by a kick from an emu. Their powerful legs make emus strong swimmers and fast runners; they can reach speeds of up to 50 km/hour. extremely strong
when
fighting.
legs,
A human
Male emus, which are
slightly smaller
eggs and the raising of the young.
than the females, tend to the incubation of
An emu
nest contains
up
to fifteen to twenty-
by several hens. Incubation of the eggs takes from twenty-five to sixty days. The large discrepancy in incubation time occurs because the male needs to leave the nest periodically to find food and drink. The length of time he is away affects the time for incubation. Newly hatched emus weigh about five
deep green eggs,
15 ounces (440 g).
laid
They
are fully
grown
at
two
to three years.
between emus and Australian farmers has always been an adveremu have been exterminated. Because emus can jump over high fences, it is difficult to keep them out of fields, where they eat
The
relationship
sarial
one; three coastal subspecies of
and trample crops. In the arid Australian bush, emus also compete with cattle and sheep for grass and water. On the other hand, emus eat many insects that would otherwise eat crops. In 1932 Australian farmers declared war on the emus, making an all-out effort to eradicate them. Fortunately, the between emus and farmers continues to this day. Edie Freedman designed the cover of
from the Dover
Pictorial Archive.
this
effort
failed.
The
battle
book, using a 19th-century engraving
Kathleen Wilson designed the back cover and
produced the cover layout with QuarkXPress
3. 32,
using the ITC
Garamond
font.
was done by Edie Freedman and modified by Nancy Priest, Garamond Light and Garamond Book fonts. The text was prepared in FrameMaker 5.5 by Mike Sierra. The illustrations were created by Robert Romano in Adobe Photoshop 5.0 and Macromedia Freehand 8.0. Quality assurance was provided by Ellie Fountain Maden, Jeffrey Liggett, Claire Cloutier LeBlanc, and Sheryl Avruch. This colophon was written by Clairemarie Fisher
The
interior design
using the ITC
services were provided by TIPS Technical by Judy Flynn, composition and indexing by Karen Brown of Scriptorium Publishing Services, Inc., proofreading by Rachel Anderson
O'Leary.
Publishing
Editorial
and production
—copyediting
of Archer Editorial, and project
Whenever RepKover
possible, our
or Otabind
management by Robert Kern.
books use a durable and .
If
flexible lay-flat binding, either
the page count exceeds the
for this type of binding, perfect binding
is
used.
maximum
bulk possible
gl^ More
^^
from O'Reilly
Titles
Perl Learning Perl on Win32 Systems
Perl in a Nutshell By Stephen Spainhour,
—
&
Ellen Siei'er
Nathan Patwardhan
^^jfH^iL^
^^HH|k
^^^^M
B^JwmJBI
]st Edition January 1999 674 pages, ISBN 1-56592-286-7
The perfect companion programmers, Perl
in
for
need
Perl.
know
to
It
a
to the
contains everything you
Perl questions.This wealth of information efficient, extraordinarily
is
is
paced course, leading Perl
and a Windows NT practitioner
^^^^3||
teach you to program in the language
V
that
promises
to
emerge as the
scripting
language of choice on NT. Based on the
an
into
&
August 1997
In this carefully trainers
most obscure
packed
Erik Olson
306 pages, ISBN 1-56592-324-3
^^Ki ^^^^r
working
a Nutshell
for all but the
1st Edition
^^^^H|
comprehensive reference guide
world of
By Randal L Schwartz, Tom Christiansen
^kl
WKfKfKKftKSglfn
"llama" book,
this
book
feanires tips for
PC users and new,
NT-specific examples, along with a foreword by Larry Wall, the
usable format.
creator of Perl, and Dick Hardt, the creator of Perl for Win32.
The Perl Cookbook By Tom
Christiansen
1st Edition
& Nathan
Mastering Regular Expressions
Torkington
By Jeffrey E. E Friedl
August 1998
794 pages. ISBN 1-56592-243-3
1st Edition January
and examples for anyone programming in Perl covers everything
Regular expressions, a powerful tool for
from beginner
manipulating ^ Regular Expressions
questions to techniques that even the most
experienced Perl programmers might learn from.
It
text
and
data, are
scripting languages, editors,
found
in
programming
environments, and peciahzed tools. In
contains hundreds of Perl
this
book, author Jeffrey Friedl leads you
through the steps of crafting a regular
"recipes," including recipes for parsing strings, doing matrix multiplication,
1997
368 pages, ISBN 1-56592-257-3
This collection of problems, solutions,
working with arrays and hashes, and performing
expression that gets the job done.
and uses them
complex regular expressions.
in
He examines a variety
of tools
an extensive array of examples, with a major
focus on Perl.
Learning Perl, 2nd Edition
Mastering Algorithms with Perl
By Randal L. Schuiartz & Tom Christiansen,
By Jon Orwant. Jarkko Hietaniemi &
Foreword by Larry Wall
Algorithms
2nd Edition July 1997 302 pages, ISBN 1-56592-284-0
John Macdonald 1st Edition August 1999 (est.) 480 pages, ISBN 1-56592-398-7
witli Perl
In this update of a bestseller, two leading Perl trainers teach you to use the
universal scripting of the
langu^e
There have been dozens of books on
most
in the
programming algorithms, but never before has there been one that uses Perl.
age
World Wide Web. Now current
Perl version 5.004, this hands-on tutorial includes a lengthy
Whether you are an amateur programmer
for
new
or
chapter on CGI programming, while touching also on the use of library modules, references,
and
in other languages, this
Perl's object-oriented constructs.
traditional
programming
easy-to-maintain
know
manner with
Perl. Topics
800-998-9938
•
and encryption.
[email protected] • http://www.orellly.com/
Our products are available at a bookstore or software store near FOR information:
800-998-9938
•
range in complexity
to statistical algorithms,
O'REILLY" TO order:
to carry out
tasks in a high-powered, efficient,
from sorting and searching analysis,
a wide range of algorithms
book will teach you how
you.
707-829-0515 • [email protected]
numerical
—
Perl Perl Resource Kit—UNIX Edition fij^^MMMEl^l^ Br Larry' Wall, Nate Patwardhan,
^Mf^W
Ellen
^^m^^
Brian Jepson
fr
VHHV
Perl documentation
enhanced software
it's
Tom
&
Christiansen
2nd Edition
September 1996 670 pages, ISBN 1-56592-149-6
Coauthored by Larry Wall, the creator of gives
Perl, the
issfs
you the most comprehensive collection of
RESOlRCi; KIT
Wall,
Randal L Schwartz
&
The Perl Resource Kit— UNIX Edition
V/X A
Developed
By Larry
November 1997 1812 pages, ISBN 1-36592-370-7
r^f^ f* I
2nd Edition
Perl,
1st Edition
j-^W| -*
David Futato
Siei'er,
Programming
second edition of this authoritative
guide contains a
and commercially
tools available today
langu^e and
in association with Larry Wall, the creator of Perl,
fiill
explanation of Perl
5. 003 features. It
version
covers Perl
syntax, functions, library
modules, references, and object-oriented features, and also explores
the definitive Perl distribution for webmasters, programmers,
invocation options, debugging,
common
mistakes, and
much more.
and system administrators.
Kit— Win32 Edition
The Perl Resource Kit provides:
Perl Resource
•
^j^KMMESMMtllM, By Dick Hardt, Erik Olson, David Futato & Brian jepson ^jj^
Over 1800 pages of
tutorial
documentation for Perl •
A CD-ROM containing
and in-depth reference and extensions,
utihties
in 4 volumes.
^m^^^ C^^^m
the complete Perl distribution,
plus hundreds of freeware Perl extensions and
utilities
T^^^i
a complete snapshot of the Comprehensive Perl Archive
—
Network (CPAN) Wall
as well as
new
software written by Larry
Jif\~,Y\.
1st Edition
^^ ^^' Resource M— Win32 Edition is
Rl'SOl
F^Ci;
they can find what they
—and more—
need on CPAN.
Now
all
the
power
include
your
fingertips.
of
The Perl Resource Kit
Win32
includes: •
and Linux
of CPAN, with an install
program
that ensures that all necessary
installed together Also includes
and a web-aware interface
of Perl. The Kit contains
Perl software
Win32 webmasters
some
from Dick Hardt's
the
for
and a
an easy-to-use search tool
that allows
you to get the
ActiveState
company along
definitive
A new Java/Perl
documentation
set
from O'Reilly
Advanced Perl Programming
latest
By Sriram Srinivasan
interface that allows
programmers
Java classes with Perl implementations. This
new
1st Edition August 1997 434 pages. ISBN 1-56592-220-4
to write
tool
was
This
written specially for the Kit by Larry Wall.
book covers complex techniques
managing production- ready Experience the power of Perl modules in areas such as CGI,
web
power and
of the latest commercial
modules are
version of each module. •
for
with a collection of hundreds of Perl modules that run on Win32,
A complete snapshot Solaris
Win32 and
and system administrators who have discovered flexibility
is at
who
KIT are expanding their platform expertise to
on One Convenient CD-ROM hackers know when to create their own, and
Perl Software Tools All
when CPAN
& CD-ROM
an essential tool for Perl programmers
just for the Kit.
Experienced Perl
August 1998
^^^ P^S^' Includes 4 books ISBN 1-56592-409-6 1'
spidering, database interfaces,
man^ng
mail and
news, user interfaces, security, graphics, math and
and explains methods
USENET
statistics,
and objects
and
before.
much more.
It
that
gives
Perl
for
programs
for manipulating data
may have looked
like
magic
you necessarv' background
for dealing with networks, databases,
and
GUIs, and includes a discussion of internals to help you program
more
efficiently
and embed Perl within C or C within
O'REILLY" JO order:
800-998-9938
• [email protected]
• http://www.oreilly.com/
Our products are available aj a bookstore or software store near FOR information:
800-998-9938
•
707-829-0515
•
you.
[email protected]
Perl.
Web Programming CGI Programming on the World Wide Web
JavaScript: The Definitive Guide, 3rd Edition By David Flanagan & Dan
By Shishir Gunciavaram 1st Edition March 1996 450 pages, ISBN 1-56592-168-2 This
book offers a comprehensive explana-
tion of
who own
This third edition of the definitive reference
CGI and related techniques for people
to JavaScript covers the latest version of the
hold on to the dream of providing their
language, JavaScript 1.2, as supported by
information servers on the Web.
Netscape Navigator 4.0. JavaScript, which
It
starts
CGI
at the beginning, explaining the value of
and how subtle details of
Shafer
3rd Edition June 1998 800 pages, ISBN 1-56592-392-8
it
works, then moves
is
being standardized under the
ECMAScript,
swiftly into the
can be embedded
programming.
directly in
is
name
a scripting language
that
HTML to give web pages programming-
language capabilities.
Dynamic HTML: The
Definitive Reference
Learning VBScript
By Danny Goodman 1st Edition July
By PaulLomax
1998
1088 pages, ISBN 1-56592-494-0
Dynamic HTML: is
1st Edition July
an indispensable compendium for
content developers.
It
reference material for
CSS
616pages,
The Definitive Reference
style attributes,
of the
HTML
This definitive guide shows
how
tags,
by the various standards and the
and discusses techniques ActiveX controls to a
&
Web Client Programming
1st Edition February 1998 618 pages, 1-56592-383-9
This definitive guide
is
exclusively to teaching
"" '^^•"'""