P. 1
Tk 1Day Course With Answers

Tk 1Day Course With Answers

|Views: 12|Likes:
This intensive one-day course, with problems and answers, focusses on the creation, control, and application of graphical image programming in Tk. It assumes existing skill in Tcl, available in other online courses by the author.

This course teaches how to create simple Tk menu systems and related controls, including the following widgets: label, text, button, entry, listbox, and various dialogs.
This intensive one-day course, with problems and answers, focusses on the creation, control, and application of graphical image programming in Tk. It assumes existing skill in Tcl, available in other online courses by the author.

This course teaches how to create simple Tk menu systems and related controls, including the following widgets: label, text, button, entry, listbox, and various dialogs.

More info:

Categories:Types, Research
Published by: John Michael Williams on Feb 24, 2013
Copyright:Traditional Copyright: All rights reserved
List Price: $5.00 Buy Now

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
See more
See less

08/12/2015

$5.00

USD

Sections

  • Agenda
  • Prerequisites
  • Course Organization
  • Topics
  • Schedule
  • References
  • Introduction
  • Relation of Tk to TcL
  • Relation of Tk to X
  • Tk Naming Conventions
  • Elementary GUI Objects
  • window
  • image
  • bitmap
  • palette
  • text
  • widget
  • Window Systems and Controls
  • tk Command
  • wm Command
  • winfo Command
  • Packer Geometry Manager
  • Gridder Geometry Manager
  • Placer Geometry Manager
  • Window raise and lower Commands
  • wish: The Windowing Shell
  • Running Tk from the OS Command Line
  • bitmap and mtpaint utilities
  • mtpaint
  • Lab 1: A Tk label Widget and Icons
  • Text and Font Manipulation
  • Font Selection
  • Text I/O
  • Widget Execution by Window Path
  • The text Widget
  • Character Indexing in a text Widget
  • More text Modification by Script
  • Window Destroy and Replace
  • Packed Append of text Value
  • Packed Supplement of text Value
  • Order of Creation Effect
  • Event Binding
  • Using global in the label Widget
  • The bind Command and a Simple entry
  • Interactive Text Entry and Validation
  • entry: bind Keywords
  • entry: Window focus
  • entry: Validation
  • entry Validation example
  • Lab 2: Text I/O
  • Image Creation and Manipulation
  • Namespaces
  • The image Command
  • image create
  • image delete
  • image names
  • X11 bitmap (xbm) management
  • The Tk palette
  • Some tk_setPalette Examples
  • Command-specific bitmaps
  • In button
  • In label
  • In tk_messageBox
  • In tk_dialog
  • Lab 3: Utility Dialog Widget Templates
  • tk_messageBox
  • tk_dialog
  • tk_chooseColor
  • tk_chooseDirectory
  • tk_getOpenFile
  • tk_getSaveFile
  • Multiple Top-Level Windows
  • Three More Widgets
  • labelframe Widget
  • listbox Widget
  • Grided listbox Example
  • listbox Declaration Options
  • listbox Command Options:
  • Grided listbox GUI Example
  • tk_popup Widget
  • Layout of a GUI with a Popup Menu
  • tk_popup Options
  • menu Widget Complications
  • Functional Prototype for a GUI with Popups
  • A Complete GUI with a Popup Menu
  • Lab 4: Image-Viewing GUI Application
  • Review and Wrap-Up
  • Graphical Programming
  • Topics We Have Presented
  • Topics Omitted

Tk Fundamentals for GUI

Development
Textbook with Lab Exercises
for a Si l i con Val l ey Techni cal I nsti tute
Workshop
by J ohn Michael Williams
2009-05-22
Copyright © 2009, J ohn Michael Williams.
Licensed free to Silicon Valley Technical Institute for training-course use. All other
rights reserved.
jmmwill@comcast.net
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
1
Table of Contents
Tabl e of Contents ............................................................................................................ 1
Agenda ............................................................................................................................ 3
Pr er equi si tes .......................................................................................................................3
Cour se Or gani zati on ...........................................................................................................3
Topi cs...................................................................................................................................4
Schedul e ..............................................................................................................................4
Refer ences ....................................................................................................................... 5
I ntr oducti on .................................................................................................................... 5
Rel ati on of Tk to TcL ...........................................................................................................6
Rel ati on of Tk to X...............................................................................................................6
Tk Nami ng Conventi ons ......................................................................................................6
El ementar y GUI Objects .....................................................................................................7
wi ndow.....................................................................................................................7
i mage .......................................................................................................................8
bi tmap......................................................................................................................8
pal ette......................................................................................................................10
text...........................................................................................................................11
wi dget ......................................................................................................................12
Wi ndow Systems and Contr ol s ............................................................................................13
tk Command ............................................................................................................13
wm Command ..........................................................................................................14
wi nfo Command.......................................................................................................17
Packer Geometr y Manager ......................................................................................18
Gridder Geometr y Manager ....................................................................................19
Placer Geometr y Manager .......................................................................................20
Wi ndow r ai se and l ower Commands .......................................................................24
wi sh: The Wi ndowi ng Shel l ................................................................................................25
Runni ng Tk fr om the OS Command Li ne ...............................................................26
bi tmap and mtpai nt uti l i ti es ...............................................................................................27
bi tmap......................................................................................................................27
mtpai nt ....................................................................................................................28
Lab 1: A Tk l abel Wi dget and I cons ............................................................................... 29
Text and Font Mani pul ati on ........................................................................................... 30
Font Sel ecti on ......................................................................................................................30
Text I /O................................................................................................................................31
Wi dget Executi on by Wi ndow Path .........................................................................31
The text Wi dget .......................................................................................................31
Char acter I ndexi ng i n a text Wi dget ......................................................................34
Mor e text Modi fi cati on by Scr i pt.........................................................................................35
Wi ndow Destr oy and Repl ace..................................................................................37
Packed Append of text Val ue ..................................................................................38
Packed Suppl ement of text Val ue ...........................................................................38
Or der of Cr eati on Effect ..........................................................................................39
Event Bi ndi ng......................................................................................................................41
Usi ng gl obal i n the l abel Wi dget .............................................................................41
The bi nd Command and a Si mpl e entr y .................................................................42
I nter acti ve Text Entr y and Val i dati on ...............................................................................45
entr y: bi nd Keywor ds .............................................................................................45
entr y: Wi ndow focus ...............................................................................................45
entr y: Val i dati on ....................................................................................................46
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
2
entr y Val i dati on exampl e ........................................................................................48
Lab 2: Text I /O............................................................................................................... 51
I mage Cr eati on and Mani pul ati on .................................................................................. 53
Namespaces .........................................................................................................................53
The i mage Command...........................................................................................................54
i mage cr eate ............................................................................................................54
i mage del ete ............................................................................................................55
i mage names ............................................................................................................55
X11 bi tmap (xbm) management ..........................................................................................56
The Tk pal ette .....................................................................................................................57
Some tk_setPal ette Exampl es .................................................................................58
Command-speci fi c bi tmaps..................................................................................................60
I n button ..................................................................................................................60
I n l abel .....................................................................................................................61
I n tk_messageBox....................................................................................................61
I n tk_di al og .............................................................................................................62
Lab 3: Uti l i ty Di al og Wi dget Templ ates ........................................................................ 62
tk_messageBox ....................................................................................................................62
tk_di al og ..............................................................................................................................63
tk_chooseCol or .....................................................................................................................64
tk_chooseDi r ector y ..............................................................................................................64
tk_getOpenFi l e ....................................................................................................................64
tk_getSaveFi l e .....................................................................................................................65
Mul ti pl e Top-Level Wi ndows .......................................................................................... 66
Thr ee Mor e Wi dgets ........................................................................................................ 67
l abel fr ame Wi dget ...............................................................................................................67
l i stbox Wi dget......................................................................................................................69
Grided l i stbox Exampl e...........................................................................................69
l i stbox Decl ar ati on Opti ons .....................................................................................71
l i stbox Command Opti ons: ......................................................................................72
Grided l i stbox GUI Exampl e...................................................................................73
tk_popup Wi dget .................................................................................................................75
Layout of a GUI wi th a Popup Menu ......................................................................75
tk_popup Opti ons ....................................................................................................76
menu Wi dget Compl i cati ons....................................................................................76
Functi onal Pr ototype for a GUI wi th Popups .........................................................77
A Compl ete GUI wi th a Popup Menu ......................................................................79
Lab 4: I mage-Vi ewi ng GUI Appl i cati on ......................................................................... 82
Revi ew and Wr ap-Up ...................................................................................................... 85
Gr aphi cal Pr ogr ammi ng......................................................................................................85
Topi cs We Have Pr esented ..................................................................................................85
Topi cs Omi tted ....................................................................................................................86
I ndex ............................................................................................................................... 1
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
3
Agenda
Prerequi si tes
Thi s workshop requi res current mastery of the TcL scri pti ng l anguage.
Parti ci pati on wi thout the prerequi si tes may be frustrati ng or di scouragi ng.
Preparati on may be adequate because of work experi ence, sel f-i nstructi on, or
coursework. SVTI offers two workshops, one on TcL fundamental s and another on TcL
advanced scri pti ng, whi ch woul d be mi ni mal preparati on for Tk. The TcL
fundamental s workshop pl us a coupl e of weeks of i ntensi ve on-the-job scri pti ng al so
mi ght be adequate preparati on.
The Tk workshop i ncl udes no programmi ng except i n TcL. Experi ence wi th any of
the fol l owi ng may be hel pful but i s not necessary: Li nux, Uni x, X-wi ndows, C
programmi ng, text-edi tti ng i n vi.
Course Organi zati on
Operati on of a computer, i ncl udi ng a cel l phone or other pocket devi ce, i s di scouraged
duri ng l ecture. Communi cati on i nterferes wi th l earni ng. Pl ease defer such acti vi ti es
for breaks or l ab peri ods.
Duri ng l ecture, pl ease stop the presentati on wi th a questi on when somethi ng i s
uncl ear to you. Pl ease save i n-depth questi ons or observati ons for l ab.
Cl assroom l ecturi ng wi l l be al ternated wi th hands-on l ab work. The four l abs i n the
course wi l l be of progressi ve di ffi cul ty, cul mi nati ng wi th creati on of a GUI for mi xed text
and graphi cal I /O.
The l ab exerci ses wi l l be performed on computers runni ng Li nux. The TcL shel l , the
Tk tool ki t, and other runti me software wi l l be provi ded prei nstal l ed. A Tk-based GUI
devel oped i n Li nux general l y wi l l run di rectl y i n Wi ndows or other operati ng systems.
Portabi l i ty i ssues wi l l be di scussed as they ari se.
On-di sc answers for al l l ab exerci ses are provi ded; TcL user and reference manual s
wi l l be avai l abl e duri ng the l abs. We use Acti veState
®
ActiveTcl i n thi s course; thi s i s
avai l abl e precompi l ed for Li nux and other operati ng systems and can be downl oaded
free from the I nternet for home or workpl ace use.
Lectures are based on sl i des taken from the Textbook but often formatted di fferentl y.
I t shoul d be conveni ent to fol l ow topi cs i n each l ecture by pagi ng through the Textbook.
Take notes to i mprove your l earni ng. Not everythi ng i n the l ectures wi l l be i n the
sl i des or the Textbook.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
4
Topi cs
Topics of the Workshop
Tk wi dget overvi ew
i mage creati on
X11 bi tmap (xbm) management
the Tk pal ette
Tk GUI database col ors
font sel ecti on
text I /O and entry val i dati on
Tk i ntegrati on wi th TcL scri pts
Tk nami ng conventi ons
wi ndow systems and namespaces
el ementary wi ndow creati on and control
geometry managers:
packer, gridder, placer
bitmap and mtpaint uti l i ti es
wi dgets and uti l i ty di al og templ ates:
label, text, entry, tk_popup,
listbox, tk_messageBox, tk_dialog,
and others
The focus of the workshop i s on creati on, control , and appl i cati on of graphi cal objects,
not on graphi cal artwork or on detai l s of the X wi ndow system. The fol l owi ng essenti al
topi cs are menti oned bri efl y but are not presented: gif photo bi tmaps, .Xdefaults
confi gurati on fi l e, X event bi ndi ngs.
Schedul e
Ti mes are approxi mate, except l unch. Breaks (not shown) wi l l fol l ow each l ecture.
9:00 - 10:00 I ntroducti on; wi dgets and wi ndow systems
10:00 - 10:30 Lab 1: A label wi th i con
10:30 - 11:30 Text and font mani pul ati on
11:30 - 12:00 Lab 2: Text I /O
12:00 - 12:30 Lunch
12:30 - 13:30 Lab 2 (concl uded)
13:30 - 14:00 I mage creati on and mani pul ati on
14:00 - 15:30 Lab 3: Tk uti l i ty templ ates
15:30 - 16:00 Wi ndow desi gn and control
16:00 - 17:15 Lab 4: A si mpl e GUI appl i cati on
17:15 - 17:30 Revi ew and wrap-up
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
5
References
Anonymous. ActiveTcl User Guide. http://www.activestate.com (2005-12-24).
Anonymous. TcL Developer Exchange. http://www.tcl.tk/ (2006-06-06). I f you
are i nterested i n object-ori entati on, see http://www.tcl.tk/about/oo.html.
Anonymous. Tk 8.5 Demo. Thi s demonstrates the use of al l the wi dgets presented i n
thi s Workshop, and more. After i nstal l i ng the Acti veTcl software, i n the
./demos/Tk8.5 di rectory i nvoke wish widget.tcl.
Fl ynt, Cl i f. TclTutor. I nteracti ve tutori al ; good revi ew of basi cs. Avai l abl e onl i ne or
for downl oad at http://www.msen.com/~clif/Tcl.html (2006-06-09).
Gougel et, Pi erre-E. XnView i mage vi ewer and converter. Freeware for personal ,
noncommerci al use. http://www.xnview.com (2009-03).
Johnson, Ray. Tcl Style Guide. Sun Mi crosystems, ca. 1997. Especi al l y val uabl e for
tk programs or mul ti pl e-fi l e programs l arger than scri pts.
http://www.tcl.tk/doc/styleGuide.pdf (2006-06-30).
Tyl er, Mark. Mark Tyler's Painting Program (mtpaint). Freeware to create and
mani pul ate bi tmaps. http://mtpaint.sourceforge.net (2009-04).
Wel ch, Brent B., Jones, Ken, and Hobbs, Jeffrey. Practical Programming in Tcl/ Tk
(4th ed.). Upper Saddl e Ri ver, New Jersey: Prenti ce-Hal l , 2003. Thi s i s the onl y
book on Tk whi ch i s recommended for further study.
Introduction
Thi s i s an i ntensi ve, one-day workshop whi ch presents a subset of the Tk GUI
devel opment ki t. The goal i s to show how to i ntegrate certai n Tk graphi cs features wi th
TcL scri pts through l ab and l ecture.
The attendee i s assumed to know TcL wel l and to desi re to l earn how to adapt
pl anned or preexi sti ng scri pt-based TcL appl i cati ons to a pl atform-i ndependent
graphi cal user i nterface.
The attendee wi l l l earn how to create si mpl e Tk menu systems and other graphi cal
control s, i ncl udi ng the fol l owi ng wi dgets: label, text, button, entry, vari ous di al ogs,
and listbox.
The attendee wi l l l earn how to transl ate i mages i nto Tk-usabl e format and to
i ntegrate them wi th textual representati ons. Communi cati on and coordi nati on among
a few, essenti al ki nds of Tk wi ndows wi l l be presented.
At the end of the Workshop, attendees shoul d be abl e to bui l d a si mpl e GUI for any
ordi nary ki nd of i nteracti ve TcL scri pt. Attendees al so shoul d be abl e to devel op a GUI
for menu-dri ven control of any arbi trary system of such scri pts.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
6
Rel ati on of Tk to TcL
Tk i s a col l ecti on of TcL commands whi ch use a l i brary of compi l ed, bi nary-format
functi ons to access the graphi cal capabi l i ti es of the operati ng system.
Everythi ng i n Tk i s compl i ant wi th TcL syntax, and Tk functi onal i ty can be accessed
onl y by runni ng one or more TcL scri pts. Thus, an i nstal l ed versi on of TcL i s requi red
for Tk.
Tk i s del i vered and i nstal l ed by defaul t wi th every ActiveTcl software di stri buti on; so,
a user who i nstal l s TcL from Acti veState general l y al so has i nstal l ed a ful l y functi onal
Tk. TcL i s i ncl uded wi th al l recent rel eases of Li nux, but the versi on may or may not be
the l atest avai l abl e di rectl y from Acti veState (=ActiveTcl). When TcL i s bundl ed to run
wi thi n a tool , such as an EDA tool , i t may not i ncl ude Tk.
Rel ati on of Tk to X
On Li nux, Tk uses cal l s to X11 for al l graphi cal functi onal i ty; on Wi ndows, i t uses the
same syntax but actual l y makes cal l s to the Win32 (or, Win64) API . Tk comes wi th
several groups of C-l anguage uti l i ti es whi ch i nterface to X (or Wi ndows API ) di rectl y.
These uti l i ti es permi t bi ndi ng of Tk or Tcl to X-wi ndow events; X concurrent cal l backs;
confi gurati on by the user's .Xdefaults startup fi l e; and, general l y, a fai rl y compl ete
i nterface to X.
The commands used for C-l anguage i nterfaci ng are enti rel y di sjoi nt from those of Tk
proper, al though they al so are i nstal l ed by defaul t wi th every Acti veState TcL software
di stri buti on. We do not assume any ski l l at C programmi ng i n thi s Workshop, so we
i gnore X features and functi onal l y, except for an occasi onal reference to si mi l ari ti es
between Tk and X11.
Tk Nami ng Conventi ons
Al l TcL standard commands are compl etel y l ower-case; so, i t i s enti rel y safe i n TcL to
name ones own procedures wi th at l east one upper-case l etter, thus compl etel y avoi di ng
name confl i cts wi th the di stri buti on. Many Tk commands fol l ow thi s TcL conventi on.
However, the Tk commands whi ch begi n wi th "tk_" i n part fol l ow the X nami ng
conventi on i n whi ch each word combi ned i nto a compound name i s capi tal i zed. The
fi rst word i n a tk_ command al ways i s i n l ower case; however, the second word, and
every subsequent one, i s capi tal i zed. The typi cal command name format thus i s,
tk_firstwordSecondword...
For exampl e, tk_getOpenFile, tk_messageBox, tk_focusNext. When there i s no
second word i n a name, everythi ng i s l ower case: tk_popup, tk_dialog.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
7
Nothi ng executabl e i n Tk shoul d be gi ven a capi tal i zed name. For our purposes, thi s
means wi ndows, i mages, and TcL procs. Upper-case characters after the fi rst one are
al l owed anywhere.
Not to be confused wi th Tk, there i s a l arge col l ecti on of commands i n the Acti veState
rel eases whi ch begi n wi th a capi tal i zed Tk_ and have each component word capi tal i zed;
for exampl e, Tk_MainLoop. These are C access routi nes to Tk or X and are not i n the
TcL l anguage; we shal l i gnore them i n thi s Workshop.
El ementary GUI Obj ects
window
A wi ndow i s an el ementary graphi cal object whi ch provi des a rectangul ar wi ndow
i nto the appl i cati on functi onal i ty. Such wi ndows can be vi si bl e or i nvi si bl e to the user,
and they can have any arbi trary appearance; they provi de a l ocati on on screen whi ch
permi ts communi cati on wi th the appl i cati on or appl i cati ons associ ated wi th them.
Wi ndows i n Tk may present themsel ves as menues of vari ous ki nds; as fi l l -i n text forms,
buttons, checkboxes, or other i nteracti ve objects; as i cons or other i mages; or, as
combi nati ons of these and other objects grouped or framed i n vari ous ways.
Everythi ng i n Tk begi ns wi th speci fi cati on of a wi ndow of one ki nd or another i n a
TcL scri pt.
For exampl e, bel ow i s a TcL procedure and a cal l to that procedure whi ch, i n the
i nteracti ve wish shel l , wi l l create a wi ndow named x rooted to the current, top-l evel
wi ndow ('.'). I n thi s exampl e, the top-l evel wi ndow i s i nvi si bl e and nonfuncti onal . The
wi ndow named x vani shes as soon as a choi ce i s taken, and wish handl es the user's
choi ce, whi ch resul ts i n consol e output i nto the i nvoki ng wish shel l wi ndow.
proc prompt3Ans { WName B0 B1 B2 } \
{
set Choice \
[tk_dialog .$WName Question {Say What?} question 0 $B0 $B1 $B2];
#
switch $Choice \
{ 0 { puts "Choice was $B0"; }
1 { puts "Choice was $B1"; }
2 { puts "Choice was $B2"; }
default { puts "Choice=$Choice UNKNOWN. Prompt3Ans() failure?"; }
}
return $Choice;
}
prompt3Ans x hello goodbye wait;
Thi s wi ndow i s of a tk_dialog ki nd whi ch appears wi th banner ti tl e "Question"
and wi th three button-name vari abl es named B0, B1, and B2. When thi s proc i s cal l ed,
the vari abl es wi l l be gi ven val ues. A l arge, graphi c '?' i con appears because of the
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
8
tk_dialog "question" opti on chosen. The "0" opti on desi gnates the button whi ch i s
by defaul t acti ve (i n case of a keyboard CR rather than a mouse cursor sel ecti on).
Thi s wi ndow's body text prompts "Say What?", and i t
presents the three buttons named on the i nvocati on l i ne as
"hello", "goodbye", and "wait". I n a Wi ndows desktop
envi ronment, our new wi ndow .x (i ts ful l name) prompts for
i nput wi th the appearance of a Wi ndows messagebox, as
shown. The prompt3Ans() wi ndow.
Mul ti pl e wi ndows usual l y are present at the same ti me on any gi ven screen. Each
wi ndow i s associ ated wi th a l ayer or stacki ng order whi ch defi nes whether i t wi l l
overl ap others or be overl apped i n appearance. Newl y-created wi ndows typi cal l y
overl ap previ ousl y exi sti ng ones.
Wi ndow names i n Tk must begi n wi th a l ower-case character; a wi ndow named .X
woul d not have been l egal i n the exampl e just gi ven. So, i nvoki ng the proc above as
prompt3Ans X hello goodbye wait;
woul d have generated an error.
image
The Tk command, image, i s used to decl are and mani pul ate GUI i mages.
An i mage i s a graphi cal pi cture whi ch may be one of two possi bl e types, bitmap or
photo.
bitmap image. As expl ai ned bel ow, each pi xel i n a bitmap i mage i s one of two
possi bl e col ors, or i s transparent. The two col ors are determi ned by the appl i cati on; and
so, effecti vel y, bi tmaps are mul ti col ored i mages. General l y, the wi dgets di spl ayed by an
appl i cati on can have many more di fferent col ors than those of any one bitmap whi ch i t
may i ncl ude.
photo image. I n contrast to a bitmap, each pi xel i n a photo i mage i s defi ned
i nternal l y i n Tk by a 32-bi t col or code. The actual appearance of a photo i mage may be
reduced to, say, a 256-col or pal ette; i f so, automati c di theri ng may occur to represent
groups of pi xel s i n a col or not i n the pal ette. Photo i mages i n gif fi l e format
necessari l y are l i mi ted to a 256-col or pal ette. The same commands, wi th di fferent
opti ons, are used for bitmap and photo i mages; see the Tk hel p menu for detai l s. For
l ack of ti me, we shal l not study photo i mages further i n thi s Workshop.
bitmap
As just expl ai ned, a bitmap i s a two-col or i mage. The two col ors are named
foreground (col or 1) and background (col or 0). Every pi xel al so opti onal l y i s associ ated
wi th a vi si bi l i ty mask whi ch ei ther presents i t i n i ts desi gnated col or (mask val ue 1), or
whi ch renders i t i nvi si bl e (mask val ue 0); i nvi si bl e pi xel s are transparent wherever the
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
9
bi tmap overl aps anythi ng el se. I f a mask i s not speci fi ed, none of the bitmap pi xel s i s
transparent.
Li ke a TcL proc, a bitmap has to be decl ared i f i t i s to be accessi bl e i n Tk. The
di spl ay structure of a bitmap may be defi ned i n a di sc fi l e or i n a TcL stri ng; i f a mask
i s i nvol ved, the mask al so may be defi ned the same way.
The format of a bitmap must be X11 xbm, whi ch i s C-source code (asci i ). Each xbm
i mage consi sts of two C preprocessor macroes named something_width and
something_height (i n pi xel s) and a l i teral constant i n the form of a static char array
named something_bits. Here, something represents an arbi trary C i denti fi er chosen by
the user or wri tten automati cal l y by a drawi ng appl i cati on. Consi stent wi th the C
l anguage, each char val ue i s that of an 8-bi t byte.
For exampl e, i f we represent the i denti fi er by x,
#define x_width Wpix /* Wpix pixels wide */
#define x_height Hpix /* Hpix pixels high */
static char x_bits[]
= { 0xnn, ... (one hex byte per 8 pixels) ..., 0xnn };
Format of an xbm bitmap i mage defi ni ti on. Each n represents a hex nybbl e wi th
val ue between 0 (= bi nary 0000) and f (= bi nary 1111). x was an arbi trary name
gi ven by the appl i cati on creati ng the xbm fi l e.
I t i s possi bl e to construct a bitmap i mage pi xel -by-pi xel manual l y, but i t i s more
conveni ent to create the i mage vi sual l y i n a drawi ng appl i cati on and convert i t to xbm
when savi ng i t to a di sc fi l e.
Al l operati ng systems runni ng X-wi ndows come equi pped wi th the very pri mi ti ve and
cl umsy bitmap appl i cati on for edi tti ng and savi ng an xbm i mage. Neverthel ess, the best
approach i s to use al most any drawi ng appl i cati on other than bitmap to create the
i mage and save i t to a fi l e i n GIF, PNG, or TIFF format. I n Li nux, the freeware mtpaint
uti l i ty then can be used to convert one of these fi l e formats to xbm; i n Wi ndows, mtpaint,
XnView, or other uti l i ti es may be used to create an xbm fi l e. We shal l return to the
bitmap and mtpaint tool s l ater i n the Workshop.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
10
For exampl e, assumi ng a 2-col or i mage i n a fi l e named Lever_Bitmap.tif, i t can be
l oaded i nto mtpaint and saved out as Lever_Bitmap.xbm. Then, wish can be i nvoked
on the fol l owi ng scri pt to present the i mage as a wi ndow named z under control of a TcL
scri pt:
image create bitmap Lever_Bitmap -file Lever_Bitmap.xbm;
set Msg "Lever Action Illustrated";
pack [label .z -textvariable Msg -font {-family Courier -size 24
-weight bold} -compound bottom -image Lever_Bitmap -bg white];
The resul ti ng wi ndow i s
packed i n a compound of
text and i mage, wi th the
i mage on the bottom:
We shal l study opti ons to image create i n l ab. Noti ce that i t i s not the image
create command whi ch di spl ays the bi tmap above; thi s merel y decl ares the GUI name
of the i mage, whi ch i s defi ned i n the fi l e, Lever_Bitmap.xbm. The GUI object
di spl ayed, whi ch i s of a label type, i s created by the pack command.
palette
Each of the objects i n a Tk GUI can be associ ated wi th a predefi ned 256-col or pal ette,
many of whi ch col ors are named. The associ ati on of object features to col ors i s cal l ed a
colormap. The pal ette can be used to modi fy GUI col ors by the Tk command,
tk_setPalette. See the Tk hel p for more i nformati on about named col ors. An
exampl e of RGB col or coordi nates (i n deci mal numeral s) taken from the Tk pal ette i s,
# R G B
...
green4 0 139 0
GreenYellow 173 255 47
grey 190 190 190
grey0 0 0 0
grey1 3 3 3
grey2 5 5 5
...
slate blue 106 90 205
slate gray 112 128 144
...
Ei ther of the two col ors i n a bitmap may be speci fi ed i n RGB (Red-Green-Bl ue)
components the same way as i n X: "#rrggbb", i n whi ch rr, gg, and bb (red, green, and
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
11
bl ue) each represent i n hex a byte val ue between 0x00 and 0xff. A l arger val ue
i ndi cates a greater contri buti on of that component; so, #ffffff = (0xff) (0xff) (0xff)
= (255) (255) (255) appears whi te and #000000 = (0x00) (0x00) (0x00) = (0) (0) (0)
appears bl ack -- dependi ng on computer di spl ay and moni tor cal i brati on, of course. The
pal ette col or names al so may be used; they may be found i n the Tk hel p under colors.
For exampl e, i n the pack command exampl e above, the i mage background coul d have
been set to a shade of bl ue by repl aci ng -bg white wi th -bg {slate blue}.
I n addi ti on to bitmaps, al l GUI objects can be assi gned col ors accordi ng to thei r
functi onal i ty or operati onal state. Thi s i s done by the tk_setPalette command. The
i denti fi ers for these objects are,
The tk_setPalette command can change the col or styl e of any object i n the GUI .
Thi s command overri des col ors sel ected automati cal l y for the GUI styl e when a wi dget
geometry creati on command such as pack i s executed. We shal l see how
tk_setPalette i s used l ater.
We won't be studyi ng photo i mages i n thi s Workshop, but suffi ce i t to say here that a
subset of the 32-bi t col or space of such i mages i s represented i n the Tk pal ette. See the
Tk hel p for more i nformati on associ ated wi th photo bi tmaps.
text
As we have seen, text may be compounded wi th an image object. The font fami l y,
si ze, and wei ght may be speci fi ed for the text when the compound wi ndow i s created.
Other text attri butes i ncl ude sl ant, underl i ne, and overstri ke. I n the present exampl es,
text wi l l be di spl ayed wi th commands speci fi c to other wi dgets; there al so exi sts a
speci fi c text wi dget i n Tk whi ch we shal l study l ater.
A ful l -custom font may be created by a TcL appl i cati on; see the Tk hel p for font for
more detai l s. I n thi s Workshop, we shal l assume onl y the three defaul t font fami l i es
provi ded by Tk; these are predecl ared wi th the names, Courier (monospaced font),
Helvetica (proporti onal and sans-seri f), and Times (proporti onal and seri fed).
A label wi dget may be used to demonstrate the defaul t fonts i n a wish wi ndow, as i s
shown next.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
12
proc fontLabel { Win Options } \
{
upvar $Options MsgL; # *L for local reference variable.
set Opts [join $MsgL];
pack [label .$Win -text "$MsgL" -fg black -bg {light green} -font $Opts];
}
set Msg1 { -family Courier -size 14 -weight bold -slant roman};
set Msg2 { -family Helvetica -size 16 -weight bold -slant italic};
set Msg3 { -family Times -size 18 -weight normal -slant roman};
#
fontLabel x Msg1;
fontLabel y Msg2;
fontLabel z Msg3;
I f the precedi ng scri pt i s run i n a wish shel l , the three l abel wi dgets are di spl ayed as
sequenti al l i nes of text i n a si ngl e wi ndow, as shown bel ow. We shal l see l ater how to
create more than one Tk wi ndow i n a si ngl e appl i cati on (scri pt). Three di fferent stri ng
vari abl es are requi red for three di sti nct message stri ngs; thi s i s because the text i n a
label i s referenced, not copi ed. Modi fyi ng any of the three label text stri ngs
i nteracti vel y or i n the scri pt causes i mmedi ate update of that label to the new text
val ue.
Three di fferent typeface formats determi ned by three di fferent sets of
text -font opti ons.
Noti ce that there i s a l ead bl ank quoted i n each of the scri pt-assi gned stri ngs. Thi s
bl ank i s preserved as empty green background i n the label messages.
widget
The word widget = "whi ch gadget?" rhymes oddl y wi th gadget, and i t refers wi th
humor or amazement to a smal l mechani sm of undefi ned functi onal i ty, compl i cated i n
appearance. A wi dget i n Tk i s about the same as a wi dget i n X-wi ndows; i t i s a
graphi cal object or wi ndow component wi th consi stent, wel l -defi ned characteri sti cs.
Any X or Tk GUI may be sai d to have been bui l t usi ng a tool box fi l l ed wi th wi dgets.
We just have l ooked at an exampl e of a label wi dget; and, we saw another bi tmap-
contai ni ng label, and a tk_dialog wi dget, i n earl i er exampl es. I n thi s Workshop, we
shal l study the fol l owi ng other wi dgets: text, entry, button, listbox, and some
other di al og types. These are enough for a basi c GUI , and we shal l menti on the other
ki nds of Tk wi dget onl y i n passi ng.
Be aware of an i mportant techni cal di sti ncti on: A wi dget i s a GUI object; i t i s not the
same as the command, scri pt, or program whi ch must be run i n order to create the
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
13
wi dget or suppl y i t wi th functi onal i ty. Al so, a wi dget i n Tk i s onl y part of a GUI . Li ke
an ornament on a Chri stmas tree, a wi dget i s not i tsel f a standal one object.
Wi ndow Systems and Control s
Before l ooki ng i nto detai l s of speci fi c Tk wi ndows or wi dgets, some context may be
useful .
Wi ndows i n Tk exi st i n a hi erarchy exactl y the same as di rectori es i n the fi l i ng
system. Thus, the top-l evel or current wi ndow (the fi rst one created -- by the wish shel l ,
for exampl e) i s named '.'. Subordi nate wi ndows are separated by '.'. For exampl e, a
new wi ndow x i n wish can be created wi th the name, ".x", as we have seen i n exampl es.
I f a new wi ndow y i s created wi thi n x, i t can be named .y and accessed from wish as
".x.y". As al ready menti oned, wi ndow names are requi red to begi n wi th a l ower-case
character. A wi ndow name can be any l ength; for brevi ty, we typi cal l y use one-
character names i n our exampl es.
There are several commands i n Tk whi ch affect wi ndows i n general or the
confi gurati on and properti es of the graphi cal envi ronment, rather than speci fyi ng
properti es or behavi or of i ndi vi dual objects. We l ook at these here.
tk Command
Thi s command i ncl udes several subcommands reporti ng or modi fyi ng the runni ng
GUI . We shal l menti on two of them here; others are i n the Tk hel p system.
tk appname. Reports (by defaul t), or changes, the name of the runni ng appl i cati on,
as di spl ayed by defaul t i n top-l evel wi ndow banners and as used as an address for
i nterprocess communi cati on.
Suppose a fi l e named setAppName.tcl contai ned thi s scri pt:
proc setAppName { Win Msg {App argv0} } \
{
upvar $App AppL;
tk appname $AppL;
pack [label .$Win -text "$Msg" -fg white -bg {dark blue} -font {-family
Times -size 14 -weight bold -slant italic}];
}
set Msg "This is an example of $argv0";
set NewName "newAppName";
The upvar i s used here merel y for vari ety, and to remi nd the attendee of i ts usage.
The above scri pt may be run by the command,
wish setAppName.tcl
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
14
I f the fol l owi ng runti me was added,
... (script above) ...
setAppName x $Msg;
the defaul ted thi rd argument woul d produce thi s wi ndow:
However, i f the runti me was thi s i nstead,
setAppName x $Msg NewName;
the thi rd argument woul d produce thi s wi ndow:
For reasons i rrel evant to the present Workshop, Tk appl i cati on names, l i ke wi ndow,
i mage, or proc names, al ways shoul d begi n wi th a l ower-case l etter, as shown above.
I t i s possi bl e to change the banner-di spl ayed text wi thout modi fyi ng the appname.
Thi s i s demonstrated i n the di scussi on of wm title, bel ow.
tk windowingsystem. Reports the speci fi c system bei ng used. The most common
returned val ues are "x11" or "win32". Two possi bl e MacOS val ues are classic and
aqua. Thi s command may be useful when porti ng code whi ch behaves di fferentl y i n
di fferent operati ng systems; for an exampl e of thi s, see wm iconbitmap bel ow.
wm Command
The wm subcommands are used to access the Tk wi ndow manager. Some of them
appl y to the system as a whol e; others may be appl i ed to i ndi vi dual wi ndows, al most
al ways to the top-l evel wi ndow created by a scri pt.
wm colormapwindows. Thi s command returns i nformati on about l ocal col ormaps
mai ntai ned by i ndi vi dual wi ndows. Al though Tk bitmap i mages are al l owed onl y two
col ors, di fferent col ors may be taken from the pal ette and vari ed among di fferent
wi ndows, produci ng a mul ti col ored GUI . Thi s command al so may be used to modi fy
col ormaps, but we shal l not use i t thi s way i n thi s Workshop.
wm iconbitmap. Thi s i s the onl y way to associ ate an i con wi th a wi ndow.
An i con i s a smal l i mage (64x64, 48x48, or 32x32 pi xel s) whi ch i s di spl ayed i n the
Li nux panel when a wi ndow i s mi ni mi zed (i coni fi ed). For most themes (GUI styl es), the
same i con i s di spl ayed i n the wi ndow banner. An i con i s di spl ayed si mi l arl y i n
Wi ndows.
I cons are speci al ki nds of i mage; onl y wm iconbitmap, not image create, i s al l owed
to decl are an i con.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
15
Note that Tk i cons onl y pertai n to acti vel y runni ng Tk GUI 's, not to i nacti ve
programs or other materi al stored i n di sc fi l es; the i cons associ ated wi th di sc fi l es are
not Tk but OS-dependent, al ways are mul ti col or, and may be bi gger than 64x64 pi xel s.
Li nux fi l e i cons may be i n xpm or png i mage format; Wi ndows has i ts own .ico format.
I n Li nux, the Tk i con format must be 2-col or bi tmap (.xbm). Al so, the xbm
background and foreground col ors may be i nverted, so a negati ve of the desi red i con
di spl ay someti mes must be created i n the bi tmap fi l e, dependi ng on the X-wi ndows UI
theme sel ected by the l ogi n user. There i s no control over the two col ors of a Li nux i con,
other than that automated by the theme.
The wm iconbitmap command i s one of the few i n Tk whi ch has pl atform
dependenci es. I n Wi ndows, opti onal l y, a Wi ndows-format bi nary i con fi l e (.ico) may
be speci fi ed as a Tk i con. Thi s makes for cl earl y-defi ned, mul ti col ored i cons i n Tk when
run i n Wi ndows. The .ico format does not work i n Li nux.
An i con can be associ ated onl y wi th a top-l evel (mai n) wi ndow; i t may be di spl ayed i n
any wi ndow i n the hi erarchy. The syntax to di spl ay a bitmap fi l e as an i con on any
pl atform i s
wm iconbitmap topwindow_path @fname.xbm
I n Wi ndows, onl y, thi s syntax i s al l owed:
wm iconbitmap topwindow_path ?-default? fname.ico
The Wi ndows-onl y -default opti on propagates the speci fi ed i con as a defaul t to al l
menu and wi ndow banners parented by the gi ven wi ndow (usual l y .). Otherwi se, the
generi c Tk feather i con may be di spl ayed everywhere but on the top-l evel wi ndow.
Noti ce that an i con i s associ ated wi th a top-l evel wi ndow, not wi th a speci fi c wi dget
such as a label. The i con for an appl i cati on can be changed i n Tk i ndependent of what
the appl i cati on does or contai ns.
For exampl e, suppose a Li nux .xbm fi l e wi th thi s i mage:
I t i s a monochrome i mage, arbi trari l y di spl ayed here wi th
bl ack foreground and whi te background. The outermost
bl ue border i s thi s Textbook's frami ng border of the i mage
and i s not part of the i mage i tsel f.
Al so, suppose a Wi ndows .ico fi l e wi th thi s i mage:
I t i s a fi ve-col or i mage wi th a dark bl ue on green text
bi tmap, framed i n concentri c bl ack and red borders.
Agai n, the outermost bl ue border i s the Textbook's frame
and i s not part of the i mage.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
16
Here i s an exampl e of some code, based on the previ ous exampl e and fi gures, whi ch
produces opti mal l y attracti ve i cons ei ther i n Li nux or Wi ndows:
proc setAppName { Win Msg {App argv0} } \
{
upvar $App AppL;
tk appname $AppL;
set L [label .$Win -text "$Msg" -fg white -bg {dark blue} -font {-family
Times -size 16 -weight normal -slant italic}];
pack $L;
if { [tk windowingsystem]=="x11" } \
{ wm iconbitmap . @TkIconBWneg.xbm; } \
else { wm iconbitmap . TkIcon.ico; }
}
set Msg "This is an example of $argv0";
set NewName "newAppName";
#
setAppName x $Msg NewName;
Run i n wish i n Wi ndows:
I n Li nux:
I n the Li nux desktop styl e for thi s exampl e, the ori gi nal TkIcon.xbm i mage was
i nverted (foreground and background bi t-val ues swapped) to create the fi l e,
TkIconBWneg.xbm, actual l y di spl ayed. Otherwi se, the appearance woul d have been of
a l i ght "Tk" on a dark background.
wm state. Thi s command may be used to change the di spl ay state of a wi ndow; the
useful states for ordi nary wi ndows are normal and iconic. An iconic wi ndow i s one
whi ch has been i coni fi ed (onto the taskbar). For exampl e,
proc winStates { Win State Title } \
{
pack [label .$Win -text "Here is a text label." -font "-size 20"];
wm title . $Title;
wm iconbitmap . @TkIconBWneg.xbm;
wm state . $State;
}
set String "wm State demo";
winStates x iconic $String;
Thi s runti me, here i n Li nux, creates a new taskbar entry whi ch
may be pi cked wi th the mouse cursor to di spl ay the wi ndow
normal l y. After pi cki ng i t on the taskbar, the resul ti ng normal -state di spl ay i s as
shown next:
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
17
I n Li nux. I n Wi ndows.
Noti ce that the i con i s i n X .xbm format; thi s format does work i n Wi ndows but may
not resul t i n a di spl ay as attracti ve as woul d a .ico format. Al so, noti ce the bl ack-on-
bl ue col ors of the di spl ayed Wi ndows i con; these are the col ors assi gned by Tk i n thi s
Wi ndows OS envi ronment. A di fferent Wi ndows col or scheme general l y woul d have
resul ted i n di fferent Tk icon col ors. The font fami l y of the label text stri ng i s the
defaul t (proporti onal sans-seri f), as i n the Helvetica fami l y.
wm title. Thi s command assi gns a text stri ng ti tl e to a wi ndow banner. The ti tl e
i s by copy, not by reference; so, modi fyi ng the stri ng after the wi ndow has been created
wi l l not change the wi ndow ti tl e. For exampl e, addi ng the fol l owi ng l i ne,
set String "New String";
to the runti me i n the previ ous code exampl e after the proc cal l produces the same
wi ndow ti tl e as before.
wm geometry. Thi s command reports the si ze and posi ti on of a wi ndow, i f i nvoked
wi th no opti on. I t may be used to change the si ze or posi ti on, or both, of a wi ndow,
taki ng these parameters away from thei r usual control by the Tk system. I f i nvoked
wi th an expl i ci t empty stri ng, i t rel i nqui shes control of si ze and posi ti on and permi ts the
Tk wi ndow di spl ay manager (i n thi s case packer), or the wi dgets di spl ayed, to regai n
control of the wi ndow si ze. Exampl e,
wm geometry .x =55x120+250+500
These opti ons force the .x wi ndow to be 55 uni ts wi de by 120 uni ts hi gh and to be
l ocated 250 pi xel s from the l eft edge of the screen and 500 pi xel s from the top edge. The
uni ts of wi dth and hei ght are pi xel s, unl ess a gri dded manager i s runni ng -- i f the l atter,
these uni ts woul d be gri d uni ts. We shal l di scuss wi ndow di spl ay managers l ater.
winfo Command
The many subcommands i n thi s command return i nformati on about the Tk wi ndow
system or i ts i ndi vi dual wi ndows. See the Tk hel p for detai l s on the 40-odd
subcommands; a few of them are:
winfo exists. Reports whether a wi ndow path exi sts.
winfo geometry. Reports the width x height i n number of pi xel s of a wi ndow.
There al so are winfo width and winfo height commands for the i ndi vi dual val ues,
as wel l as winfo x and winfo y for l ocati ons on the screen.
winfo id. Reports the l ow-l evel handl e used by the operati ng system to i denti fy a
wi ndow.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
18
winfo manager. Reports the name of the wi ndow geometry manager command for
a wi ndow. Thi s may be grid, pack, or place. When the geometry manager i s a
wi dget, the wi dget cl ass name i s returned. I f there i s no geometry manager, for
exampl e for an i nvi si bl e wi ndow, an empty stri ng i s returned.
winfo pathname. Reports the Tk pathname of a wi ndow, gi ven i ts l ow-l evel i d.
We next present the Tk geometry managers. These uti l i ti es are cal l ed to di spl ay the
subwi ndows i n a wi ndow. The placer al l ows dynami c control of the rel ati onshi ps among
pai rs of subwi ndows; the other two automate mul ti pl e rel ati onshi ps wi thi n a si ngl e
mai n wi ndow, al so someti mes adapti ng the si ze or shape of the mai n wi ndow.
Packer Geometry Manager
We've used the packer, i nvoked by the pack command, i n several exampl es al ready.
What the packer does, i s to arrange the subordi nate wi ndows of a mai n wi ndow around
the edges of the mai n wi ndow i n a way that effi ci entl y uti l i zes the area requi red by the
mai n wi ndow. The programmer has some control over where the subordi nate wi ndows
are packed, but onl y i n terms of the quadrant or si de of the mai n wi ndow, gi ven thei r
sequenti al order of creati on. Opti ons permi t stretchi ng of the background space
occupi ed by subordi nate wi ndows and the speci fyi ng of empty paddi ng on sel ected si des
of the mai n wi ndow. See the Tk hel p for detai l s of the pack command. There fol l ow a
coupl e of new pack exampl es to cl ari fy the effect of creati on order.
The si mpl e defaul t packi ng whi ch we have seen i n previ ous exampl es:
proc showPacker1 { } \
{wm title . {Default Pack};
#
# Create the windows:
foreach n {1 2 3 4} \
{set L$n [label .x$n -text "Win .x$n" -font "-size [expr 12+(4*$n)]"];}
#
# Call the geometry manager:
foreach n {1 2 3 4} { pack [subst \$L$n]; }
#
# Append the pack info reports:
foreach n {1 2 3 4} \
{ set M$n "[subst \$L$n]: [pack info ".x$n"]";
pack [label ".y$n" -text [subst \$M$n] -font {-size 12 -family Times}];
}
}
showPacker1;
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
19
The wi ndow created i n wish by showPacker1(), wi th defaul t pack opti ons.
The four l abel wi dgets, whi ch of course are subordi nates to the mai n wish wi ndow,
can be made to al i gn i n order begi nni ng at the l eft edge and gravi tated to the bottom (s
for south) by the fol l owi ng modi fi cati ons:
proc showPacker2 { } \
{
wm title . {Left Side, South Anchor Pack};
#
# Create the windows:
foreach n {1 2 3 4} \
{set L$n [label .x$n -text "Win .x$n" -font "-size [expr 12+(4*$n)]"];}
#
# Call the geometry manager:
foreach n {1 2 3 4} { pack [subst \$L$n] -side left -anchor s; }
#
# Append the pack info reports:
foreach n {1 2 3 4} \
{ set M$n "[subst \$L$n]: [pack info .x$n]";
pack [label ".y$n" -text [subst \$M$n] -font {-size 12 -family Times}];
}
}
showPacker2;
The wi ndow created i n wish by showPacker2(), wi th -side left and -anchor s opti ons.
Gri dder Geometry Manager
Thi s manager al l ows arrangement of subwi ndows by row and col umn.
One di fference between the grid and pack commands i s somethi ng l i ke the
di fference between list and string commands i n TcL: I t has to do wi th resol uti on. Gri d-
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
20
based geometry management i s meant to accommodate wi ndows wi th text of speci fi c
font si ze or fi xed bi tmapped graphi cs, so that changes or di fferences can not
meani ngful l y occur at the l evel of i ndi vi dual pi xel s. Thi s i s done by speci fyi ng a gri d
si ze. I nstead of pi xel s, l ocati on di fferences are defi ned i n the l arger, gri d uni ts
speci fi ed. As one appl i cati on exampl e, gri ddi ng can be used to make a text wi ndow
scrol l l i ne by l i ne, not pi xel by pi xel .
Thus, i n a sense, grid has l ower geometri cal resol uti on than pack. However, grid
al l ows two-di mensi onal control of subwi ndow l ocati on, whereas pack can posi ti on
wi ndows onl y sequenti al l y, accordi ng to the order i n whi ch they were created.
We show here how grid can be more space-effi ci ent than pack, when deal i ng wi th
text stri ngs of vari ous, fi xed si zes:
proc showGridder { } \
{
wm title . {All One Grid Row};
#
# Create the windows:
foreach n {1 2 3 4} \
{set L$n [label .x$n -text "Win .x$n" -font "-size [expr 12+(4*$n)]"];}
#
# Call the geometry manager:
foreach n {1 2 3 4} { grid [subst \$L$n] -row 0 -column [expr $n - 1]; }
#
# Append the grid info reports:
foreach n {1 2 3 4} \
{ set M$n "[subst \$L$n]: [grid info .x$n]";
grid configure [label ".y$n" -text [subst \$M$n] \
-font {-size 12 -family Times}] -columnspan 4 ;
}
}
showGridder;
The wi ndow created i n wish by showGridder(), wi th the grid info wi dgets
spanni ng the i ni ti al four col umns.
Pl acer Geometry Manager
The place command creates a rel ati on between just two wi ndows; one of these
wi ndows al ways wi l l be a subwi ndow of the other. I n thi s respect, place di ffers from
pack or grid, ei ther of whi ch may be appl i ed to any number of subwi ndows i n a mai n
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
21
wi ndow. Placer can control both the si ze and l ocati on of the subwi ndow to a pi xel -l evel
of resol uti on.
Because there i s onl y one subwi ndow to manage, place can be used for preci se
posi ti oni ng of the subwi ndow rel ati ve to the mai n wi ndow; i t al so can be i nvoked so that
si ze changes of the mai n wi ndow cause the subwi ndow (not just the background) to
change si ze correspondi ngl y, gi vi ng the pai r a rubber-sheet stretchi ng or contracti ng
appearance.
The subwi ndow may be posi ti oned so that i t i s di spl ayed outsi de the boundari es of the
mai n wi ndow; thi s makes i t possi bl e to move the mai n wi ndow so that the subwi ndow
fol l ows al ong, mai ntai ni ng i ts rel ati ve posi ti on, wi thout overl appi ng.
Fi nal l y, ei ther the subwi ndow's parent (..) wi ndow, or any wi ndow deri ved from that
.. wi ndow, may be desi gnated a mai n wi ndow by place; i t i s not necessary for the
subwi ndow to be deri ved from i ts place mai n wi ndow. Thi s i mpl i es that no i nvocati on
of place can control the geometry of the mai n wi ndow speci fi ed or i mpl i ed i n the
i nvocati on; mai n wi ndows must be si zed or l ocated on the screen by other means. I t
al so i mpl i es that the same mai n wi ndow may be speci fi ed or i mpl i ed i n mul ti pl e place
i nvocati ons, whi ch i s a way of gi vi ng that mai n wi ndow mul ti pl e placed subordi nates.
Next i s an exampl e of four pl aced label wi ndows and thei r respecti ve place info
reports.
proc showPlacer { } \
{wm title . {Four Placed Labels};
#
# Create the windows:
foreach n {1 2 3 4} \
{label .x$n -text "Win .x$n" -font "-size [expr 12+(4*$n)]" -bg white;}
#
# Call the geometry manager:
foreach n {1 2 3 4} { place .x$n -relheight 0.125 \
-relx 0.5 -rely [expr ($n-1)/8.0]; }
#
# Append the place info reports:
foreach n {1 2 3 4} \
{set M$n ".x$n: [place info .x$n]";
label ".y$n" -text [subst \$M$n] -font {-size 12 \
-family Times} -bg {light green};
place .y$n -relheight 0.125 -relx 0.0 -rely [expr 0.5+($n-1)/8.0];
}
}
showPlacer;
Al l wi ndows are deri ved from the same .. wish wi ndow, so al l can be placed
therei n. The fi rst fi gure shows the ori gi nal wish defaul t wi ndow si ze, because the
placer can not control that si ze. The second fi gure shows the wish wi ndow resi zed
i nteracti vel y, usi ng the mouse screen cursor, so that al l wi ndows are ful l y vi si bl e:
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
22
The place ori gi nal wi ndow.
The place wi ndow stretched i nteracti vel y by extendi ng the l ower-ri ght corner, showi ng the subwi ndow
edges. Further verti cal stretchi ng makes the whi te and green areas tal l er and the text l i nes spaced
farther apart.
The text can not be resi zed, but the label wi ndows can; so, the backgrounds stretch
to ful fi l l the placer constrai nts.
I n the next exampl e, the four label wi dget wi ndows are pai red, wi th .x3 i n .x1 and
.x4 i n .x2. Noti ce the effect of the i nner relheight, relx, and rely val ues, whi ch
are referenced to the respecti ve mai n wi ndows (.x1 and .x2), not to the wish mai n
wi ndow.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
23
proc showPlacePairs { } \
{wm title . {Two Paired Labels};
#
# Create the windows:
foreach n {1 2 3 4} \
{label .x$n -text "Win .x$n" -font "-size [expr 12+(4*$n)]" -bg white;}
#
# Call the geometry manager:
place .x1 -relheight 0.125 -relx 0.4 -rely 0.01;
place .x2 -relheight 0.125 -relx 0.1 -rely 0.01;
place .x3 -in .x1 -relheight 1.0 -relx 1.0 -rely 0;
place .x4 -in .x2 -relheight 2.0 -relx 1.0 -rely 1.0;
#
# Append the place info reports:
foreach n {1 2 3 4} \
{set M$n ".x$n: [place info .x$n]";
label ".y$n" -text [subst \$M$n] -font {-size 12 \
-family Times} -bg {light green};
place .y$n -relheight 0.125 -relx 0.0 -rely [expr 0.4+($n-1)/8.0];
}
}
showPlacePairs;
The showPlacePairs() di spl ay, somewhat stretched
verti cal l y and hori zontal l y.
The showPlacePairs() di spl ay, stretched hori zontal l y and somewhat
compressed verti cal l y. Noti ce how the di agonal contact of the pai red wi ndows,
.x2 and .x4, i s mai ntai ned; l i kewi se the hori zontal al i gnment of .x1 and .x3.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
24
Window raise and lower Commands
Every wi ndow vi si bl e on screen i s assi gned a stacki ng order val ue by Tk. When
wi ndows do not overl ap, the stacki ng order general l y i s meani ngl ess; however, when
they overl ap, a wi ndow wi th a hi gher stacki ng order wi l l obscure part or al l of one wi th
a l ower one.
The raise command rai ses the stacki ng order of a wi ndow, and the lower command
l owers i t. The change i n order can be absol ute, or i t can be rel ati ve to a gi ven other
wi ndow's order.
Because packer and gridder arrange label wi ndows sequenti al l y, they can not be
used to show the effects of raise or lower on the si mpl e wi ndows we have been usi ng
i n our exampl es. However, place easi l y can be used to do thi s.
I n the next scri pt, we create wi ndows purposel y overl apped: Wi ndow .x2 obscures
wi ndow .x1, and wi ndow .x4 obscures .x3. Thi s i s because of the order i n whi ch
place was cal l ed. I n general , throughout Tk, the l ater a wi ndow i s di spl ayed by a
wi ndow geometry manager i n the runti me, the hi gher i t wi l l be i n the stacki ng order.
proc showRaise { } \
{wm title (Unraised};
#wm title . {Raised .x1 and .x3};
#
# Create the windows:
foreach n {1 2 3 4} \
{label .x$n -text "Win .x$n" -font "-size [expr 12+(4*$n)]" -bg white;}
#
# Call the geometry manager:
place .x1 -relheight 0.125 -relx 0.2 -rely 0.01;
place .x2 -relheight 0.125 -relx 0.3 -rely 0.01;
place .x3 -relheight 0.5 -relx 0.4 -rely 0.05;
place .x4 -relheight 0.3 -relx 0.5 -rely 0.10;
#
# Append the place info reports:
foreach n {1 2 3 4} \
{set M$n ".x$n: [place info .x$n]";
label ".y$n" -text [subst \$M$n] -font {-size 12 \
-family Times} -bg {light green};
place .y$n -relheight 0.125 -relx 0.0 -rely [expr 0.4+($n-1)/8.0];
}
#raise .x1 .x2;
#raise .x3;
}
showRaise;
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
25
The scri pt above creates thi s di spl ay i n the wish mai n wi ndow:
The showRaise() resul t wi th obscured wi ndows .x1 and .x3. The i ni ti al wish
wi ndow i nteracti vel y was somewhat stretched verti cal l y and hori zontal l y.
Wi th the raise commands uncommented, and the ti tl es exchanged, the resul t i s as
fol l ows:
The showRaise() resul t wi th wi ndow .x1 rai sed rel ati ve to .x2, and wi th .x3 rai sed
uncondi ti onal l y. The wish wi ndow was stretched the same way as i n the previ ous fi gure.
wish: The Wi ndowi ng Shel l
The wish command i s the appl i cati on we have been i nvoki ng to run al l our Tk scri pts.
I n general , i t si mpl y i s a way to execute code to cal l the operati ng system graphi cal
support functi ons.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
26
I n Li nux, i nvoki ng wish i n a shel l wi ndow wi thout suppl yi ng a scri pt name creates
an i nert mai n wi ndow, a functi onl ess Tk GUI , whi ch i s of no use. However, the shel l i s
repl aced by the wish shel l , whi ch permi ts entry of i nteracti ve Tk commands; exi tti ng
the wish shel l ki l l s the i nert wi ndow and returns to the system shel l .
I n Wi ndows, i nvoki ng wish i n a cmd shel l causes two wi ndows to appear; the i nert
wi ndow, the same as the one i n Li nux, and a bastardi zed consol e wi ndow whi ch can run
TcL or Tk scri pts i nteracti vel y as wel l as commands for the Wi ndows nati ve cmd (DOS)
shel l . I n Wi ndows, the consol e-l i ke wi ndow vani shes i mmedi atel y i f a noni nteracti ve
wish scri pt i s i nvoked i n a cmd wi ndow and does anythi ng graphi cal .
Under speci al ci rcumstances, wish can be i nvoked wi th opti ons whi ch modi fy i ts
behavi or. Two of the opti ons are:
-display. Thi s associ ates a screen wi th the wish mai n wi ndow. Thi s opti on may
be useful when a Tk GUI i s bei ng executed on one machi ne and di spl ayed on the screen
of another, over a TCP-I P network. The usual X11 di spl ay securi ty features appl y.
-use. Thi s al l ows wish to run i nsi de a preexi sti ng mai n wi ndow rather than
creati ng i ts own. The wi ndow must be i denti fi ed by i ts l ow-l evel i d, as returned by the
winfo id command. The i d coul d be passed to a shel l scri pt as an i nvocati on
parameter, because these i d's are uni que wi thi n the operati ng system runti me, rather
than bei ng pri vate to a Tk GUI .
Running Tk from the OS Command Line
I f you want to run wish i n a shel l scri pt and pass wish arguments on the shel l scri pt
i nvocati on l i ne, i t can be done thi s way:
#!/bin/sh
# The next line restarts this shell script in wish \
exec wish "$0" "$@"
(TcL commands are the remainder of the file)
The fi rst l i ne tel l s the OS executi ve that thi s i s a shel l scri pt (sh and bash are the
same on Li nux). The shel l does not recogni ze the commented backsl ash as a NL escape,
so i t runs the wish command on the thi rd l i ne; because of the way an OS exec works,
the ori gi nal shel l process then i s termi nated and repl aced by the one (shel l ) exec of the
wish command.
However, when wish was exec'ed, i t was passed by the shel l two vari abl es: $0 i s the
name of thi s fi l e (the current shel l scri pt fi l e), and "$@" (must be quoted) i s the l i st of
arguments whi ch were typed i n on the command l i ne when the shel l scri pt was
executed. Therefore, wish reexecutes the whol e fi l e as a TcL scri pt, passi ng the TcL
scri pt the same arguments as was passed the ori gi nal shel l scri pt. But, wish i nterprets
the commented backsl ash as a TcL comment conti nuati on, and i t does not see the thi rd
l i ne as code. Therefore, wish starts i nterpreti ng TcL onl y at the fourth l i ne i n the fi l e.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
27
The net resul t i s that the whol e fi l e, except the fi rst three l i nes, i s run by wish as a TcL
scri pt.
Thi s approach onl y works i n Uni x or Li nux; i n Wi ndows, wish must be i nvoked i n a
Wi ndows .bat batch fi l e. At most ni ne arguments then can be passed to wish (whi ch
shoul d be pl enty!).
bitmap and mtpaint uti l i ti es
bitmap
The X wi ndow system comes wi th a tool named bi tmap for drawi ng bi tmaps, but onl y
smal l , monochrome ones. Thi s tool i s usabl e for i cons or custom cursors, but i t i s very
pri mi ti ve and probabl y shoul d be avoi ded.
The bitmap tool can be used to
edi t fi l es onl y i n one format, xbm,
and i t can not l i st a di rectory's
contents. Thus, i ts user i nterface
i s more of a col l ecti on of command-
l i ne remi nders than a modern
GUI . But, i t defi ni tel y i s easi er
than woul d be the enteri ng of
pi xel -state bytes numeri cal l y, i n
hex, by hand.
The defaul t i mage si ze (shown) i s
16 x 16 pi xel s; di fferent si zes may
be speci fi ed on the tool i nvocati on
l i ne. Other opti ons such as col ors
al so may be speci fi ed on the
i nvocati on l i ne, consi stent wi th
standard X Wi ndows command
opti ons.
The screen snapshot shows the
File/Load form for openi ng a fi l e
to edi t. The tool col ors are
defaul ts assi gned by X.
The [File] and [Edit] buttons control drop-down menues whi ch i n turn accept
typed entry or di spl ay si mpl e forms si mi l ar to the "Load File:" di al og shown. The
user i nterface control i s acci dent-prone. For exampl e, pi cki ng the [x] i n the upper-
ri ght corner of the di al og above causes the enti re edi tor to exi t wi thout warni ng.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
28
mtpaint
The mtpai nt tool i s a freeware program downl oadabl e from the i nternet (see the
References at the start of thi s book). I t i s avai l abl e for Li nux or Wi ndows. The
author's name i s Mark Tyl er; whence, mt. I t has al l the usual functi onal i ty of a modern
GUI appl i cati on program.
Thi s screen
snapshot shows
mtpaint wi th some
random pol ygon l i nes
and fi l l s i n di fferent
col ors. The 256-col or
pal ette i s di spl ayed
verti cal l y on the l eft.
mtpaint can save or
l oad two-col or
bi tmaps i n xbm
format; i t al so can be
used to edi t or convert
bi tmaps i n xpm (X
wi ndows or Li nux
mul ti col or), gif, png,
or Wi ndows bmp
format.
By defaul t, mtpaint wi l l not i ncl ude xbm on i ts save-as menu. To make thi s fi l e
format vi si bl e, the mtpaint pal ette fi rst must be set to two col ors, usi ng the
[Palette]/[Set Palette Size ...] menu. Enter "2". Wi th an i mage al ready
l oaded, use [Image]/[Convert to Indexed] and enter "2". After thi s, you wi l l be
abl e to save xbm bi tmaps. The actual pal ette col ors don't matter, because xbm pi xel s
ei ther are on or off and have no i ntri nsi c col or mappi ng.
As al ready suggested, Tk i mage creati on i s best done i n mtpaint, Li nux GI MP, or
some other ful l -featured bi tmap edi tor. The resul t then can be converted i n mtpaint to
1-bi t monochrome (wi th di theri ng or hatchi ng i f desi red) and wri tten out as xbm.
I f you have the KDE uti l i ti es i nstal l ed i n Li nux, you may fi nd the "I con Edi tor"
(=KIconEdit), or KolourPaint, l i sted on your "Graphi cs" mai n menu; these edi tors are
very good for creati ng, converti ng, or modi fyi ng smal l i mages.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
29
Lab 1: A Tk label Widget and Icons
Thi s l ab i s i ntended to provi de a l i ttl e hands-on wi ndow creati on.
Start by l oggi ng i n and changi ng to your Lab01 di rectory.
Step 1: Wri te a pl ai n TcL scri pt whi ch puts the message,
"We can do squares and circles.",
to the screen. Save your scri pt i n a fi l e named, Lab01_Text.tcl.
Test your scri pt by runni ng i t i n wish i nteracti vel y. I nvoke wish; then run,
% source Lab01_Text.tcl.
Step 2: I n a new fi l e named, Lab01_Label.tcl, create a TcL procedure (proc)
that i nvokes a Tk label wi dget to present the Step 1 message i n a graphi cal wi ndow.
Use couri er font for thi s message.
Your procedure shoul d run the label command and shoul d accept two arguments, a
wi ndow name for wi ndow creati on and a text stri ng to be used as i ts message. Use
source as i n Step 1 to l oad Lab01_Label.tcl i nto wish. Cal l your procedure
i nteracti vel y i n wish to test i t.
Step 3: Use the Li nux gimp drawi ng appl i cati on to create a new 64 x 64 pi xel
i mage. To do thi s, use the menu, [File]/[New...], and set the si ze to 64 x 64. Don't
bother bei ng fancy; a pl ai n l etter 'A' desi gn or a scri bbl ed i ni ti al wi l l be fi ne. Save the
i mage to a fi l e i n png format.
Convert the png fi l e wi th mtpaint to 2-col or X11 bi tmap (.xbm) format, and save i t.
Copy your .tcl fi l e of Step 2 to a new fi l e named Lab01_LabelGimp.tcl.
Modi fy your Tk procedure so that your label wi ndow di spl ays a message as i n Step 2
and your Tk mai n wi ndow banner di spl ays the new i con. You may mi ni mi ze the wish
label wi ndow to see the i con better.
Step 4 (Opti onal ): Use the Li nux bitmap drawi ng appl i cati on to create a 64 x 64
pi xel i con. Make the desi gn di fferent from that of your Step 3 i mage. Save the i con to
a fi l e i n xbm format.
Copy your .tcl fi l e of Step 3 to a new fi l e named Lab01_LabelBitmap.tcl.
Modi fy your Tk procedure so that i t associ ates the new bitmap i con i mage wi th the
label wi dget; test the di spl ay by mi ni mi zi ng the wish label wi ndow.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
30
Text and Font Manipulation
A GUI rarel y i s useful unl ess i t can present text as wel l as generi c i mages. A menu
system need not accept text i nput; but, i t al most al ways must provi de text to i denti fy i ts
choi ces. Al so, for many purposes, i t i s necessary for the GUI to accept text i nput;
exampl es of such i nput woul d be fi l e names, passwords, and confi gurati on parameters.
We al ready have seen how label wi dgets can be used to present text. We'l l fi rst
di scuss some detai l concerni ng text output; then, we'l l move on to the more compl i cated
topi c of processi ng and val i dati ng text i nput.
Font Sel ecti on
The pri mary parameter governi ng text i s the choi ce of typeface, al so referred to as
font. The defaul t Tk font fami l i es, as menti oned before, are named Courier,
Helvetica, and Times. Courier i s a monospaced, seri fed font, whi ch means that the
hori zontal spaci ng of every character i s the same, general l y the wi dth of an 'm', and that
the l i nes drawn for many characters are not pl ai n but end i n l i ttl e
cross-strokes. Helvetica i s a proporti onal , sans-seri f font, whi ch
means that the characters occupy di fferent hori zontal extents,
proporti onal to the wi dth requi red by the character's structure, and
that al l l i nes used to draw the characters are pl ai n.
Times i s a proporti onal , seri fed font. Experi ment has proven that seri fs make the
characters more compl i cated but the words easi er to read; proporti onal spaci ng al so can
enhance the readabi l i ty of words as wel l as savi ng space on the di spl ay screen.
For portabi l i ty, i t i s best to use onl y the three Tk defaul t fami l i es. I t i s possi bl e to
create an enti rel y new font fami l y by assi gni ng i t a name and uni que properti es; such a
font may be modi fi ed duri ng a wish sessi on by the font configure command. See the
Tk documentati on for more i nformati on concerni ng the creati on and modi fi cati on of
fonts.
When text i s created, Tk al ways permi ts certai n opti ons as fol l ows:
-family
The defaul t i s a sans-seri f font cl ose i n appearance to Hel veti ca.
-size
The defaul t i s somewhere near 12-poi nt on the screen di spl ayed.
-weight
Al ternati ves are normal (the defaul t) and bold.
-slant
Al ternati ves are roman (unsl anted; the defaul t) and italic.
-underline
A bool ean; the defaul t i s false (Wi ndows onl y).
-overstrike
A bool ean; the defaul t i s false (Wi ndows onl y).
We presented an exampl e of these opti ons, except underline and overstrike, near
the begi nni ng of thi s Textbook. For more detai l i n associ ati ng text wi th a speci fi c
wi dget, see the Tk documentati on on that wi dget.
Seri f and sans seri f.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
31
Text I /O
Widget Execution by Window Path
Al l Tk wi dgets are assi gned a wi ndow path when created. What we have not
menti oned so far i s that each such wi ndow path usual l y becomes the name of a
procedure i n the wi ndow system and can be i nvoked di rectl y as an executabl e. The
reason for executi ng a wi dget by i ts wi ndow path i s not to create i t but general l y to
modi fy i t or to acti vate i t i n some manner.
Each ti me a wi dget i s executed, i t can be passed new parameters whi ch may vary i ts
di spl ay characteri sti cs or other properti es. When a wi dget i s created, i t general l y
accepts opti ons i n the form, -widget_option; for exampl e, -width. When a wi dget i s
executed, i t someti mes al l ows modi fi cati on of that same parameter val ue, but the format
i s just widget_option, wi thout the i ni ti al hyphen ('-').
I n the Tk documentati on, the -widget_option form i s referred to as the "command-
l i ne name" of the opti on; the widget_option form i s referred to as the "database name"
of the opti on. I f the opti on name i s compound, the database name general l y capi tal i zes
the second and subsequent el ements; for exampl e, the command-l i ne name -maxundo
corresponds to the database name maxUndo.
Most of the Tk wi dgets accept configure as a database name for setti ng a parameter
or reporti ng a l i st of avai l abl e parameter names; they often accept cget ("confi gurati on
get") as a database name for returni ng the current state of a database name. We shal l
see an exampl e of wi dget executi on next.
The text Widget
Unl i ke graphi cs, text can be used to express al most anythi ng; thus, i t i s a very
compl ex topi c. We have seen how to di spl ay read-onl y text i n a label; now we shal l
l ook i nto the text wi dget proper.
A text wi dget normal l y i s subordi nate to the GUI context i n whi ch i t appears.
General l y, the text wi dget i s used to i mpl ement an edi ttabl e fi el d for entry or
modi fi cati on of data, or to permi t cl i pboard cut-and-paste operati ons. However, a text
wi dget al so may be di spl ayed by i tsel f. The typi cal GUI use of a text wi dget woul d be
to fi l l a text i nput fi el d wi th a defaul t, possi bl y cl eari ng i t, or to provi de a correcti on of
erroneous previ ous user text i nput.
Fi ne control over the appearance and i nteracti ve responses of i ndi vi dual substri ngs or
characters i n a text wi dget may be confi gured by means of text tags. We shal l not
di scuss tags i n thi s Workshop; see Wel ch, et al., Chapter 36, for extensi ve coverage of
thi s topi c.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
32
For exampl e, here i s a procedure demonstrati ng a text di spl ay resul ti ng from a
packer i nvocati on, pack bei ng cal l ed wi th al l defaul ts:
proc showText {Win Wid Points} \
{
wm title . "Text .$Win width=$Wid; $Points pt";
# Define the widget:
text .$Win -font "-size $Points -family Times" -height 1 -width $Wid;
.$Win insert end "Hello. ";
.$Win insert end "A text String!";
#
# Display it with defaults:
pack .$Win;
}
Here are a few di fferent i nvocati ons of thi s procedure, usi ng wish, as above, to cal l
packer to di spl ay the text wi dget wi ndow:
1
showText x 10 24;
2 (#1, stretched interactively)
3
showText x 20 24;
4
showText x 20 12;
(stretched i nteracti vel y)
5
showText x 20 24;
6
showText x 20 24;
(height was at 2)
A few thi ngs to noti ce i n the exampl es above:
Fi rst, a text wi dget i s meant to be used i n the context of i nteracti ve access to the
text, not just to di spl ay a stri ng; unl i ke a label, a text wi dget supports sel ecti on, copy,
cut, and paste. The insert opti on to a text wi dget wi ndow command i s the best way
to speci fy the i ni ti al val ue of the di spl ayed stri ng.
I n example 1, the text wi dget wi dth parameter caused i t to be cropped at a wi dth of
10 ("10" = 10 chars onl y i n a monospaced font), and packer used thi s wi dth to si ze the
wi ndow to fi t the defi ned wi dth. The same wi ndow i s shown i n example 2 stretched
i nteracti vel y; cl earl y, the croppi ng affected the text wi dget and packer, whi ch
control l ed onl y the wi ndow, had no control over the di spl ay of the stri ng i nsi de the
wi dget.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
33
I n example 3, the wi dth of the text has been i ncreased to 20, whi ch i s more than
enough to di spl ay the enti re stri ng. The l eftover space i n the text wi dget has been
fi l l ed wi th the defaul t text background col or.
I n example 4, the same wi dth was used, but the font si ze was hal ved; agai n, the
wi dth was more than enough to di spl ay the enti re stri ng. Thi s wi ndow was stretched
i nteracti vel y hori zontal l y sol el y to show the enti re banner title stri ng.
I n example 6, the hei ght parameter i n showText() was edi tted manual l y to change i t
from 1 to 2. As a resul t, the text wi dget was si zed to two l i nes at the font si ze of 24
poi nts speci fi ed.
So, even when a nongri d geometry manager such as packer i s i nvoked, a text wi dget
behaves as though gri dded at the resol uti on of i ndi vi dual chars.
Fi nal l y, l ooki ng at a detai l of example 1, the verti cal l i ne just to the l eft of 'A' i s the
text cursor of the i nteracti ve GUI (i n thi s case, Wi ndows). I n example 5, thi s cursor
was posi ti oned before the l ast 't' i n "text" and then swept to the fi rst 't' i n "String",
causi ng the sel ecti on hi ghl i ghti ng shown.
The hi ghl i ghted sel ecti on i n example 5 i s a wi ndow-system feature compl etel y
i nteroperabl e wi th Tk. Usi ng menu or keyboard copy-to-cl i pboard operati ons ({Ctrl }+{C}
i n Wi ndows), the sel ected text wi l l be copi ed to the system cl i pboard and may be pasted
to any runni ng appl i cati on capabl e of accepti ng text i nput. Li kewi se, addi ti onal text
may be pasted i nto the wi dget or entered, overwri tten, or del eted i nteracti vel y by typi ng
at the keyboard. Automati on of cut, paste, and text entry i s a great effort-savi ng
feature of Tk and speeds GUI devel opment consi derabl y.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
34
Character Indexing in a text Widget
Scri pted i ndexi ng i n a text wi dget i s di fferent from stri ng i ndexi ng i n pl ai n TcL. To
address a char i n a Tk text wi dget by i ts i ndex, the i ndex must be i n the form,
lineNo.charIndex. Li ne numbers start at 1; char i ndi ces start at 0.
Here i s an exampl e; the features other than i ndexi ng wi l l be expl ai ned bel ow:
proc showFrameText { WF WTop WTxt } \
{wm title . {Root Level = .};
#
frame .$WF -container true -height 3 -width 3; # h & w must be >= 3.
set FrameID [winfo id .$WF];
#
toplevel .$WTop -use $FrameID;
wm title .$WTop {Top Level = .$WTop};
#
set WTextPath $WTop.$WTxt; # To simplify the text widget window path.
#
text .$WTextPath -font "-size 16 -family Times" -height 2 -width 45;
.$WTextPath insert end "Hello. \$FrameID=$FrameID.\n" ;
.$WTextPath delete 1.5;
.$WTextPath insert 1.5 " from a text string!";
.$WTextPath insert 2.0 "frame=.$WF; toplevel=.$WTop; text=.$WTextPath.";
#
pack .$WF;
pack .$WTextPath;
}
showFrameText f top x;
The resul t appears l i ke thi s:
The sequence of text wi dget wi ndow commands i n showFrameText() does thi s:
• Fi rst, i t sets up the stri ng, "Hello. $FrameID=FrameI D.\n"
• Next, i t del etes the peri od after "Hello".
• Then, i t appends to "Hello", the stri ng, " from a text string!".
• Fi nal l y, the '\n' at the end of the stri ng havi ng defi ned a second l i ne of text, the
l ast insert command i nserts the i nformati onal stri ng,
"frame=.framePath; toplevel=.toplevelPath; text=.textPath."
I f the '\n' had been omi tted, the fi nal i nserti on, even wi th an address of l i ne 2,
si mpl y woul d have been appended to the rest of the stri ng. Whether thi s
resul ted i n a wrap to another l i ne woul d depend on the wi ndow wi dth and the
number and si ze of the text characters.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
35
The scri pti ng of text wi dgets i s a very compl i cated topi c; i t can i ncl ude embeddi ng of
subwi ndows and i mages i n a text stri ng and vari ous annotati ons of speci fi c characters or
offsets i n a stri ng. Refer to the Tk hel p system, and to Wel ch, et al., Chapter 36, for
more detai l on these compl exi ti es of the text wi dget.
A framed text wi dget behaves i nteracti vel y i denti cal l y to the unframed one i n the
showText() exampl e, above. For our present purposes, a frame doesn't add anythi ng
noti ceabl e to a si mpl e text wi dget di spl ay. We i ncl uded a frame i n the exampl e,
though, because a frame does have the uni que capabi l i ty of supporti ng the combi nati on
of other wi dgets wi thout i ntrudi ng wi th i ts own functi onal i ty (i t has none).
Noti ce that the framed wi ndow takes the title of the root wi ndow; the second wm
title command nami ng the toplevel had no vi si bl e effect. We shal l study the use of
toplevel l ater. We al so shal l see how to use Tk subordi nate wi ndow paths wi th a
frame.
We defi ned the frame wi dget i n the topl evel as a container object. Thi s was just
an excuse to show how to obtai n a wi ndow i d, because a container must be
mani pul ated by a wi ndow i d, rather than by i ts Tk wi ndow path.
I n Tk, i n general , a container object such as a frame i s desi gnated by the
toplevel opti on contai ner, and i ts wi ndow i s i denti fi ed by a screen-uni que wi ndow i d.
Each contai ned object must be desi gnated by the opti on use, the val ue associ ated wi th
use bei ng the wi ndow i d of i ts desi gnated container.
When used as a container, a toplevel wi dget such as a frame may not i ncl ude
any subordi nate wi ndow path. Thi s i s because a container may be ANY wi ndow i n
the di spl ay, not just a Tk wi ndow created by the current appl i cati on. Thi s exampl e was
just to i l l ustrate text i ndexi ng; we shal l l eave containers asi de, now, as too
compl i cated and di gressi ve for the present Workshop.
More text Modi fi cati on by Scri pt
We exami ne now how modi fi cati on of a text stri ng by the control l i ng scri pt can be
effected.
Fi rst, we poi nt out that i f a text wi dget i s used for user i nteracti ve i nput, i t i s
necessary for the control l i ng scri pt to be abl e to access the char or stri ng entered. Thi s
access i s avai l abl e si mpl y by runni ng the text wi dget wi ndow wi th the get opti on. An
i ndex of a si ngl e character may be provi ded for get, or a range. The enti re contents of a
text wi dget wi l l be returned i f the range i s "1.0 end".
We i ncl ude thi s feature i n the next few exampl es; thi s way, i t wi l l be fami l i ar when
we i ntroduce control of entry wi dgets, whi ch are the basi c Tk tool s for i nteracti ve text
i nput.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
36
Here i s an exampl e i n whi ch the scri pt merel y copi es the (scri pted) stri ng val ue of a
text i nto a label:
proc getTextToLabel { Win Txt } \
{wm title . {Text Get and Put Into Label};
#
# Initialize the text widget:
text .$Win -font "-size 16 -family Times" -height 2 -width 40;
.$Win insert end "$Txt\n" ;
#
# Get the first line of text and print it in a label:
set LabelMsg [.$Win get 1.0 1.end];
label .x$Win -text $LabelMsg -font {-size 24} -bg pink -fg black;
#
# Display the text and label together:
pack .$Win .x$Win;
}
getTextToLabel t "Hello Cruel World!";
The di spl ayed resul t:
Whi l e we are experi menti ng wi th text wi dgets, l et's expl ore the effect of vari ous
control s upon the di spl ay. We assume we want the di spl ay to be control l ed by a si ngl e
TcL proc i n a si ngl e wish i nvocati on, packed i n a si ngl e wi ndow.
We shal l see l ater how to use a si ngl e proc to create mul ti pl e, di fferentl y packed,
i ndependent wi ndows.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
37
Window Destroy and Replace
Fi rst, i f we wi sh our scri pt to repl ace a wi ndow wi th an i denti cal one but perhaps
wi th new contents, one si mpl e way i s to use Tk destroy. Thi s works for any wi dget.
NOTE: I t i s an error i n Tk to attempt to create a wi ndow of a name
whi ch al ready exi sts.
I n the fol l owi ng, we use the TcL after command to del ay the change so i t i s
ani mated on the screen. The TcL after i s a sequenti al , not concurrent, control . I t sets
a runti me command executi on del ay of some number of mi l l i seconds:
proc textIO_Destroy { Win Txt } \
{if { [winfo exists .$Win] } { destroy .$Win .x$Win; }
wm title . {Text Replace with Destroy};
#
# Initialize the text widget:
text .$Win -font "-size 16 -family Times" -height 2 -width 40;
.$Win insert end "$Txt\n" ;
#
# Get the first line of text and print it in a label:
set LabelMsg [.$Win get 1.0 1.end];
label .x$Win -text $LabelMsg -font {-size 24} \
-bg pink -fg black -height 2 -anchor n;
#
# Display the text and label together:
pack .$Win .x$Win;
}
set Msg "Hello Cruel World!";
textIO_Destroy t $Msg; # Initial display.
set Msg "2nd $Msg";
after 2000 { textIO_Destroy t $Msg; }; # Delayed display.
The resul ti ng screen di spl ay:
I ni ti al l y: After two seconds:
I t's not hard to see how thi s ki nd of proc coul d be cal l ed not just twi ce, but i n a l oop,
to i mpl ement i nteracti ve GUI -control l ed edi tti ng of text.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
38
Packed Append of text Value
Second, we si mpl y can append the new contents at the same wi ndow paths; we have
seen how thi s works i n previ ous packer exampl es. Of course, we can not re-create an
exi sti ng wi ndow path, al though we can re-pack i t; so, we must test for preexi stence.
Thi s ki nd of appendi ng works for text wi dgets but not for labels.
To modi fy the label di spl ayed, we woul d have had to append to the stri ng and run,
.x$Win -text NewString ... .
proc textIO_SameWin { Win Txt } \
{wm title . {Text Append in Same Window};
#
# Initialize the text widget:
if { ![winfo exists .$Win] } \
{ text .$Win -font "-size 16 -family Times" -height 2 -width 40; }
.$Win insert end "$Txt\n" ;
#
# Get the first line of text and print it in a label:
set LabelMsg [.$Win get 1.0 1.end];
if { ![winfo exists .x$Win] } \
{ label .x$Win -text $LabelMsg -font {-size 24} \
-bg pink -fg black -height 2 -anchor n; }
#
# Display the text and label together:
pack .$Win .x$Win;
}
set Msg "Hello Cruel World!";
textIO_SameWin t $Msg;
set Msg "2nd $Msg";
after 2000 { textIO_SameWin t $Msg; }
The resul ti ng screen di spl ay:
I ni ti al l y: After two seconds:
Packed Supplement of text Value
Thi rd, we can create a new wi ndow and di spl ay i t i n addi ti on to ones al ready vi si bl e.
Thi s suppl ements the preexi sti ng wi ndow(s); packer sees both wi ndows i n the two proc
cal l s as new ones.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
39
The code i s i denti cal to that of the precedi ng exampl e, but the wi ndow ti tl e i s
di fferent and the fi nal , del ayed runti me cal l of the proc now i s changed so i t i s passed a
di fferent wi ndow path,
after 2000 { textIO_SameWin u $Msg; }
The resul ti ng screen di spl ay:
I ni ti al l y: After two seconds:
Order of Creation Effect
I t i s i nteresti ng to see what i s di spl ayed i f we attempt both to append and to
suppl ement a new stri ng i n a preexi sti ng wi ndow hi erarchy, usi ng thi s termi nol ogy as
we have i n the i mmedi atel y precedi ng exampl es. Here are the two possi bi l i ti es:
Append before suppl ement. The code i s:
proc textIO_AppSupp { Win Txt } \
{wm title . {Text Append then Supplement};
#
# Initialize the text widget:
if { ![winfo exists .$Win] } \
{ text .$Win -font "-size 16 -family Times" -height 2 -width 40; }
.$Win insert end "$Txt\n" ;
#
# Get the first line of text and print it in a label:
set LabelMsg [.$Win get 1.0 1.end];
if { ![winfo exists .x$Win] } \
{ label .x$Win -text $LabelMsg -font {-size 24} \
-bg pink -fg black -height 2 -anchor n; }
# Display the text and label together:
pack .$Win .x$Win;
}
set Msg "Hello Cruel World!";
textIO_AppSupp t $Msg;
after 2000 \
{set Msg "2nd $Msg"; textIO_AppSupp t $Msg; # The "append".
set Msg "3rd $Msg"; textIO_AppSupp u $Msg; # The "supplement".
}
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
40
The resul ti ng screen di spl ay:
I ni ti al l y: After two seconds:
Suppl ement before append. The code i s the same, but the pai r of del ayed runti me
cal l s i s reversed i n order:
The resul ti ng screen di spl ay:
I ni ti al l y: After two seconds:
We shal l l eave the topi c of text wi dgets now. The mai n val ue of these wi dgets i s
that they can be i mpl emented to present bl ocks of edi ttabl e or sel ectabl e text. The text
i n a label, for exampl e, i s not sel ectabl e and so can not be copi ed to the system
cl i pboard or pasted from i t.
When a text stri ng i s requi red to enter control parameters or data for di rect GUI
operati on, more useful than a text wi dget i s the very si mi l ar entry wi dget.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
41
Event Bi ndi ng
Using global in the label Widget
Before proceedi ng to the most i nteresti ng features of text entry by entry, i t i s
necessary to excuse the use of global vari abl es i n the exampl es to fol l ow. General l y, i t
i s ri sky desi gn to cal l procedures wi th references to global (as opposed to upvar)
vari abl es.
Here i s the reason for the globals: There i s a bug, or possi bl y a desi gn fl aw, i n the
label i mpl ementati on i n current TcL (ActiveTcl v. 8.5.7 and previ ous): One can not
pass a proc argument vari abl e by name to a label, even i f the name refers to a
vari abl e whi ch certai nl y wi l l persi st for the durati on of the GUI . I nstead, bi zarrel y, the
i nterpreter al l ows the label wi dget to vi ol ate stack-frame i ntegri ty and treat proc-
l ocal vari abl es as though they had been decl ared global.
Here i s an exampl e. The fol l owi ng code, run i n wish, shoul d create a label whi ch
di spl ays the message text passed to the proc:
proc doLabelBug { Win Txt} \
{wm title . {Bug in label -textvariable};
upvar $Txt Msg_L;
#
label .x$Win -textvariable Msg_L \
-font {-size 16 -family Courier} -width 40 -bg pink -fg black;
pack .x$Win;
}
set Msg "Here is some TEXT.";
doLabelBug t Msg;
I nstead, the wi ndow i s bl ank:
The upvar vari abl e named i n the label command i s parsed correctl y, and no error i s
reported, but the val ue di spl ayed i s nul l , as though the label command coul d not read
the vari abl e; thus, no message appears.
However, changi ng the label command vari abl e reference above from Msg_L to
(i l l egal ) Msg works wel l :
Unfortunatel y, $Msg shoul d be i naccessi bl e wi thi n the proc. To avoi d thi s probl em,
the exampl es bel ow are wri tten i n l egal TcL by fl aggi ng every -textvariable vari abl e
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
42
i n a label command as global and not passi ng i t as an argument. When the bug i s
fi xed, these exampl es sti l l wi l l run correctl y.
Here i s the workaround for the precedi ng code; the wi ndow text i s di spl ayed correctl y:
proc doLabelBug { Win } \
{wm title . {global fixed label -textvariable};
#
wm iconbitmap . @TkIconBWneg.xbm; # fore-background inverted.
#
global Msg;
#
label .x$Win -textvariable Msg \
-font {-size 16 -family Courier} -width 40 -bg pink -fg black;
pack .x$Win;
}
set Msg "Here is some TEXT."; # $Msg legally is global because of the proc.
doLabelBug t;
The resul t (i n Wi ndows, wi th a di fferent desktop styl e -- noti ce the i con!):
Copi es of the precedi ng scri pts showi ng thi s bug and workaround are i n your ~/doc
di rectory.
The bind Command and a Simple entry
The term bi nd i s about the same i n Tk as i t i s i n X: A bind associ ates a GUI event,
such as a mouse movement, sel ect, or keyboard keypress, wi th a scri pt acti on.
We al ways have used TcL proc decl arati ons i n our exerci ses and exampl es; however,
from a TcL scri pti ng poi nt of vi ew, up to now, our scri pts al ways have been run to
compl eti on, the procs havi ng been cal l ed and termi nated. From a TcL poi nt of vi ew,
each of our scri pts has ended and has gone out of exi stence.
But, i n Tk, scri pts are used to create wi ndows and the wi dgets they contai n.
Whenever our scri pts have termi nated, the wish i nstance runni ng them has not; and,
unti l we di smi ssed the wish wi ndow, the GUI created by the scri pt remai ned vi si bl e and
i n fact functi onal . Actual l y, even wi th the scri pt done, our previ ous wi ndows just have
been wai ti ng for an i nterrupt to do somethi ng more.
We had a hi nt of scri ptl ess wi ndow acti vi ty when we showed how a text wi dget
al l owed sel ecti on of the text and i nteracti ve edi tti ng of i t; no scri pt acti vi ty was i nvol ved.
Now we shal l see how a wi ndow can reacti vate a scri pt. Thi s can be done by bindi ng a
Tk GUI wi ndow event to the TcL code i n a scri pt.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
43
The Tk bind command requi res speci fi cati on of a wi ndow (or tag; we shal l ski p tags
i n the present Workshop and onl y consi der wi ndows), a GUI event, and a scri pt
(command) to be run when the event occurs.
From here on, for text entry, we shal l not use a text wi dget proper but rather the
very si mi l ar entry wi dget. We do thi s because the syntax and opti ons are a l i ttl e
di fferent and thus demand some attenti on; but, mai nl y, because entry wi dgets i ncl ude
the feature of automati c val i dati on, somethi ng very useful i n GUI desi gn and l acki ng i n
text wi dgets.
A text wi dget i s for di spl ayi ng and edi tti ng text; an entry wi dget i s to
provi de requi red text i nput for the GUI .
For exampl e, to extend our most recent exampl es, here i s how a label can be
modi fi ed i nteracti vel y by scri pt whi l e edi ti ng some text:
proc doSimpleEntry { Win } \
{wm title . {Simple Entry Into Label};
global Txt;
#
if { [winfo exists .$Win] } \
{ set Txt [.$Win get]; } \
else {entry .$Win -font {-size 14 -family Times} -width 30;
# Initialize the text:
.$Win insert end $Txt;
pack .$Win;
}
# The label:
if { ![winfo exists .x$Win] } \
{label .x$Win -textvariable Txt -bg yellow -fg black \
-font {-size 16 -family Courier -weight bold};
pack .x$Win;
}
}
set Txt "Enter text here: ";
doSimpleEntry t;
bind . <Key> {doSimpleEntry t};
Noti ce that an entry wi dget's get opti on does not i ncl ude an i ndex range. The get
opti on for a text wi dget requi red an i ndex expressi on, because text edi tti ng i n general
i s mul ti l i ne and requi res more preci se access than does command-rel ated entry of text
whi ch i s i ntended sol el y to be processed by the GUI .
The condi ti onal wi ndow creati on if's are i ncl uded so that the doSimpleEntry() proc
mi ght be cal l ed more than once wi thout generati ng an error: I n a gi ven wish sessi on,
the entry wi ndow and label wi ndow creati on commands wi l l be run onl y once; al so,
the packer wi l l be cal l ed onl y once for each wi ndow.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
44
Why worry about mul ti pl e cal l s? Because of the bind. The bind causes the proc
to be rerun whenever a key i s pressed or rel eased. Thus, unl i ke any other scri pt we
have seen before, thi s one updates the label vari abl e i nteracti vel y.
Looki ng at the scri pt runti me, the fi rst cal l to doSimpleEntry() di spl ays the label
wi th the i ni ti al val ue of $Txt. After that, the bind statement causes
doSimpleEntry() to be cal l ed agai n whenever there i s any keyboard acti vi ty. Noti ce
that a bind event i s i denti fi ed by a keyword wri tten i n angl e brackets ('<' and '>').
There are user-defi ned vi rtual events, too; these are referenced by thei r decl ared names
i n doubl e angl e brackets ("<<" and ">>"). We shal l not di scuss user-defi ned vi rtual
events further i n thi s Workshop.
The i ni ti al resul t of runni ng the above scri pt i n
wish i s the stri ng provi ded before the proc cal l :
The label i nteracti vel y
i s updated as we enter
some new text:
Noti ce how packer has extended the label wi ndow to accommodate the label text,
whi ch, as we know, i s dynami c and al ways di spl ays the current val ue of the stri ng
vari abl e desi gnated.
The stri ng shown i n the fi gure i mmedi atel y above i s at the maxi mum whi ch wi l l fi t i n
the 30-character entry wi ndow wi thout scrol l i ng. Unl i ke a text wi dget, whi ch may be
many l i nes and may wrap, an entry wi dget can di spl ay onl y one l i ne.
Predi ctabl y, because an entry i s one l i ne onl y, wi th the mouse cursor i n the entry
wi ndow, a keyboard NL (return key) i s i gnored i n the entry di spl ay. The entry text
doesn't change, so nei ther does the label di spl ay. However, any event binded by
<Key> woul d be tri ggered by each such NL entry.
I n the precedi ng scri pt, al l pri ntabl e ASCI I characters except NL are copi ed to the
label l i teral l y. I f text i s entered whi ch exceeds the entry wi dth, the label wi l l
conti nue to be wi dened, and the entry wi ndow wi l l scrol l si deways to the l eft to keep
the text cursor vi si bl e, no matter how l ong the stri ng.
The get i n the binded scri pt makes i t respond
to al l keyboard entry edi ts. Here i s the resul t
of backspaci ng from the keyboard over most of
the previ ous text:
I f the text had been al tered by mouse acti vi ty -- for exampl e, by a paste -- the label
text shoul d not change unti l after keyboard acti vi ty occurred.
Concerni ng keyboard vs. mouse events, see the note i n the secti on entry Validation
example bel ow, for a mi nor bug i n Tk.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
45
I nteracti ve Text Entry and Val i dati on
The entry wi dget effects consi derabl e automati on of the val i dati on of the format and
content of a stri ng entered i nteracti vel y. But, before val i dati on, l et us study bindi ng
and focus of an entry i n a l i ttl e more detai l .
entry: bind Keywords
The mai n bind keywords for di fferent events are:
bind Keyword Event Descri pti on
Key
Any acti vati on of a keyboard key
KeyPress
Depressi on of a keyboard key
KeyRelease
Rel ease of a depressed keyboard key
Button
Any acti vati on of a mouse button
ButtonPress
Depressi on of a mouse button
ButtonRelease
Rel ease of a depressed mouse button
Motion
Any moti on of the mouse cursor i n the
wi ndow contai ni ng the entry
See the Tk hel p system for other event bi ndi ngs.
entry: Window focus
The focus refers to the wi ndow or subwi ndow responsi ve to keyboard events; such a
wi ndow i s sai d to be the wi ndow wi th the focus. Dependi ng on the wi ndow system
confi gurati on, ei ther movi ng the mouse cursor i nto a wi ndow or pi cki ng i n the wi ndow
by pressi ng a mouse button wi l l gi ve that wi ndow the focus. For a wi ndow wi th
subwi ndows, a subwi ndow typi cal l y woul d be a menu choi ce or a di al og button.
To edi t text i n an entry (or a text), i t i s necessary to gi ve i ts wi ndow the focus,
because onl y a wi ndow wi th the focus wi l l di spl ay a text-i nserti on cursor. I n
movement-sensi ti ve systems, for wi ndows wi th subwi ndows, once the focus has been set
i n a subwi ndow, removi ng the mouse cursor and l ater returni ng i t to that wi ndow
restores the most recent focus; thi s i s a bui l t-i n Tk feature.
I t i s possi bl e to control the focus wi thi n a scri pt, rather than i nteracti vel y. Usual l y,
thi s i s to i ni ti al i ze a wi ndow before the fi rst user i nteracti on has occurred. The focus
may be set i n a scri pt by desi gnati ng the defaul t choi ce i n a creati on command (when
the wi dget permi ts thi s), or by runni ng the focus command i n the scri pt. See the Tk
hel p system for more detai l s on the focus command.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
46
The entry, l i ke the text, al l ows many more opti ons and control s than we can
present i n thi s Workshop; be sure to read the Tk hel p manual for more i nformati on.
Here i s a scri pt whi ch di spl ays al l avai l abl e entry confi gurati on opti ons:
proc showEntryConfigs { Win } \
{wm title . {All Tk entry configuration options};
if { ![winfo exists .$Win] } \
{
entry .$Win -font {-size 14 -family Courier} -width 28;
.$Win insert end ".$Win configuration --> ";
.$Win insert end "[.$Win configure]";
#
label .x$Win -height 14 -wraplength 1200 -text "[.$Win get]" \
-bg cornsilk -fg black \
-font {-size 10 -family Helvetica -weight bold};
#
pack .$Win .x$Win;
}
}
showEntryConfigs entryWin;
The entry -configure defaul t return val ue i s a TcL l i st of al l configure parameters. Wi th
monospaced font, the -width val ue exactl y equal s the entry stri ng character count.
The -wraplength 1200 assumes uni ts i n number of pi xel s; these defaul t uni ts may
be changed: See the Tk hel p for Tk_GetPixels.
entry: Validation
Because the entry i s i ntended to accept user i nput whi ch i s not to be read by the user
but to be operated upon by the GUI , i t i s necessary to be sure that the GUI scri pts can
handl e what was entered. For exampl e, a user mi ght mi sunderstand the purpose of an
entry and type i n words when numeral s were expected. Or, the entry mi ght have
been l eft bl ank whi l e a GUI command requi ri ng nonbl ank i nput was run. Thi s i s not a
probl em when buttons or menu choi ces are used, because they return fi xed, predefi ned
val ues determi ned by the Tk programmer; but, i t i s a probl em when the user i s asked to
provi de an arbi trary fi l e name, numeri cal val ue, or speci fi cal l y-formatted stri ng.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
47
Rather than compl i cate the GUI scri pts, Tk i s desi gned to al l ow rejecti on or correcti on
of i nput errors up front, ri ght at the poi nt of i nput: The entry wi dget i s provi ded wi th
bui l ti n val i dati on opti ons.
The val i dati on-rel ated entry opti ons i ncl ude one to sel ect the mode of val i dati on and
another to speci fy a TcL command (or proc) to perform the val i dati on. The speci fi ed
val i dati on command must return a pass/fai l (true/fal se) bool ean val ue; thi s means, i n
TcL, a '1' or a '0'. The modes are named i n an enumerati on as fol l ows: {none, key,
focus, focusin, focusout, all}. The defaul t i s none, maki ng the entry act
somewhat l i ke a pl ai n text wi dget l i mi ted to one l i ne.
We shal l cover the modes i n detai l bel ow. The TcL i nterpreter can change the mode
to none on certai n errors, whi ch di sabl es val i dati on and al l ows arbi trary (erroneous)
text to persi st i n the entry; thi s al l ows the user to see the error and perhaps correct i t.
I n parti cul ar, i f a val i dati on command returns anythi ng but a bool ean val ue, the entry
i mmedi atel y wi l l change the val i dati on mode to none.
An i mportant entry val i dati on opti on al l ows speci fi cati on of a TcL command (proc)
to be run i f val i dati on fai l s.
Here are the mai n entry opti ons rel ated to val i dati on, wi th -validatecommand and
-invalidcommand shown as thei r standard abbrevi ati ons, -vcmd and -invcmd,
respecti vel y:
Database Name Purpose and Command Syntax Example
validate
Sets the val i dati on mode:
-validate mode
entry .$Win ... -validate key ...;
validateCommand
Speci fi es the val i dati on command:
-validatecommand cmdName
entry ... -vcmd "goodFname Input" ...;
invalidCommand
Speci fi es the command to run on
val i dati on false:
-invalidcommand cmdName
entry ... -invcmd bell ...;
The Tk hel p system recommends that the usual command named i n the
invalidCommand opti on shoul d be bell, whi ch i s the bui l ti n Tk command to sound the
audi bl e bell i n the appl i cati on mai n wi ndow. Thus, an entry error ri ngs the bel l and
does nothi ng el se. Recal l that the X-wi ndows envi ronment can be confi gured by the
user to modi fy the bell to be a vi sual bl i nk rather than, or i n addi ti on to, an audi bl e ri ng.
Later, we shal l see how to present a message box on error. Showi ng the user the
erroneous entry and tel l i ng why the entered val ue was wrong can be very hel pful . The
purpose of a GUI i s to hel p the user, after al l . . ..
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
48
The val i dati on modes are as fol l ows:
none Val i dati on i s di sabl ed (the defaul t).
key Every keyboard event tri ggers a val i dati on.
focus Any change i n entry wi ndow focus tri ggers val i dati on.
focusin Val i dati on i s tri ggered whenever the entry gai ns the focus.
focusout Val i dati on i s tri ggered whenever the entry l oses the focus.
all Any keyboard or focus event tri ggers val i dati on.
entry Validation example
Now we can show how to use the val i dati on features of the entry wi dget. I n the next
code exampl e, noti ce that the val i dati on command i s a proc decl ared wi thi n the proc
control l i ng the entry wi dget. Thi s i s a very useful feature, because i t coordi nates a
speci fi c val i dati on wi th a speci fi c entry creati on. However, keep i n mi nd that a TcL
proc name i s gl obal , and that the name of the val i dati on proc wi l l be vi si bl e to al l
other procs, entry-creati ng or not, i n the appl i cati on. Confl i cti ng proc names create
unpredi ctabl e runti me, because the l ast proc decl ared of a gi ven name i s the one whi ch
woul d be run everywhere. Thus, to avoi d the overhead of i ntroduci ng namespace
compl exi ti es, i t pays manual l y to "mangl e" a speci al i zed val i dati on proc name by
maki ng i t depend on the name of the proc whi ch contai ns i t.
An al ternati ve approach woul d be to defi ne a smal l number of generi c val i dati on
procs whi ch were cal l ed for certai n cl asses of entered data; for exampl e, one for text but
not numeral s, another for i ntegers, another for fl oats, etc. These generi c procs coul d be
used anywhere i n the appl i cati on and coul d be cal l ed (or repl aced) by more speci al i zed
val i dati on procs, i f the l atter became necessary i n i ndi vi dual cases.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
49
Here i s an exampl e of the use of speci al i zed val i dati on:
proc getInteger { Win } \
{wm title . {entry Integer Validation};
global UserInt;
# Local validateCommand:
proc val_getInteger {Win} \
{global UserInt;
if {[string is integer -strict $UserInt]&&[string length $UserInt]==2} \
{tk_dialog .v$Win "SUCCESS" \
"Very good: $UserInt is valid." {} 0 "Dismiss" ;
return 1;
} else {return 0;}
}
# Local invalidateCommand:
proc inval_getInteger {Win} \
{bell;
tk_dialog .i$Win "ERROR" "Value must be a 2-digit integer.\nTry again." \
{} 0 "Dismiss";
return 1;
}
# proc runtime:
if { [winfo exists .$Win] } \
{ set UserInt [.$Win get]; } \
else { entry .$Win -font {-size 18 -family Courier} -width 20 \
-validate focusout -vcmd "val_getInteger $Win" \
-invcmd "inval_getInteger $Win";
pack .$Win;
}
}
set IWin "iIn"; # Window names must be uncapitalized.
getInteger $IWin;
bind . <Key> "getInteger $IWin"; # For some reason, <Key> works best!
The entry awai ts i nput thi s way:
I f "OK" i s entered and the user pi cks somethi ng outsi de the entry wi ndow, thi s i s
i nval i d, and the tk_dialog wi ndow appears (here moved next to the entry):
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
50
Apparentl y, there i s a mi nor bug here: Al though the event i n the scri pt says "<Key>",
i n Tk v. 8.4 through 8.5.7, a pi ck wi th the mouse button works the way "<Button>"
woul d be expected to work, and repl aci ng <Key> wi th <Button> gi ves unrel i abl e entry
processi ng.
Anyway, i f "19" i s entered, the entry accepts thi s val ue, the resul t i s saved i n
$UserInt, and the user i s free to proceed wi th other acti ons i n the GUI . I n our
exampl e, we present a confi rmi ng tk_dialog; but, i n the usual GUI , such a wi ndow
woul d not be created. The appearance i s:
After a val i d entry (and i n our case, after di smi ssal of the confi rmi ng tk_dialog), the
entry wi dget remai ns; i t may be moved or reedi tted unti l some other GUI runti me
destroys i t.
There are several thi ngs of i nterest i n thi s exampl e:
• Noti ce that the entered, val i dated resul t i s set i nto the global $UserInt, whi ch
i s reci procal l y accessi bl e to any proc i n the appl i cati on al so decl ari ng i t global.
• The wi dth of 20 for the entry i s excessi ve for a 2-di gi t i nteger; i t was set that way
so that the entry wi ndow ti tl e coul d be read wi thout i nteracti ve stretchi ng. Thi s
normal l y woul d not be necessary, because an entry usual l y i s not a standal one
wi ndow but i s a subwi ndow appeari ng i n the GUI as an edi ttabl e fi el d.
• The tk_dialog i s a modal wi ndow whi ch must be di smi ssed before the entry wi l l
accept any further i nput. I t i s shown above as i t i ni ti al l y appeared, wi thout the
focus, because when the user pi cked outsi de the entry wi ndow to tri gger
val i dati on, somethi ng el se i n the runni ng OS wi ndow system got the focus.
However, wi thi n the Tk appl i cati on, the tk_dialog wi l l take focus whenever any
runni ng wi ndow of the Tk appl i cati on i s pi cked.
• There i s no reason to test for a preexi sti ng tk_dialog wi ndow path, because a
tk_dialog automati cal l y destroys the preexi sti ng wi ndow of the gi ven path and
repl aces i t. However, the entry wi ndow path must be tested to avoi d an error on
keyboard or mouse events.
• The return val ue of the invalidCommand i s not used; but, i t i s wi se al ways to
provi de i t, because habi tual l y omi tti ng i t may cause a sl i p of omi tti ng the return
for the validateCommand, whi ch i s requi red.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
51
• Dependi ng on context, getInteger() coul d be used to return somethi ng to
i ndi cate each ti me that i t was run. However, gi ven the usual concurrency of a
GUI , a scri pt sequence dependi ng on mere compl eti on of a cal l to getInteger()
l i kel y woul d not be under meani ngful control . Subsequent user i nput probabl y
woul d be the best way to use the resul t of getInteger() . I t al so mi ght be useful
to have the val i dati on proc set some sort of success fl ag associ ated wi th
$UserInt. I n C++, such a fl ag woul d be encapsul ated wi th the val ue $UserInt;
but, the scri pti ng overhead of such encapsul ati on probabl y woul d be too
compl i cated for Tk, whi ch i s meant for rapi d and si mpl e GUI devel opment.
Lab 2: Text I/O
Log i n and change to your Lab02 di rectory.
These exerci ses are somewhat more compl i cated that the ones of Lab 1, so i t probabl y
woul d be a good i dea to test your work by i nvoki ng wish i n a shel l scri pt whi ch names
your .tcl fi l e, rather than repeatedl y i nvoki ng wish i nteracti vel y. You may, of course,
set up a shel l scri pt to exec to wish, as was shown previ ousl y (p. 26).
Step 1: Si mpl e text wi dget. Wri te a TcL scri pt whi ch uses a decl ared proc to
create and di spl ay a text wi dget wi th these characteri sti cs:
• Three l i nes of text, the l i nes respecti vel y sayi ng: "Here's l i ne 1, And here's l i ne
2, And l i ne 3." Cal l your proc once for thi s, not three ti mes.
• The text wi ndow banner (title) shoul d say, "Lab 2, Step 1".
• The text shoul d be Times fami l y, 16 poi nt, bol d, and i tal i ci zed.
• The text background col or shoul d be a l i ght shade of green, and the text stri ng
shoul d be a dark bl ue (use TcL hel p on colors for col or names).
Step 2: Stati c text transferred to a label. Repeat the Step 1 exerci se; but, i n
addi ti on, i n the same wi ndow bel ow the text, add a label wi dget whi ch repeats the
second l i ne, onl y, of the text contents.
The banner shoul d say, "Lab 2, Step 2".
The label wi dget shoul d be i n Courier fami l y font, 18 poi nt, and underl i ned. The
label background col or shoul d be l i ght bl ue and the label stri ng dark green.
Step 3: An entry i nput val i dated and wri tten to di sc. Wri te a TcL scri pt whi ch
di spl ays an entry wi dget i n a wi ndow wi th banner "Lab 2, Step 3". I n addi ti on,
• The entry must be decl ared and run i n a si ngl e proc. Val i dati on processi ng of
i nput must be by procs decl ared i nsi de the entry's proc.
• The entry proc must accept one argument, a wi ndow name.
• A val i d entry shoul d be any ASCI I stri ng, al l i n l ower case, more than 6
characters l ong and fewer than 20 characters l ong.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
52
• I f the entry i s val i d, the wi dget shoul d tri gger a wri te of the val ue to a di sc fi l e
named Lab2_Step3.txt. The scri pt then shoul d exi t wi th no message or any
other i ndi cati on of success, l eavi ng onl y the di sc fi l e.
• I f the entry i s i nval i d, the entry shoul d sound the bel l and present a
tk_dialog di spl ayi ng the i nval i d entry val ue and stati ng the condi ti ons whi ch
woul d make i t val i d.
Test your scri pt by runni ng the entry and enteri ng val i d stri ngs al l i n l ower case.
Then, try to tri gger a val i dati on error wi th some upper-case chars. Al so try stri ngs too
short and too l ong. Do you want to al l ow spaces or tabs? What i f the output fi l e exi sts
but ei ther i t or the current di rectory refuses wri te permi ssi on?
Opti onal exerci ses. I f ti me i n thi s l ab permi ts, compl ete the fol l owi ng two
addi ti onal Steps:
Step 4: Text i nput i nteracti vel y transferred to a label. Wri te a TcL scri pt whi ch
presents a text and a label wi dget, label above text, and has a banner "Lab 2, Step
4".
The text wi dget shoul d be i ni ti al i zed wi th a stri ng; i f the user modi fi es the stri ng
i nteracti vel y, the label i mmedi atel y shoul d di spl ay the modi fi ed stri ng.
Al so, sel ect some of the stri ng i nteracti vel y (usi ng your mouse cursor), cut i t, and
paste the cut text i nto a vim wi ndow to show that thi s Tk wi dget permi ts cut-and-paste
edi tti ng.
Try pasti ng some text from vim i nto the text wi ndow, too.
Step 5: Numeri cal entry wi dget. Wri te a TcL scri pt whi ch creates an entry
wi dget i n a wi ndow wi th banner, "Lab 2, Step 5". The entry shoul d be coded i n a proc
and shoul d accept onl y numeri cal i nput (deci mal i ntegers, a '+' or '-' si gn, and at most
one deci mal poi nt) of any magni tude. The entry si mpl y shoul d ri ng the bel l on
i ncorrect i nput. On correct i nput, i t shoul d copy the val ue to a tk_dialog wi ndow for
di spl ay.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
53
Image Creation and Manipulation
We presented the wm iconbitmap and the image create commands at the
begi nni ng of the Workshop. We showed how to di spl ay a two-col or bitmap i mage i n a
wi ndow or as an i con. We al ready have sai d enough about wm iconbitmap; so, we'l l
just revi si t image now, for a l i ttl e whi l e, to revi ew and expand on the use of i mages i n
Tk.
Once we have (re)covered image creati on, we can move on to a l ab-based survey of
some of the more compl ex of the Tk wi dgets.
Namespaces
I t's assumed the attendee i s fami l i ar at l east wi th the concept of TcL namespaces.
Al though rarel y useful i n scri pti ng, subdi vi si on of the TcL namespace by the namespace
command has advantages i n si mpl i fyi ng the coordi nati on of work when mul ti pl e
devel opers are contri buti ng to the same l arge project. Such a project usual l y woul d be
GUI based.
We cannot do such a project i n our one day. However, we shal l show how to use a
separate namespace pro forma for the storage of i mages. The i dea wi l l be to decl are
i mages i n thei r own namespace, whi ch we shal l cal l iSpace. The reason for thi s i s that
decl ared image names, l i ke decl ared proc names, are gl obal . Wi th thi s rul e i n force,
we can name images arbi trari l y wi thout fear of repl aci ng a proc wi th an image
acci dental l y of the same name. Of course, i n thi s Workshop, we al ready have adopted
the conventi on of nami ng procs al ways uncapi tal i zed, so we coul d achi eve the same
goal by nami ng images al ways capi tal i zed. But, we'l l use namespace for dri l l .
By way of revi ew, namespace eval NameSpace { ... } creates or extends a
namespace named NameSpace contai ni ng TcL decl arati ons or runti me wi thi n the
braces. I f a proc i s decl ared i n a namespace, i ts name i s no l onger gl obal but i s vi si bl e
onl y i n that namespace. However, the global command sti l l may be used i n a
namespace to mani pul ate gl obal (scri pt-l evel ) vari abl es.
The variable command must be used i nstead of the set command to mani pul ate
vari abl es i n reference to a namespace. The namespace exists Name command may
be used to test for exi stence of a namespace named Name. Namespaces consti tute a
hi erarchy. The creati on context or root of al l namespaces i s nul l or may be wri tten
"::"; hi erarchi cal separators are "::".
A variable V decl ared i n a namespace N can be assi gned from outsi de N by,
variable N::V value;, and i t's val ue can be expressed by, $N::V. Vari abl es or procs
wi thi n a namespace may be addressed hi erarchi cal l y. I mages shoul d be assi gned to
vari abl es for reference outsi de a namespace.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
54
The commands just descri bed wi l l be demonstrated i n the exampl e bel ow. We have
no speci al reason to use any of the many other namespace commands i n thi s Workshop.
Here i s a si mpl e label wi th an i mage decl ared i n namespace iSpace:
namespace eval \
iSpace {
variable LeverImage \
[image create bitmap LeverImage -file Lever_Bitmap.xbm];
}
#
proc labelNamespace { Win Img } \
{wm title . {Label with Image in iSpace};
label .q$Win -text "This Image is in iSpace" -font {-size 24} \
-compound top -image $Img -bg {light blue};
pack .q$Win ;
}
labelNamespace x $iSpace::LeverImage;
The resul ti ng di spl ay i s,
The image Command
The subcommands to image most useful for us are create, delete, and names; see
the Tk hel p system for other subcommands.
image create
Thi s command decl ares an image; i t does not di spl ay i t. The decl ared name i s
returned. Tk can not access an i mage the name of whi ch whi ch has not been decl ared.
Once decl ared, an image can be executed by name i n the usual way, as can be other Tk
wi dgets. Syntax:
image create type ?name? ?type_options?;
The type shoul d be bitmap; the onl y al ternati ve i s photo, whi ch we shal l not
el aborate upon i n thi s Workshop.
The name i s opti onal , because Tk can create a name automati cal l y; however, i t i s
good practi ce to prevent future name confl i cts, or repl ace exi sti ng i mages i f desi red, by
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
55
speci fyi ng the name i n the command. Names of images are gl obal and vi si bl e
everywhere, l i ke names of procs.
Li ke a tk_dialog, image create si l entl y wi l l repl ace anythi ng of the same name
wi th the image of the name i t i s decl ari ng; thi s wi l l occur even i f the preexi sti ng name
i s that of a TcL procedure. Therefore, i t i s a good i dea to adopt a confl i ct-free nami ng
conventi on for images. The TcL namespace construct may be used to i sol ate i mage
names from others; thi s i s the recommendati on i n the Tk hel p system.
For GUI projects of moderate si ze, or for any project wi th a proc-nami ng rul e,
perhaps a preferabl e approach woul d be C++-l i ke name mangl i ng. A reasonabl e
mangl i ng al ternati ve woul d be al ways to name each image for the proc i n whi ch i t i s
created. For exampl e, a proc named makeMainMenu woul d create onl y images named
makeMainMenu_Image01, etc. Thi s object-ori ented al ternati ve has the advantage of
i denti fyi ng the creator of every i mage whenever that i mage i s accessed.
The type_opti ons are associ ated wi th the image type decl ared. For bitmap, these
i ncl ude background and foreground col ors (-background and -foreground), the
l ocati on of the i mage bi t-map defi ni ti on (-file or -data, i n whi ch -data expresses a
stri ng i n the same format as -file), and ei ther a fi l e or a stri ng defi ni ng the i mage
vi si bi l i ty mask (-maskfile and -maskdata). As usual , opti ons may be abbrevi ated to
any uni que i ni ti al substri ng of the ful l opti on name (see exampl e bel ow).
The use of these opti ons shoul d be fai rl y obvi ous, but i t i s expanded upon bel ow. See
the Tk hel p system for more detai l on bitmap. A photo bi tmap shoul d be used
wherever mul ti pl e col ors are necessary; mul ti pl e col ori ng usual l y woul d be decorati ve
rather than functi onal , except i n appl i cati ons more compl ex than usual l y woul d be
i mpl emented i n Tk.
image delete
Thi s removes the named image(s) from the runni ng appl i cati on, so that the name(s)
no l onger can be used i n commands. I t al ways returns an empty stri ng. Preexi sti ng
di spl ayed i nstances of a del eted i mage sti l l wi l l remai n vi si bl e. Syntax:
image delete name1 ?name2 ...?;
image names
Anal ogous to array names i n generi c TcL, thi s command returns a current l i st of
decl ared image names. Syntax:
image names;
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
56
X11 bi tmap (xbm) management
The xbm format may be used i n Tk ei ther stored i n a TcL stri ng i n memory, or, more
usual l y, stored i n a di sc fi l e. I t i s a pure ASCI I format, al l i n pri ntabl e characters. The
l anguage i s the C programmi ng l anguage.
As al ready menti oned, an xbm image object consi sts of three parts: Two macro
defi nes, one for i mage wi dth, and the other for i mage hei ght; and, one array of char.
The char array i s what descri bes the pattern di spl ayed i n the i mage.
The wi dth and hei ght are i n pi xel s. Each pi xel i n an xbm i mage i s monochrome and
may be ei ther on or off. An on pi xel i s di spl ayed i n the foreground (-fo) col or; an off
pi xel i s di spl ayed i n the background (-ba) col or. Thus, a bi tmap i mage requi res just
one bi t of i nformati on per pi xel . A bi t wi th val ue '1' i s on; wi th val ue '0', i t i s off.
A typi cal use of the xbm format i n Li nux i s for Tk i cons. Such an i con mi ght be 64 x
64 pi xel s. Thi s means 64
2
(=2
6 2 x
= 2
12
), or 4096, bi ts are requi red i n the di spl ay. The
xbm char array i s i n bytes; each byte bei ng 8 (=2
3
) bi ts wi de, thi s means that the i con
just descri bed woul d requi re an array of 2
12
/2
3
= 2
12
-
3
= 2
9
= 512 bytes. Each byte, as
usual i n C, i s expressed as two hex nybbl es i n the form, 0xhh, where 0x i n C i ntroduces
a constant i n hexadeci mal base, and each h represents a nybbl e wi th val ue 0 - f.
Note that i n thi s format, the l east si gni fi cant bi t i n a byte wi l l be di spl ayed to the l eft
of the more si gni fi cant bi ts. Thus, i f 0xe0 represented a pattern al l i n one row i n the
i mage, the on/off di spl ayed bi t-pattern woul d be, 00000111.
An exampl e of an xbm fi l e for a smal l , square i mage named xIcon i s as fol l ows:
#define xIcon_width 64
#define xIcon_height 64
static char xIcon_bits[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
... (omitted) ..., 0xff, 0xff,
};
The fi nal comma i n the byte array i s opti onal i n C.
The wi dth and hei ght macro defines, whi ch speci fy the rectangul ar shape of the
i mage, have been gi ven uni que names whi ch associ ate them wi th the decl ared name of
the char array. The char array i ni ti al i zati on stri ng woul d be exactl y 512 bytes (not al l
shown above), exactl y the ri ght val ue for the gi ven wi dth and hei ght.
Looki ng at the di spl ayed pattern, the fi rst byte i s 0xff, whi ch means that al l the fi rst
ei ght pi xel s i n the i mage (upper l eft corner to 8th pi xel i n top row) wi l l be i n the
foreground col or. The 0xe0 byte expands to a bi nary pattern of 1110_0000 and thus
i ncl udes three foreground-col or pi xel s and fi ve background-col or pi xel s. Th actual
geometri cal posi ti ons represented are l eft-to-ri ght, LSB to MSB; so, 0xe0 represents fi ve
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
57
background bi ts to the l eft of three foreground bi ts, assumi ng the pi xel s were al l i n one
i mage row.
I f stored i n a fi l e named xIcon.xbm, the above pattern coul d be decl ared wi th the
name xImage thi s way:
image create bitmap xImage -file xIcon.xbm -ba red -fo yellow;
Of course, al though vi si bl y perhaps an icon, the bitmap created woul d not be a Tk
icon functi onal l y but rather a generi c two-col or i mage. As the reader mi ght recal l , the
wm iconbitmap command must be used to create an icon; al so, an xbm icon can not be
assi gned col ors.
Havi ng decl ared an i mage as above, here i s an exampl e of how to di spl ay i t:
proc doBitmap { Win Fname } \
{
wm title . "Bitmap from $Fname";
image create bitmap xImage$Win -file $Fname -ba red -fo yellow;
pack [label .$Win -image xImage$Win -width 300 -bg white];
}
doBitmap x xIcon.xbm
The resul t, for the actual i con i mage i n the xbm fi l e exampl e above,
The wi dth of 300 was to make the enti re banner stri ng vi si bl e wi thout i nteracti ve
stretchi ng of the wi ndow.
The Tk pal ette
As menti oned i n the context of el ementary GUI objects, ei ther the predefi ned Tk 256-
col or pal ette, or any X RGB col or descri pti on, may be used wi th tk_setPalette to
change the Tk wi dget col ori ng styl e. Assi gni ng one or more col ors expl i ci tl y means that
Tk wi l l use i ts own al gori thms to change the col ors of other, unspeci fi ed GUI objects i n
some reasonabl y consi stent, usabl e way; such objects i ncl ude wi ndow decorati ons and
i cons.
We have seen how i con (i mage) col ors were chosen by Tk from the runni ng OS's
wi ndow col or scheme. Thi s was si mpl y because i con col ors have to come from
somewhere; when the i mage i s xbm, the col ors can't be speci fi ed by wm iconbitmap; so,
they were adopted from the overal l col or styl e of the runni ng wi ndowi ng system,
automati cal l y, by Tk.
But, i mages other than i cons, namel y bitmap or photo i mages, i ncl ude i nherent
col ori ng; thi s al l ows such i mages to express somethi ng more or l ess unrel ated to GUI
functi onal i ty -- perhaps somethi ng i ndi vi dual l y decorati ve. These i mages must not be
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
58
al tered merel y because of the GUI styl e. Therefore, except for i cons, whi ch have no
other col or mechani sm, tk_setPalette can not al ter i mage col ors; tk_setPalette i s
for GUI wi dget col ori ng (i ncl udi ng wi ndow decorati ons) onl y.
Some tk_setPalette Examples
When tk_setPalette i s cal l ed wi th just one argument, a col or name, i t i s used to
determi ne the background col or; other col ors are automati c. More than one col or may
be changed by provi di ng names of the GUI features pai red wi th the col ors assi gned. I f
there i s more than one argument to tk_setPalette, there must be an even number of
them, and the background col or must be speci fi ed among them.
To see how tk_setPalette works, here i s si mpl e scri pt whi ch creates a compound
text-bi tmap label, wi th nonfuncti onal but operabl e buttons, i ni ti al l y i n bl ack and
whi te. I n thi s exampl e, the text char 'Z' was sel ected by sweepi ng the text cursor from
ri ght to l eft; the mouse cursor then was moved so that the l eft mouse button coul d be
used to hol d wi dget button B1 depressed:
proc doColors { Win Fname } \
{
wm title . "C00";
image create bitmap bm$Win -file $Fname;
text .x$Win -height 1 -width 4 -font {-size 20};
.x$Win insert end "XYZ";
#
button .bt1$Win -text "B1" -default normal;
button .bt2$Win -text "B2" -default active;
button .bt3$Win -text "B3" -default disabled;
#
pack [label .$Win -image bm$Win -width 100] -side left;
pack .x$Win .bt1$Win .bt2$Win .bt3$Win -side left;
}
tk_setPalette white;
doColors x xIcon.xbm
Here i s the captured
i mage, i n Wi ndows:
These screen captures are
somewhat system-
dependent. None of them
i ncl ude the mouse cursor
i mage, and they catch the
text cursor onl y i f run
whi l e i t i s bl i nked on.
The screen captures bel ow don't al ways show the B1 depressi on, but i t al ways i s
vi si bl e i nteracti vel y.
The tabl e fol l owi ng shows the resul ts of assi gni ng a shade of bl ue, #5050ff, al ong
wi th a whi te background, to vari ous database names i n the proc above. The fi gures
were captured on a Wi ndows machi ne.
For exampl e, the fi rst wi ndow i n the tabl e, bannered "C01", was col ored by repl aci ng
"tk_setPalette white" wi th the command,
tk_setPalette background white foreground #5050ff;
Noti ce that the correct syntax omi ts the hyphen ('-') before each opti on name.
Named col ors al so woul d work as opti on val ues. The order of the two opti ons makes no
di fference.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
59
Onl y the rel evant arguments to thi s command are shown i n the tabl e.
tk_setPalette Arguments Image Displayed
background white foreground #5050ff;
background white selectColor #5050ff;
background white selectForeground #5050ff;
background white selectBackground #5050ff;
background white highlightColor #5050ff;
background white highlightBackground #5050ff;
background white activeForeground #5050ff;
background white activeBackground #5050ff;
background white disabledForeground #5050ff;
background white insertBackground #5050ff;
background white troughColor #5050ff;
Thi s exampl e i s meant to hel p cl ari fy the meani ng of the vari ous database names
al l owed i n a tk_setPalette i nvocati on. However, as can be seen i n the wi dget
di spl ays, tk_setPalette had no vi si bl e effect when col ori zi ng the selectColor,
highlightBackground, disabledForeground, or troughColor. The effect of
varyi ng wi dget background or foreground col ors i s not shown; automati c col ori zati on i n
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
60
general wi l l depend on wi dget col ors whi ch are speci fi ed, on wi ndow-system styl e (Li nux
theme), and on the Tk port to a parti cul ar OS.
As expected, the bitmap i mages on the l eft of each of the label wi dgets i n the tabl e
were not modi fi ed by tk_setPalette.
Command-speci fi c bi tmaps
I n regard to a command or wi dget opti on, the word bi tmap i s used i n Tk to refer to
two di fferent thi ngs:
(a) An image bitmap may be an arbi trary graphi c i n xbm or some other format,
drawn by someone i ndi vi dual l y and resi di ng i n a di sc fi l e or i n a l oadabl e TcL
stri ng. The name of the wi dget opti on referenci ng such an object, when such an
opti on i s avai l abl e, usual l y i s -image.
(b) A bitmap bitmap may be one of a smal l number of predefi ned graphi cs whi ch
resi de i n the Tk l i brary suppl yi ng the command i n questi on. Thi s opti on al ways
i s named, -bitmap or -icon. The predefi ned graphi cs, for commands al l owi ng
them, are:
error A ci rcl e, stri cken out.
hourglass An hourgl ass graphi c.
info A capi tal I .
questhead Profi l e si l houette of a head wi th questi on mark for brai n.
question A questi on mark.
warning An excl amati on poi nt (often i n a tri angl e).
The graphi cs of the predefi ned bi tmaps are i l l ustrated i n the next secti on.
I n the next secti on, we shal l l ook at a few sel ected commands whi ch are i nvoked to
create wi dgets and whi ch opti onal l y are associ ated wi th bi tmaps i n the two di fferent
bi tmap ways. We shal l focus onl y on the bi tmap associ ati on, l eavi ng asi de other detai l s
of the commands.
In button
The predefi ned bi tmaps for the button wi dget al l are speci fi ed by the -bitmap
opti on. I f -text al so was gi ven, the -bitmap overri des i t and no text i s di spl ayed.
Both text and bi tmap may be di spl ayed by addi ng the -compound opti on.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
61
Here i s a si mpl e procedure to i l l ustrate al l the predefi ned bi tmaps:
proc buttonBitMap { Win } \
{
wm title . "Button Bitmaps";
pack [label .$Win -text "The button bitmaps: " -font {-size 14}] -side left;
#
foreach BitMap { warning error question questhead hourglass info } \
{button .bt$BitMap$Win -bitmap $BitMap -width 60 -height 40 \
-text "$BitMap" -compound top -default normal;
pack .bt$BitMap$Win -side left;
}
}
buttonBitMap x
The resul ti ng di spl ay (i n Wi ndows) i s:
A button al so may have an arbi trary i mage assi gned by the -image opti on. Thi s
takes precedence both over -text and -bitmap, unl ess a compound i s speci fi ed. A
compound button di spl ay wi th i mage, bi tmap, and text wi l l show onl y the i mage and the
text.
For exampl e,
proc buttonImage { Win } \
{
wm title . "Tk Button with 'warning'";
image create bitmap tkIcon -file "xIcon.xbm";
#
set BitMap warning;
button .bt$BitMap$Win -bitmap $BitMap -width 300 \
-height [expr 64 + 12 + 5] -text "$BitMap" \
-compound top -image tkIcon \
-bg white -fg blue -default normal;
pack .bt$BitMap$Win;
}
buttonImage x
In label
The predefi ned bi tmaps for label are i denti cal to those for button.
In tk_messageBox
An arbi trary i mage can not be associ ated wi th a tk_messageBox wi dget. There i s a
bi tmap opti on, -icon, whi ch accepts any of four of the possi bl e predefi ned bi tmaps:
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
62
warning, error, question, and info. I f no -icon opti on i s present, the predefi ned info
bi tmap wi l l be di spl ayed by defaul t. I t i s not possi bl e to create a tk_messageBox
wi ndow wi th no i con.
For exampl e,
proc msgBoxIcon { Win } \
{
# Suppress appearance of the inert main window:
wm withdraw .;
#
tk_messageBox -title "Message Box with Warning" \
-message {Here is a warning message to display} \
-parent . -icon warning -type ok;
}
msgBoxIcon x
exit
In tk_dialog
The predefi ned bi tmap opti ons are the same as for tk_messageBox.
Lab 3: Utility Dialog Widget Templates
Change to your Lab03 di rectory.
I n these exerci ses, we shal l expl ore a few of the most useful speci al i zed Tk wi dgets.
I n fol l owi ng the i nstructi ons, pl ease be sure to have the Tk hel p system avai l abl e (man
command); thi s i s how you wi l l know the syntax and features of each wi dget.
The exerci ses i n thi s l ab are cumul ati ve. Be sure to save al l your work after
compl eti ng each Step. Name your procs i n each Step di fferentl y; thi s wi l l make i t easy
to use them together i n l ater Steps.
tk_messageBox
Step 1. Message boxes to warn of fi l e errors.
Explanation. A message box, whether i n X, Wi ndows API or Tk, i s an easy-to-
program, standal one graphi c wi th l i mi ted functi onal i ty. The buttons can show onl y
certai n stereotyped text choi ces. A tk_messageBox has no decl ared wi ndow pathname;
therefore, i t can not be addressed or control l ed by anythi ng i n the GUI , other than i tsel f.
A tk_messageBox i s nonmodal , whi ch i s to say, i t does not di sabl e other acti ons by
the appl i cati on unti l i t i s di smi ssed.
The si mpl i ci ty and l ack of GUI context makes a tk_messageBox i deal for handl i ng
errors, even errors whi ch perhaps mi ght di sabl e or crash the whol e GUI .
Lab Task. Wri te a TcL scri pt that copi es a fi l e. Cal l i t i n a shel l scri pt named
CopyFile; the shel l scri pt shoul d accept two i nput parameters, the source and
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
63
desti nati on fi l e names, and shoul d pass them unveri fi ed as i nput arguments to the TcL
scri pt.
The TcL scri pt shoul d check to see whether the source fi l e exi sts; i f not, i t shoul d
present a message box i nformi ng the user of thi s; the scri pt shoul d exi t after the user
has acknowl edged the message.
Assumi ng a good source fi l e, the TcL scri pt shoul d check to determi ne whether the
desti nati on fi l e exi sts or not; i f not, the copy shoul d be performed si l entl y, endi ng the
scri pt. I f the desti nati on fi l e exi sts, the TcL scri pt shoul d not copy anythi ng; i nstead, i t
present an error message box i nformi ng the user of the probl em.
tk_dialog
Step 2. A di al og to i nspect envi ronment vari abl es.
Explanation. There are three mai n di fferences between a tk_dialog and a
tk_messageBox:
• The tk_dialog buttons are al l owed to have arbi tary names.
• A tk_dialog has a wi ndow path, maki ng i t possi bl e to i ntegrate a tk_dialog
i nto a GUI di spl ay.
• A tk_dialog i s a modal wi ndow; i t prevents al l other appl i cati on acti vi ty unti l
i t has been di smi ssed.
Lab Task. Wri te a TcL scri pt whi ch creates a label wi ndow whi ch says, "Make a
Choi ce". The label shoul d contai n two buttons.
One button, whi ch i s named "Exi t", i mmedi atel y termi nates the scri pt.
The second button i s named "Check Env". When the "Check Env" button i s pi cked,
the scri pt i mmedi atel y shoul d read the TcL $env array and create vari abl es to save the
envi ronment val ues for the fol l owi ng names: TEMP, PWD, USER, HOME, and PATH. I f any
one i s not defi ned or nul l , the val ue "(not set)" shoul d be saved.
The tk_dialog then shoul d appear wi th si x buttons: "TEMP", "PWD", "USER",
"HOME", "PATH", and "Done". When the user pi cks one of the envi ronment buttons,
the name and saved val ue shoul d be presented i n a new text wi ndow packed i nto the
ori gi nal label wi ndow. Use a text hei ght of 1 and wi dth of about 10 - 20. Any
number of these new text wi ndows i s al l owed.
Because the tk_dialog wi ndow i s modal , i t prevents scrol l i ng or copy-and-paste of
the text wi ndow contents. To enabl e these operati ons, when the "Done" button i s
pi cked, the tk_dialog wi ndow shoul d be destroyed, l eavi ng i ntact the ori gi nal label
wi ndow and al l i ts new text appendages.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
64
tk_chooseColor
Step 3. A di al og to choose a col or.
Explanation. We present thi s fai rl y si mpl e di al og onl y as an i ntroducti on to the
more essenti al fi l e-accessi ng di al ogs. Of course, i n certai n appl i cati ons such as drawi ng
programs, GUI -medi ated col or choi ce may be more i mportant than fi l e I /O.
Lab Task. Wri te a TcL scri pt whi ch presents a label wi ndow wi th two button
choi ces, "Choose a Col or" and "Exi t". The scri pt shoul d termi nate when "Exi t" i s pi cked.
On "Choose a Col or", the scri pt shoul d present the tk_chooseColor di al og. The user's
col or choi ce then shoul d be reported as a text stri ng i n a message box.
tk_chooseDirectory
Step 4. A di al og to choose a fi l esystem di rectory path.
Explanation. Thi s di al og presents a l ocal runti me di rectory tree and al l ows the
user to choose a di rectory.
The di rectory di spl ay may be mani pul ated by the user i n the usual GUI way common
i n Li nux or Wi ndows. When the user makes a choi ce, the absol ute path to the chosen
di rectory i s returned, and the di al og i s termi nated. The di al og wi l l be i ni ti ated i n the
i nvocati on current worki ng di rectory, unl ess a -initialdir opti on i s used to modi fy
thi s.
Lab Task. Modi fy your scri pt from Step 3 so that i t uses tk_chooseDirectory
i nstead of tk_chooseColor. The i ni ti al di rectory shoul d be /usr.
Your scri pt shoul d open a new text wi dget wi ndow and l i st the contents of the
chosen di rectory i n i t.
Optional Steps. Compl ete these as ti me permi ts:
tk_getOpenFile
Optional Step 5. A di al og to open a fi l e.
Explanation. Thi s di al og usual l y woul d be cal l ed i n a GUI from a [File
Open...] menu or tool bar choi ce. The prompt i s to choose a (preexi sti ng) fi l e name to
open i t; however, the di al og merel y returns the absol ute path to the fi l e chosen and
l eaves i t to the control l i ng scri pt to process the pathname. The user may type i n a
name or use a mouse pi ck; however, the di al og wi l l not return i f the fi l e named does not
exi st.
Lab Task. Modi fy your scri pt from Step 4 so that tk_getOpenFile i s the di al og
cal l ed. The scri pt shoul d read the fi l e and di spl ay the fi l e contents i n vim. Be sure to
handl e errors i n whi ch the fi l e can't be read.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
65
tk_getSaveFile
Optional Step 6. A di al og to save a copy of a fi l e.
Explanation. The tk_getSaveFile di al og i s categori zed i n the Tk hel p system as
cl osel y rel ated to tk_getOpenFile. I t normal l y woul d be cal l ed from a GUI [File
Save...] menu or tool bar choi ce. Thi s di al og al so returns the absol ute pathname of
the fi l e chosen. However, i f the save name i s that of a preexi sti ng fi l e, thi s di al og
prompts to overwri te and wi l l return i f the user approves the save.
Lab Task. Modi fy your scri pt from Step 5 so that, after usi ng tk_getOpenFile to
obtai n a fi l e name, the scri pt then i nvokes tk_getSaveFile to prompt to save the fi l e
under a new name. The scri pt shoul d refuse to wri te out the fi l e to i ts ori gi nal name; i f
a new name i s gi ven, i t shoul d copy the chosen fi l e to the new (path)name.
Suggesti on: Use one proc to run tk_getOpenFile and another one to run
tk_getSaveFile.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
66
Multiple Top-Level Windows
We so far have assumed an appl i cati on based on a si ngl e wi ndow, wi th wi dgets whi ch
coul d be packed, gridded, or placed i n that wi ndow. We al so have used a few speci al
wi dgets, message boxes and di al ogs, whi ch created thei r own, i ndependent wi ndows.
There i s a Tk command for di stri buti ng appl i cati on functi onal i ty among several
wi ndows, no matter what the wi dget; thi s i s the toplevel command.
The basi c syntax si mpl y i s toplevel windowpath. Opti ons control l i ng appearance
and addi ti onal functi onal i ty may be found i n the Tk hel p system. Two of the many
i mportant opti ons are -menu and -takefocus. The -menu opti on al l ows a tool bar
menu to be attached to the upper frame of the toplevel wi ndow. The compl ex and
powerful menu wi dget i s very hel pful i n seri ous GUI devel opment. We shal l show rote
use of a menu i n the tk_popup presentati on, but our ti me i n the present Workshop i s
better spent on the basi cs; so we suggest that i f you are pl anni ng to devel op a GUI usi ng
Tk, you shoul d study and understand the menu wi dget more thoroughl y than ti me here
has al l owed.
To spawn off mul ti pl e i ndependent wi ndows i n a si ngl e scri pt, one assi gns each one to
i ts own top l evel wi ndow. For exampl e, here i s a way to use packer to present two
separate label wi ndows, each named a, i n one procedure:
proc twoToplevelLabels { Win } \
{
# Suppress the unused root window:
wm iconify .;
#
set t1 [toplevel .t1$Win];
label $t1.a -font {-family Times -size 18} \
-text "This is the initial label";
wm title $t1 "First label";
#
set t2 [toplevel .t2$Win];
label $t2.a -font {-family Times -size 18} \
-text "This is another label";
wm title $t2 "Second label";
#
pack $t1.a $t2.a;
}
twoToplevelLabels x
Appearance of the two i ndependent
label wi ndows, reposi ti oned
i nteracti vel y.
The two label wi ndows may be di smi ssed separatel y; or, the i coni fi ed root wi ndow
may be di smi ssed, destroyi ng both label wi ndows. I n thi s exampl e, i f the root wi ndow
had been suppressed wi th wm withdraw, i t woul d have remai ned as a resi dent process
i n an i naccessi bl e wi ndow and woul d have to be ki l l ed at the OS l evel ; or, i ts appl i cati on
woul d have to destroy i t by executi ng an exit command on termi nati on.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
67
Three More Widgets
We now have enough to do al most anythi ng wi th a Tk GUI . Just for a hi nt of the
functi onal i ty l eft undi scovered, we shal l present three addi ti onal wi dgets, the
labelframe, the listbox, and the tk_popup.
labelframe Wi dget
Thi s i s a very si mpl e wi dget. I t i s i denti cal to the frame wi dget we presented earl y i n
the Workshop (p. 34), but i t al l ows for a l abel i n addi ti on to the empty frame. Li ke the
pl ai n frame, i t i s useful as a way of combi ni ng other wi dgets i nto a compl ex di al og or
menu-dri ven GUI .
We shal l use a labelframe i n the next exampl e to show how to embed buttons and
an i mage i nto a compl ete, si mpl e GUI di al og.
I n thi s exampl e, the purpose of the GUI i s to al l ow the user easi l y to choose the base
footpri nt of a tabl e l amp. Thi s GUI woul d be part of some sort of product-orderi ng
system. The tk_dialog shown bel ow woul d return a val ue whi ch woul d be wri tten
i nto a fi l e or HTML database so i t coul d be used by another process i n that system. I n a
compl ete system, i nstead of exit, the labelframe woul d be repl aced by another
wi ndow -- or, a new scri pt woul d be exec'ed.
proc labelFrameButtons { Win Img } \
{wm title . {Labelframe with Buttons};
#
variable ImgL $Img;
namespace eval iSpace \
{ variable Img [image create bitmap Img \
-file "$::ImgL" -back {light yellow} -fore {dark blue}];
}
proc ${Win}Run { Win Choice } \
{tk_dialog .lf$Win {Choice Done} "You chose $Choice" {} 0 {Dismiss};
exit;
}
#
labelframe .lf$Win -labelanchor n \
-text "Choose the base footprint for your new lamp:" \
-font {-size 14} -fg {dark green} -bg {light yellow};
label .lf$Win.img -image $iSpace::Img;
button .lf$Win.b1 -text {Circle} -command "${Win}Run $Win Circle" \
-font {-weight bold} -bg white -activefore red -activeback green;
button .lf$Win.b2 -text {Square} -command "${Win}Run $Win Square" \
-font {-weight bold} -bg white -activefore red -activeback green;
button .lf$Win.b3 -text {Hexagon} -command "${Win}Run $Win Hexagon" \
-font {-weight bold} -bg white -activefore red -activeback green;
pack .lf$Win .lf$Win.img;
pack .lf$Win.b1 .lf$Win.b2 .lf$Win.b3 -side left -expand 1;
}
labelFrameButtons x LabelFrameButtons.xbm;
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
68
The di spl ay then proceeds as fol l ows:
Initial Display Depression of Button Final Display
As soon as the mouse button i s rel eased, the labelframe mai n wi ndow goes bl ank
and i nert, and the tk_dialog takes the focus modal l y. The exit command fol l owi ng
the tk_dialog termi nates the appl i cati on and destroys al l remai ni ng wi ndows
associ ated wi th i t.
Several other comments shoul d be made about the code above:
• The i mage representi ng the three shapes of the l amp bases was decl ared for
i l l ustrati ve purposes i n a namespace iSpace. I t was assi gned to a vari abl e $Img
i n that namespace so that i t coul d be addressed hi erarchi cal l y, i n the command,
label .lf$Win.img -image $iSpace::Img;
• The variable command, not the set command, was used to access the $Img
vari abl e. I n general , i n current versi ons of TcL, the set command does not work
predi ctabl y wherever namespaces are i nvol ved. When a vari abl e i s decl ared i n a
namespace, i ts name i n general i s vi si bl e to the variable command i n the
i mmedi atel y encl osi ng namespace. Thi s works somewhat the way global works
wi th set i n TcL i n the absence of namespaces.
• A l ocal proc i s decl ared to handl e the button response and i s named after the
generated wi ndow name. Thi s mangl ed nami ng conventi on i s much si mpl er and
safer than woul d be the use of another namespace.
• The button -command opti on i s a TcL l i st; when quoti ng i n the command mi ght
cause compl i cati ons, list coul d be cal l ed i nl i ne; for exampl e,
button ... -command [list ${Win}Run $Win Circle] \ ...
• The opti ons to the button commands are meant to be i l l ustrati ve. I mages coul d
have been assi gned to the buttons, but thi s woul d have di stracted from the use of
the labelframe.
• The labelframe wi ndow i s used as a hi erarchi cal root of the button wi ndows.
Thi s way, when the labelframe i s destroyed (by the tk_dialog), the buttons
are destroyed, too; thi s i s a good reason to use a frame or labelframe wi dget.
• The tk_dialog cal l ed by a button of course bl ocks further executi on unti l i t has
been di smi ssed. Because i t i s assi gned the same wi ndow path as was the
labelframe, i t destroys the labelframe on the fi rst button pi ck. Thi s i s to
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
69
prevent further choi ces, but i t l eaves the now-i nert mai n wi ndow whi ch once hel d
the labelframe.
Destructi on of the labelframe al so l eaves the (stati c text) mai n wi ndow ti tl e the
same. When the tk_dialog returns, i t automati cal l y destroys i tsel f, too,
al l owi ng the wi ndow path to be reused. Thi s means that a subsequent pack, even
i n some sort of l oop, coul d be i nvoked after the tk_dialog to repopul ate the mai n
wi ndow, i f desi red. The fi rst new pack coul d resi ze the mai n wi ndow compl etel y,
but the ti tl e woul d remai n the same.
listbox Wi dget
I n the remai ni ng exposi ti on, we shal l shi ft emphasi s from the packer to the gridder,
because our goal i s control of several GUI wi dgets i n two di mensi ons.
A listbox wi dget basi cal l y i s a text wi dget i n whi ch each l i ne of text represents an
i tem whi ch may be sel ected. The listbox text wi ndow may or may not be bi g enough
to di spl ay the enti re wi dth of a l i ne of text, or to di spl ay al l the l i nes i n the i tem l i st.
The listbox contents are scrol l ed automati cal l y when the mouse cursor i s swept.
Thi s means that any number, and l i ne-l ength, of i tems useful l y can be processed i n a
listbox text area of any reasonabl e si ze. I t i s possi bl e to add scrollbar wi dgets to a
listbox to make scrol l i ng more conveni ent, but there i s some communi cati on overhead,
and we shal l ski p thi s topi c i n the i nterest of ti me.
One l i ne of text (one i tem) may be sel ected; or, opti onal l y, several may be sel ected by
the usual mouse mani pul ati ons too obvi ous to descri be here.
After a listbox has been created, i t may be executed i n the scri pt wi th any of
several command opti ons for access to the i tems di spl ayed. For thi s access, an i tem may
be addressed by i ts i nteger i ndex offset, the fi rst i tem bei ng gi ven the i ndex 0. The l ast
i tem may be addressed numeri cal l y or as end.
Al ternati vel y, the scri pt may address an i tem by i ts pi xel offset i n the listbox
wi ndow, usi ng the syntax, @x_offset,y_offset. The i tem coveri ng the desi gnated pi xel
wi l l be sel ected; or, i f none covers that pi xel , the cl osest i tem wi l l be substi tuted. More
than one i tem may be sel ected at a ti me, as wi l l be descri bed bel ow.
The listbox i tems are read-onl y: They can not be modi fi ed by the user i nteracti vel y,
al though the wi dget scri pt i tsel f can read or wri te arbi trari l y i n the di spl ayed l i st.
There i s a speci al vi rtual event, <<ListboxSelect>>, whi ch i s generated whenever
the listbox sel ecti on changes. Thi s event probabl y i s the easi est one to use when
bindi ng to a command to process the i tem(s) sel ected.
Gri ded listbox Example
To i l l ustrate how to i ncl ude a listbox i n a GUI , we can use i t to di spl ay al l fi l es one
l evel down i n the Workshop home di rectory. Looki ng forward to our next l ab sessi on,
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
70
we use the gridder i n the next exampl e i nstead of the packer for better control of the
GUI l ayout.
We al so show the effect si mpl y of gridi ng the wi ndows versus gridi ng them i n a
frame wi dget. The frame wi dget i n thi s exampl e gi ves us control over the background
wi ndow col or.
Here i s an i nert l i ttl e GUI wi thout a frame (the "D:/~" i s the user's $HOME i n
Wi ndows) :
proc fileListBox { Win Dir } \
{wm title . {Listbox with Filenames};
#
set Flist [glob -nocomplain -tails -dir $Dir */*];
#
label .lDir$Win -text "$Dir" -wraplength {20 c} -bg grey90;
label .lFile$Win -text "$Flist" -wraplength { 8 c} -bg cornsilk;
listbox .lBox$Win -width 15 -height 6;
#
foreach f "$Flist" { .lBox$Win insert end $f; };
#
grid configure .lDir$Win -row 1 -columnspan 3;
grid configure .lFile$Win -row 2 -column 1;
grid configure .lBox$Win -row 2 -column 2;
}
fileListBox x d:/~;
The resul t of the unframed fileListBox x d:/~ i nvocati on. The
defaul t background col or for thi s Wi ndows exampl e i s a bei ge.
Noti ce the use of the -wraplength uni t: 'c' means centi meters.
We are cal l i ng a TcL i terator and usi ng the insert opti on to bui l d up the l i st to be
di spl ayed. The TcL list command al so coul d be used, but a listbox requi res a NL to
termi nate each i tem, so we woul d have to l oop over the glob stri ng, or maybe cal l
regsub, to i nsert NL's, anyway. Thus, the code shown carri es no speci al runti me
performance penal ty.
Thi s exampl e demonstrates onl y the creati on and di spl ay of a Tk listbox; the
listbox i tsel f i s not functi onal , except for i ts bui l ti n scrol l i ng and sel ecti on features.
Sweepi ng the cursor i n the listbox causes i t to scrol l i ts contents, i f any of them are
not vi si bl e.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
71
Here i s the same GUI , but framed:
proc fileListBox { Win Dir } \
{wm title . {Listbox with Filenames};
set Flist [glob -nocomplain -tails -dir $Dir */*];
frame .f$Win -background {light goldenrod};
#
label .f$Win.lDir$Win -text "$Dir" -wraplength {20 c} -bg grey90;
label .f$Win.lFile$Win -text "$Flist" -wraplength { 8 c} -bg cornsilk;
listbox .f$Win.lBox$Win -width 15 -height 6;
foreach f "$Flist" { .f$Win.lBox$Win insert end $f; };
#
grid configure .f$Win -row 1 -columnspan 3;
grid configure .f$Win.lDir$Win -row 1 -columnspan 3;
grid configure .f$Win.lFile$Win -row 2 -column 1;
grid configure .f$Win.lBox$Win -row 2 -column 2;
}
fileListBox x d:/~;
The resul t of the framed fileListBox x d:/~ i nvocati on.
The listbox i n thi s exampl e i s nonfuncti onal , except for permi tti ng scrol l i ng and Tk
sel ecti on (whi ch l atter does not i ncl ude copy to the cl i pboard). We coul d make i t
functi onal by bi ndi ng the listbox wi ndow sel ecti on to a command.
At thi s poi nt, havi ng seen the basi cs of a listbox, we shoul d present some of i ts most
useful opti ons. See the Tk hel p system for compl ete detai l s.
listbox Declaration Options
These are opti ons avai l abl e when the listbox wi dget i s decl ared (created). As
usual , they correspond to database name opti ons i n wi dget executi on.
-font. Thi s opti on has the usual effect of speci fyi ng attri butes of the font used i n
the listbox wi ndow.
-background; -foreground. These opti ons speci fy the background and
foreground col ors i n the listbox wi ndow.
-height; -width. These i nteger opti ons speci fy the hei ght and wi dth of the
listbox wi ndow. The hei ght i s i n l i nes; the wi dth i s i n characters.
-state. Thi s opti on determi nes whether the listbox wi l l respond or not to the
user. Val ues are disabled or (the defaul t) normal.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
72
-listvariable. The listbox i tems may be assi gned to the wi ndow, as i n the
precedi ng exampl e, or they may be assi gned to the vari abl e named i n thi s
opti on. I f thi s opti on i s used, the listbox contents become dynami cal l y
l i nked to the vari abl e. Whenever the vari abl e i s modi fi ed, the listbox
di spl ay i mmedi atel y changes accordi ngl y. We saw the same effect when we
used the -textvariable opti on to a label wi dget.
-selectmode. Thi s opti on determi nes whether exactl y one i tem at a ti me may be
sel ected (browse val ue) or whether more than one i tem may be sel ected
(extended val ue) by the usual mouse mani pul ati ons. The defaul t i s browse.
See the Tk hel p for other val ues of thi s opti on.
listbox Command Options:
I n addi ti on to the above opti ons (i f i n database name format), here are three of the
speci al opti ons avai l abl e when the listbox (wi ndow path) i s executed:
curselection. Thi s returns a l i st of i ndi ces of the one or more listbox i tems
currentl y sel ected. I t returns an empty stri ng i f none i s sel ected.
insert. Thi s i nserts one or more new i tems i nto the listbox i tem l i st, gi ven an
i ndex of i nserti on. We used thi s command i n the precedi ng exampl e to create
the listbox contents.
get. Gi ven an i ndex i nto the listbox i tem l i st, thi s returns the i tem stri ng. I f
an i ndex range i s gi ven, a l i st of al l i tem stri ngs i n that range i s returned.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
73
Gri ded listbox GUI Example
Here i s an exampl e of a si mpl e, compl ete listbox-based GUI :
proc fileChooseLB { W Dir } \
{wm title . {Listbox to Choose a Filename};
#
set Flist [glob -nocomplain -tails -dir $Dir */*];
#
frame .f$W -background {light goldenrod};
#
set HelpVar {Select any file in the list box on };
append HelpVar {the right. Your choice will be };
append HelpVar {confirmed; then the choice value };
append HelpVar {will be passed to an independent };
append HelpVar {window to simulate useful activity.};
#
label .f$W.lDir$W -text "$Dir" -wraplength {20 c} -bg grey90;
label .f$W.lMsg$W -text $HelpVar -wraplength { 8 c} -bg cornsilk;
listbox .f$W.lBox$W -width 15 -height 6;
#
foreach f "$Flist" { .f$W.lBox$W insert end $f; };
#
grid configure .f$W -row 1 -columnspan 3;
grid configure .f$W.lDir$W -row 1 -columnspan 3 -sticky {e w};
grid configure .f$W.lMsg$W -row 2 -column 1;
grid configure .f$W.lBox$W -row 2 -column 2;
#
proc fileChooseLBsel { W } \
{ global TransferVar;
set Sel [.f$W.lBox$W curselection];
if {$Sel ne {} } \
{set Got [.f$W.lBox$W get $Sel];
set TransferVar $Got;
tk_dialog .f$W.d {Acknowledgement of Selection} \
"You chose $Got" {} 0 {Dismiss};
doIt;
}
}
#
bind .f$W.lBox$W <<ListboxSelect>> "fileChooseLBsel $W;";
}
proc doIt {} \
{ global TransferVar;
tk_messageBox -icon info -type ok -title "New Application Called" \
-message "Now processing $TransferVar";
};
fileChooseLB x D:/~/Lab01;
There i s a copy of thi s i n fileChooseLB.tcl i n your Lab04 di rectory.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
74
The operati on of thi s l i ttl e GUI proceeds as fol l ows:
Initial Display Scroll to See Listed Filenames
Effect of Selection Continuation after Dismissal
A few observati ons:
• The top graphi c on the ri ght shows the effect of scrol l i ng the listbox contents
hori zontal l y (mi ddl e mouse button) before maki ng a sel ecti on. The l i st al so coul d
be scrol l ed up or down by hol di ng down the mi ddl e button whi l e sweepi ng the
mouse cursor up or down. Thi s listbox wi ndow purposel y was made smal l so as
to demonstrate scrol l i ng.
• The pl ai n frame bei ng used here i s made to emul ate a labelframe by use of the
gridder -sticky opti on shown, whi ch stretches the di rectory pathname stri ng
across the whol e hori zontal extent of the GUI wi ndow.
• The sel ecti on-processi ng proc i s decl ared as fileChooseLBsel i nsi de i ts GUI
creati on proc. The name i n effect i s i nheri ted i n mangl ed form. Thi s object-
ori ented approach ai ds i n coordi nati ng the graphi cs wi th the processi ng whi l e
recogni zi ng that proc names have gl obal scope.
• The i ndependent proc named doIt() i s meant to represent any arbi trary proc
currentl y accessi bl e i n thi s wish scri pt. For thi s reason, i t i s decl ared outsi de the
GUI -creati on proc. I n general , a GUI wi l l have to communi cate wi th GUI -
i ndependent appl i cati ons; the global used i n thi s exampl e i s one way to effect
thi s communi cati on. Of course, to avoi d seri ous confusi on because of name
confl i cts, global vari abl es shoul d be used spari ngl y i n any TcL program.
• Noti ce that wi ndow pathnames, l i ke proc names, are gl obal l y accessi bl e. Thi s i s
why they are referred to as pathnames, l i ke the pathnames i n a fi l i ng system.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
75
tk_popup Wi dget
Thi s wi l l be the most compl i cated wi dget we study. I f you can manage a tk_popup,
you can handl e anythi ng i n Tk.
The tk_popup wi dget i s not a di al og but a menu. I t i s i ntended to be used onl y as
part of a l arger GUI desi gn and ordi nari l y woul d have no standal one uti l i ty. Unl i ke the
di al ogs we studi ed previ ousl y, the tk_popup expl i ci tl y i s deri ved from another wi dget,
the menu. Thus, mani pul ati on of a tk_popup requi res coordi nati on of a menu wi th
other wi ndows i n the popup context.
Layout of a GUI with a Popup Menu
To show how to i mpl ement a popup menu, fi rst we shoul d l ay out a GUI . Let's
devi ate from our previ ous listbox exampl e and start wi th a GUI whi ch just says,
"Make a choi ce:" and presents three buttons, two to do somethi ng and a thi rd to exi t.
We assume that thi s GUI wi l l present some text i nformati on, so we al so shal l reserve an
area bel ow the buttons for that. Here i s a reasonabl e i mpl ementati on of the l ayout. We
use the bell command as a pl ace-hol der:
wm title . {My Clever Popup};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
# Set up the main menu bar widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 14 -weight bold} -bg blue -fg yellow];
set B1 [button .b1Win -text {Choice 1} -font {-size 14} \
-bd 6 -bg green -command {bell;}];
set B2 [button .b2Win -text {Choice 2} -font {-size 14} \
-bd 6 -bg green -command {bell;}];
set Bexit [button .bExitWin -text {Exit} -font {-size 14} \
-bd 6 -bg red -command {exit;}];
set Ans [label .ansWin -bg cornsilk];
#
# Runtime:
grid $L $B1 $B2 $Bexit -row 1;
grid $Ans -row 2 -columnspan 4 -sticky {e w};
The resul t (i n Wi ndows):
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
76
I n the code above, we use wm geometry to speci fy a l ocati on on the screen. I n thi s
desi gn, we requi re that our popup menu appear near i ts i nvoki ng button; to do thi s, we
must have a l ocati on for the button.
The rest of the code shoul d be fami l i ar by now. To proceed wi th the new thi ngs
i nvol ved i n popups, l et's start wi th some detai l on the tk_popup command:
tk_popup Options
The opti ons are very si mpl e. The basi c syntax i s,
tk_popup menu_path x_location y_location
The x and y val ues are screen coordi nates i n pi xel s. To keep the l ocati on of a popup
menu associ ated wi th the wi ndow i n whi ch i t was i nvoked, we shal l provi de nearby
screen coordi nate val ues for both.
The val ue of menu_path must be the path of a menu wi dget wi ndow. Thi s i s where
the compl exi ty begi ns. We al ways must provi de a menu before creati ng a tk_popup.
And, gl anci ng at the Tk hel p, the menu wi dget i s about as compl i cated as they get!
menu Widget Complications
Because each command i n a menu di spl ay may requi re a wi ndow path of i ts own, a
popup menu i n general wi l l be created i n the context of a wi ndow hi erarchy.
I n vi ew of the l i kel i hood that our popup menu may entai l possi bl y several l ayers of
subordi nate wi ndows, we choose to rei terate here the systemati c wi ndow-nami ng
conventi on we have been usi ng: Any wi ndow name passed to a proc wi l l be passed
wi thout a l eadi ng '.'; the proc al ways wi l l suppl y thi s '.'.
A menu, unl i ke a tk_dialog, does not destroy and repl ace a preexi sti ng wi ndow of
the same name. Therefore, to ensure that we can (re)create a menu each ti me we pi ck
i ts button, we must provi de for destroyi ng any wi ndow of the menu path name every
ti me we pop i t up.
Here i s a l i st of the menu command opti ons whi ch we shal l use. See the Tk hel p
system for the many others:
menu declaration options:
-tearoff. Bool ean. 1 creates a dotted tear-off l i ne near the top of the menu.
-disabledforeground. Defi nes the foreground col or of a di sabl ed i tem.
menu execution options:
add command
opti ons to the menu add command command:
-command. Gi ves the command to be binded to the menu i tem.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
77
-label. Defi nes the text appeari ng on the menu i tem.
-background. Defi nes the background col or of an i tem (i f not di sabl ed).
-foreground. Defi nes the foreground col or of an i tem (i f not di sabl ed).
-state. Ei ther normal, active, or disabled.
There i s no expl i ci t provi si on for enti tl i ng a menu, so we shal l use the text i n a
disabled i tem to gi ve our menues thei r ti tl es.
Functional Prototype for a GUI with Popups
Wi th al l thi s understood, l et's proceed from the nonfuncti onal l ayout of our exampl e to
one whi ch actual l y does somethi ng. We expand the precedi ng code by deci di ng to have
the two buttons control popup menues, one for accessi ng the fi l i ng system, and the other
for accessi ng the TcL envi ronment.
We'l l see whether we can get by wi thout a wi ndow hi erarchy, by just usi ng and
reusi ng what was our $Ans path. Our system al l ows onl y one menu at a ti me, so thi s
shoul d work.
Our l ayout becomes thi s:
wm title . {My Clever Popup};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
# Set up the main menu bar widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 14 -weight bold} -bg blue -fg yellow];
set B1 [button .b1Win -text {Access Files} -font {-size 14} \
-bd 6 -bg green -command {doPopFil ansWin;}];
set B2 [button .b2Win -text {Access Environment} -font {-size 14} \
-bd 6 -bg pink -command {doPopEnv ansWin;}];
set Bexit [button .bExitWin -text {Exit} -font {-size 14} \
-bd 6 -bg red -command {exit;}];
set Ans [label .ansWin -bg cornsilk]; # Now just a placeholder.
#
# Runtime:
grid $L $B1 $B2 $Bexit -row 1;
There i s no grid command for the second row of the mai n menu, because the label
previ ousl y di spl ayed there has become a pl acehol der wi ndow (.ansWin) to be taken over
by any popup menu proc whi ch i s run by a button pi ck.
The prototype mai n wi ndow now appears l i ke thi s:
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
78
Above the mai n menu defi ni ti on, we shal l add code for the two popup menu procs:
proc doPopFil {Win} \
{if { [winfo exists .$Win] } { destroy .$Win; }
set m [menu .$Win -tearoff 0 -disabledforeground black];
$m add command -label {Filesystem Access} -back green -state disabled;
$m add command -command "doDirList $Win" -label {List Directory Contents...};
$m add command -command "doFileOpen $Win" -label {Open a File...};
tk_popup .$Win 200 220;
bind .$Win <1> "tk_popup .$Win 200 220";
}
proc doPopEnv {Win} \
{if { [winfo exists .$Win] } { destroy .$Win; }
set m [menu .$Win -tearoff 0 -disabledforeground black];
$m add command -label {Environment Access} -back pink -state disabled;
$m add command -command "doEnvList $Win" -label {List Selected Variables...};
$m add command -command "doEnvMod $Win" -label {Modify the Environment...};
tk_popup .$Win 200 220;
bind .$Win <1> "tk_popup .$Win 200 220";
}
Noti ce the bind to mouse button 1 ("<1>"; the l eft mouse button), and the screen
coordi nates of the popups.
At thi s poi nt, we may add four dummy, pl acehol der proc decl arati ons; these wi l l
provi de somethi ng functi onal for the popup menues to i nvoke:
proc doDirList {x} {tk_messageBox -message "doDirList(): Not implemented";}
proc doFileOpen {x} {tk_messageBox -message "doFileOpen(): Not implemented";}
proc doEnvList {x} {tk_messageBox -message "doEnvList(): Not implemented";}
proc doEnvMod {x} {tk_messageBox -message "doEnvMod(): Not implemented";}
Omi tti ng fi gures for the tri vi al message boxes coded above, wi th the mouse cursor
hi ghl i ghti ng a popup i tem, the resul ti ng di spl ay i s somethi ng l i ke thi s:
The "Access Fi l es" popup:
The "Access Envi ronment" popup:
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
79
A Complete GUI with a Popup Menu
I t i sn't very i nstructi ve to show the i mpl ementati on of two essenti al l y i denti cal popup
menues, so we shal l change the desi gn at thi s poi nt and drop the "Access Envi ronment"
button and i ts menu.
The code for the revi sed mai n menu then i s changed tri vi al l y, and the di spl ay now
l ooks l i ke thi s:
The popup l ooks l i ke thi s, wi th the fi rst i tem sel ected, i n a di fferent Wi ndows styl e:
For si mpl i ci ty of thi s exampl e, and to show two menu choi ces, we al l ow the di rectory-
l i sti ng choi ce and the fi l e-openi ng choi ce to be compl etel y i ndependent of each other;
normal l y, we woul d want an open-fi l e opti on as a choi ce i n the di rectory-l i sti ng menu.
I n fact, the fi l e-openi ng choi ce al l ows di rectory l i sti ng al l by i tsel f.
I f we i mpl ement compl etel y the doDirList() proc, i t shoul d do thi s:
• al l ow us to change di rectory to ~/Lab04, i f that di rectory exi sts (Tk
understands '~');
• present a tk_chooseDirectory di al og;
• use glob to obtai n a l i st of the fi l es i n the chosen di rectory;
• present the l i st i n a text wi dget gridded as the ol d pl acehol der $Ans.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
80
The code for the ful l y i mpl emented proc:
proc doDirList { Win } \
{
set StartDir {.};
#
if { [file exists $StartDir] } { cd $StartDir; }
set Choice [tk_chooseDirectory];
if { [catch {cd $Choice} ErrVar] } \
{set Msg [format "%s\n%s" "doDirList() ERROR: Cant cd to $Choice" $ErrVar];
tk_messageBox -title {Directory Access Error} -icon error \
-type ok -message "$Msg";
} \
else { cd $Choice; }
#
set DirGlob [glob -nocomplain -tails -dir $Choice *];
#
if { [llength $DirGlob] > 0 } \
{ set DirGlob [lsort $DirGlob];
foreach {f} "$DirGlob" { append DirList "$f\n"; }
} \
else { set DirList {(none found)}; }
#
# This permits repeated listings:
if { [winfo exists .$Win] } { destroy .$Win; };
#
text .$Win -height 10 -bg cornsilk;
.$Win insert end $DirList;
grid .$Win -row 2 -columnspan 2 -sticky {e w};
}
The popup now functi ons thi s way: After pi cki ng "Li st Di rectory Contents..." (wi th
the tk_chooseDirectory di al og reposi ti oned):
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
81
Noti ce how a di fferent wi ndow styl e i n thi s l ast Li nux fi gure has caused sl i ghtl y
di fferent Tk wi dget styl es, as compared wi th the precedi ng fi gures: The wi ndow banner
has gone from an orange or purpl i sh background to a l i ght bl ue one -- and, i t has become
shaded for "3-D" curvature, whereas the previ ous banner was shaded hori zontal l y.
However, the Tk i mage col ors and shadi ngs have been preserved as speci fi ed i n the
scri pt.
Then, wi th Lab04 chosen, the mai n wi ndow i s regrided to thi s:
Of course, i f there were more than about ten Lab04 di rectory entri es, the text i tems
coul d be scrol l ed to vi ew them al l .
The "Open a Fi l e..." operati on i s si mi l ar. The resul t of pi cki ng i t and then sel ecti ng a
fi l e i s shown next; pi cki ng "Open" i nvokes vim to open the fi l e:
Executabl e code for thi s devel opment of the GUI wi th a popup menu i s avai l abl e to
you i n your Lab04 di rectory, i n fi l es named, "SimplePopupxxx".
We can proceed now to a l ab exerci se i n whi ch we shal l use what we know to bui l d a
menu-dri ven GUI appl i cati on for vi ewi ng Tk i mages.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
82
Lab 4: Image-Viewing GUI Application
Change to your Lab04 di rectory.
I f you run ls on the ~/doc di rectory, you wi l l fi nd several xbm i mage fi l es.
Step 1. I mage-l i sti ng scri pt.
Wri te a pl ai n TcL scri pt whi ch cal l s a proc to col l ect the names of al l .xbm fi l es i n
any gi ven di rectory, stores the names i n a TcL array, and returns. Each array name
shoul d be the fi l e name (no extensi on); each array val ue shoul d be the ful l pathname i n
the fi l i ng system of the fi l e, i ncl udi ng i ts extensi on.
The scri pt then shoul d cal l a second proc whi ch puts each el ement (name and val ue)
i n the array to the screen. The scri pt then shoul d termi nate.
Test your scri pt on the ~/doc di rectory and i n another di rectory whi ch contai ns no
.xbm fi l e. Al so try i nvoki ng i t on a nonexi stent di rectory.
Step 2. GUI speci fi cati on. There i s no i mpl ementati on i n thi s Step, just
understandi ng.
We wi sh to i mpl ement a GUI whi ch wi l l gi ve us access to xbm i mages. I t shoul d al l ow
us to choose a di rectory and shoul d use a listbox to di spl ay al l .xbm fi l es i n that
di rectory. For a fi l e sel ected i n the listbox, our GUI shoul d al l ow us to choose
whether to di spl ay the fi l e si ze i n bytes, the i mage di mensi ons i n pi xel s, or the i mage
graphi c i tsel f.
Here i s a sketched l ayout of our GUI :
The GUI i s composed i n a frame whi ch has two menu buttons (button wi dget) near
the top, and, to thei r ri ght, a dynami c text output area (label wi dget). Bel ow the
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
83
menu area i s a wi de text wi dget di spl ayi ng dynami cal l y the current di rectory path, the
absol ute path to the di rectory i n whi ch i mage fi l es wi l l be l i sted. Bel ow the current
path di spl ay are two l arger rectangul ar regi ons. The l eft rectangul ar regi on contai ns
some stati c text (label wi dget) whi ch gi ves i nstructi ons on how to use the GUI (there i s
no hel p menu). On the ri ght i s a listbox di spl ayi ng the fi l e names of al l .xbm fi l es i n
the (di spl ayed) di rectory. One fi l e at a ti me may be sel ected i n the listbox.
The two buttons do the work; they control tk_popup menues. The {File} menu
provi des two choi ces, one to sel ect the di rectory the contents of whi ch the listbox wi l l
di spl ay, and another to exi t the appl i cati on. The {View Mode} menu provi des three
choi ces, one to show the si ze i n bytes of the sel ected fi l e, another to di spl ay the
di mensi ons (wi dth and hei ght) of the i mage i n the sel ected fi l e, and a thi rd to di spl ay
graphi cal l y the i mage i n the fi l e. The two fi rst {View Mode} menu choi ces produce
output i n the "Fi l e attri bute" text area shown i n the sketch; the thi rd choi ce creates a
new, nonmodal wi ndow contai ni ng the di spl ayed i mage graphi c.
When the xbm fi l e i s desel ected, the attri butes are cl eared, but the i mage wi ndow
persi sts unti l ei ther i t i s cl osed i ndi vi dual l y or the appl i cati on i s exi tted. Thus, several
i mages may be sel ected successi vel y and di spl ayed si mul taneousl y i n i ndependent
wi ndows.
Step 3. I nert GUI l ayout.
I mpl ement a fi rst-pass, prototype GUI compl etel y i n a new TcL scri pt fi l e: Use a
frame wi dget and the gridder. Use the TcL pwd command for the stri ng to be di spl ayed
i n a label the current worki ng di rectory. For the rest, use stati c-text label wi dgets
for al l features but the listbox -- use a real but empty listbox wi dget there. Adjust
your prototype to deci de the si zes and arrangement of the parts of your GUI .
To save you some ti me wi th thi s, a copy of one of the previ ousl y presented listbox
exampl es has been provi ded for you i n your Lab04 di rectory. I t i s i n a fi l e named,
fileChooseLB.tcl.
Step 4. GUI hel p message di spl ay.
I mpl ement the l eft-bottom rectangul ar text regi on as a stati c-text label wi dget
contai ni ng user i nstructi ons on how to operate your GUI . Try to make the i nstructi ons
as conci se and compl ete as you can; however, as you proceed wi th the l ab, you al ways
can i mprove on the i nstructi ons whi l e perfecti ng the rest of the GUI .
Step 5. Sel ecti bl e listbox di spl ay.
Usi ng the pwd path as the defaul t di rectory, i mpl ement the listbox. Have the
listbox i tems properl y di spl ayed, dependi ng on the di rectory choi ce. Each i tem shoul d
be a fi l e name onl y, not a di rectory path, and your scri pt shoul d be stori ng the path for
each i tem i n a TcL array, for l ater menu access.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
84
Step 6. The {File} menu i mpl ementati on.
I mpl ement the l eft button-control l ed menu. The two choi ces whi ch pop up shoul d
be: (a) choose a new di rectory; and, (b) exi t the appl i cati on. Modi fy your scri pt so the
di rectory path di spl ayed, and therefore the listbox contents, are control l ed by thi s fi rst
popup choi ce.
Step 7. The {View Mode} menu i mpl ementati on.
Compl ete your GUI by i mpl ementi ng the ri ght popup menu. The fi l e si ze can be
obtai ned from the fi l i ng system (use TcL file size); the i mage di mensi ons can be
extracted by readi ng the fi rst few l i nes i n the sel ected xbm fi l e, and the i mage can be
di spl ayed i n a new top l evel label wi ndow so that i t can remai n (nonmodal l y) vi si bl e
unti l appl i cati on exi t.
Recommendati on: Decl are a di fferent proc for each of these menu i tems.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
85
Review and Wrap-Up
We have tri ed i n thi s Workshop to present the most basi c and useful features of Tk, to
provi de tool s for creati on of a si mpl e but compl etel y functi onal GUI , and al so to suppl y
enough understandi ng to permi t the attendees to extend thei r knowl edge and experi ence
i nto the vast and growi ng domai n of TcL.
Graphi cal Programmi ng
Somethi ng very i mportant whi ch you shoul d keep i n mi nd from thi s course:
Graphi cal methodol ogy can di ffer from scri pti ng methodol ogy.
Scri pted procedures work best wi th parameters passed via thei r cal l i ng argument l i st,
and by returni ng val ues i nl i ne. But, when wri ti ng a scri pt to i mpl ement graphi cal
objects, thi s approach becomes cumbersome and someti mes unrel i abl e. I nstead, for
graphi cal programmi ng, judi ci ous use of gl obal vari abl es (wi th set) or namespace
vari abl es (wi th variable) shoul d be consi dered very seri ousl y.
Topi cs We Have Presented
I n thi s Workshop, we started by defi ni ng the basi c el ements of a GUI : wi ndows,
i mages, pal ettes, text, and wi dgets. We descri bed the rel ati onshi p of Tk to TcL,
presented a few general Tk commands, tk, wm, and winfo, and expl ai ned the three
geometry managers, packer, gridder, and placer. We used packer i n most of our earl y
exampl es.
After a bri ef l ab, we went i nto detai l on the essenti al s of fonts i n Tk, as wel l as the
use of text and entry wi dgets. We expl ai ned event bi ndi ng before a second l ab, whi ch
was concentrated on text mani pul ati on.
We then revi ewed namespaces and recommended how they shoul d be used i n a
modest-si zed Tk GUI . We detai l ed the use and format of xbm i mages, and expl ai ned
how to create them as wel l as how to defi ne thei r col or styl es wi th tk_setPalette. We
then presented some of the most useful Tk wi dgets and hel d a major l ab on thei r use
i ndi vi dual l y.
Fi nal l y, we expl ai ned how to generate mul ti pl e i ndependent wi ndows i n a si ngl e Tk
scri pt, usi ng toplevel, and presented two more wi dgets, the labelframe and the
listbox. We wrapped up the Workshop wi th a l ab i n whi ch we combi ned previ ous
ski l l s to create a compl ete, si mpl e GUI appl i cati on for vi ewi ng i mages.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
86
Topi cs Omi tted
Here i s a l i st of thi ngs whi ch we have omi tted i n thi s Workshop for l ack of ti me:
Fi rst, we have omi tted di scussi on of the majori ty of the opti ons avai l abl e i n the wi dgets
and other functi ons presented i n detai l ; these are l eft to the attendee as essenti al l y
tri vi al i n thei r i nstructi onal val ue.
Second, we al so have omi tted di scussi on of many Tk commands, some of whi ch are qui te
di fferent from those we have covered. However, i f the attendee has understood
what we have presented, these shoul d not be di ffi cul t to use effecti vel y, based on
study of the ActiveState TcL and Tk hel p system:
• We omi tted the fol l owi ng si mpl e wi dgets: checkbutton, message,
menubutton, panedwindow, radiobutton, scale, scrollbar, and
spinbox.
• We omi tted the fol l owi ng more compl ex functi ons: (a) canvas for arbi trary
graphi cal di spl ays associ ated wi th TcL commands; (b) tkwait to acti vate
concurrent procedures; (c) bindtags and event commands; (d) the
clipboard, selection, and send commands for Tk GUI i nterprocess
communi cati on; and, (e) al l drag and drop functi onal i ty.
We al so ski pped coverage of cursor speci fi cati on and the grab command.
Thi rd, we compl etel y omi tted di scussi on of the pl ethora of C and C++ i nterfaces defi ned
by the Tk_* bui l ti n procedures.
Fourth, we di d not even menti on numerous TcL packages, usual l y avai l abl e i n careful l y
speci fi ed namespaces, whi ch have been contri buted to TcL and Tk over the years.
Many of these packages add uni que functi onal i ty, such as i nterfaces to audi o
hardware, or to HTML, SQL, or XML database formats. Some of these wi l l be
tri vi al and redundant to anyone who has compl eted thi s Workshop. I n any case, a
compl ete l i st of these extensi ons i s avai l abl e i n the ActiveState TcL hel p system.
One day i s not enough for retenti on of what you have l earned. Start usi ng Tk as soon
as possi bl e.
Hopeful l y, you wi l l fi nd use for Tk i n your work i n the EDA i ndustry. TcL and Tk
are versati l e, hi gh-l evel means for rapi d devel opment of rel i abl e graphi cal software.
And, they are di rectl y portabl e to any modern, wi del y-used operati ng system.
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
87
Index
A
after command, example......37, 38
B
bell command.............................75
bind command......................43, 45
bitmap drawing tool ...............9, 27
bitmap image..........................8, 60
bitmap, Tk meanings..................60
bitmap, widget predefined .........60
bitmaps, GIF ................................4
bitmaps, photo .............................4
button labelframe example.........67
button widget .............................60
button widget example.........61, 77
C
colormap ....................................10
container object..........................35
E
entry widget ...............................43
entry widget example.................43
entry widget options...................46
entry, validate modes .................48
entry, validate options ................47
entry, validate procs ...................49
entry, validation ...................46, 48
event binding .............................42
event, virtual ........................44, 69
exit command.............................66
F
focus, in GUI .............................45
font, in Tk ............................ 11, 30
frame widget ........................35, 67
frame widget example................34
G
geometry managers ....................18
GIMP drawing tool ....................28
global, in GUI communication...74
grid example ..............................20
gridder manager ...................19, 70
gridder, sticky option .................74
I
icon ............................................14
image create command...............54
image create example.................57
image create, example................10
image delete command...............55
image names command..............55
image, bitmap.........................8, 56
image, namespace example........54
image, photo ........8, 11, 54, 55, 57
image, Tk types............................8
K
KIconEdit, drawing tool.............28
L
label example .............................19
label widget................................61
label widget, globals ..................41
label widget, wraplength units ...70
label windows, multiple .............66
label, dynamic text .....................44
label, example ............................11
labelframe button example.........67
labelframe widget.......................67
layer, of window...........................8
listbox browse option.................72
listbox curselection command....72
listbox extended option..............72
listbox font option......................71
listbox get command..................72
listbox height and width options 71
listbox insert command ........70, 72
listbox listvariable option...........72
listbox select mode.....................72
listbox simple example...............70
listbox simple example framed ..71
listbox simple GUI example ......73
listbox state option.....................71
listbox widget.............................69
listbox window colors ................71
listbox, item index......................69
listbox, item pixel offset.............69
listbox, scrolling.........................74
listbox, selection ........................69
listbox, selection event...............69
lower command..........................24
M
menu add....................................76
menu options..............................76
menu widget.........................75, 76
modal, Tk window......................63
monospace font ..........................30
mtpaint drawing tool ..................28
N
namespace eval command..........53
namespace exists command .......53
namespace, for images ...53, 55, 68
nonmodal, Tk window................62
P
pack command ...........................10
pack example .............................18
packer manager ....................17, 18
palette, Tk GUI.....................10, 57
photo image..........8, 11, 54, 55, 57
place example ..........21, 22, 23, 24
placer manager ...........................20
popup menu, in simple GUI .......79
proportional font ........................30
R
raise command ...........................24
References....................................5
RGB, color.................................10
S
sans serif ....................................30
scrollbar widget..........................69
serif ............................................30
stacking order, of window......8, 24
T
tag, window................................43
tags, text widget .........................31
text and label append .................38
text append, order effect ............39
text tags......................................31
text widget..................................34
text widget example ...................32
text widget, append ....................38
text widget, char indexing..........34
text, attributes............................. 11
text, in label ...............................11
text, script control ......................35
tk appname, example..................13
tk command................................13
tk windowingsystem...................14
Tk, installation..............................6
tk_, names ................................6, 7
tk_chooseColor ..........................64
tk_chooseDirectory....................64
tk_chooseDirectory example......79
tk_dialog ..............................62, 63
tk_dialog example................49, 67
J. M. Wi l l i ams 2009-05-22 Tk Fundamental s
1
tk_dialog, as main window ........68
tk_dialog, example.......................7
tk_getOpenFile ..........................64
tk_getSaveFile ...........................65
tk_messageBox....................61, 62
tk_messageBox, vs dialog..........63
tk_popup....................................75
tk_popup example......................78
tk_popup options .......................76
tk_setPalette...................10, 57, 58
tk_setPalette example ................58
toplevel command..........34, 35, 66
toplevel example........................66
transparent bitmap........................8
U
upvar, requires global.................41
use option...................................35
V
validation example.....................49
validation, of entry.....................47
variable command......................53
variable command, namespace53, 68
W
widget ........................................12
widget configuration ..................31
widget, execution of...................31
widget, text.................................31
window id, of container .............35
window, focus ............................45
window, global hierarchy...........74
window, in GUI ...........................7
window, naming.....................8, 76
window, Tk hierarchy...........13, 31
windows, multiple independent..66
winfo exists ................................17
winfo geometry ..........................17
winfo id................................17, 34
winfo manager............................18
winfo pathname..........................18
wish shell ...............................7, 25
wish, in shell script.....................26
wm colormapwindows ...............14
wm geometry........................17, 76
wm iconbitmap.....................14, 57
wm iconbitmap example ......16, 75
wm state command.....................16
wm title ................................17, 35
wm withdraw command .............66
X
X event binding............................4
xbm format.............................9, 56
Xdefaults......................................6
Xdefaults file................................4
============== Begin lab answers: ==========
Note: This course normally would include lab answers in plain text and Tk. However, Scribd
currently can not conveniently provide for anything but textual or graphical continuations of the
nonlab presentation. Therefore, the course answers are appended below, as converted to PDF.
Each lab answer below is named and is delimited by "=========================" marks.
Use your PDF search command to step from one answer to another.
======================= Lab01 Step 1:
#
puts "We can do squares and circles.";
#
======================= Lab01 Step 2:
# For Lab01, Step 2:
#
proc labelText { Win String } \
{
label .$Win -text $String -font {-size 16 -family Courier};
pack .$Win;
}
#
======================= Lab01 Step 3:
# For Lab01, Step 3:
#
proc labelGimp { Win String } \
{
wm iconbitmap . @Lab01_LabelGimp.xbm;
label .$Win -text $String -font {-size 16
-family Courier} -bg white -fg black;
pack .$Win;
}
#
Image of .png:
Image of .xbm:
======================= Lab01 Step 4:
# For Lab01, Step 4:
#
proc labelBitmap { Win String } \
{
wm iconbitmap . @Lab01_LabelBitmap.xbm;
label .$Win -text $String -font {-size 16
-family Courier} -bg white -fg black;
pack .$Win;
}
#
Image of .xbm:
Converted to .tif:
======================= Lab02 Step 1:
#
# Lab 2, Step 1 ans:
#
proc doText3Lines { Win String } \
{
wm title . {Lab 2, Step 1};
#
text .$Win -font {-size 16 -family Times -slant italic -weight bold} \
-height 3 -width 20 -bg LightGreen -fg DarkBlue;
.$Win insert end "$String";
pack .$Win;
}
doText3Lines x "Here's line 1,\nAnd here's line 2,\nAnd line 3.
#
======================= Lab02 Step 2:
#
# Lab 2, Step 2 ans:
#
proc doText3LinesLabel { Win String } \
{
wm title . {Lab 2, Step 2};
#
text .$Win -font {-size 16 -family Times -slant italic -weight bold} \
-height 3 -width 20 -bg LightGreen -fg DarkBlue;
.$Win insert end "$String";
#
label .l$Win -font {-size 18 -family Courier -underline true} \
-bg LightBlue -fg DarkGreen -text $String;
#
pack .$Win .l$Win;
}
# Runtime:
set Text "Here's line 1,\nAnd here's line 2,\nAnd line 3.";
doText3LinesLabel x $Text
#
======================= Lab02 Step 3:
# ---------------------------------------------------------------------------------------------------------------------------
# Lab 2, Step 3 ans:
#
# A separate, reusable proc is provided to write a
# string to a file. Because of file I/O, when
# this proc is called, it is called by catch, to allow
# system or permission errors to be reported.
#
# The main program checks for valid input; when a valid
# line has been entered, it opens a file by hard-coded
# name, writes the valid line to the file, closes the file,
# and exits the application.
# ---------------------------------------------------------------------------------------------------------------------------
proc writeLine { Fname Line } \
{
if { [catch {set Fw [open "$Fname" w]} ErrMsg]!=0 } \
{set Report "writeLine(): Open \[$Fname\] for write failed.";
set Report "$Report\nopen: $ErrMsg";
} \
else {puts $Fw $Line;
close $Fw;
set Report "";
}
return $Report;
}
#
# Create the entry widget, and handle valid and
# invalid input by subproc's and tk_dialogs:
proc doEntryWrite { Win } \
{
wm title . {Lab 2, Step 3};
#
global LineIn; # Just to reserve the name.
#
# Handle invalid input:
proc inval_doEntryWrite {Win} \
{bell;
tk_dialog .i$Win "BAD ENTRY!" \
"Please enter a string of lower-case chars,
7 - 19 chars long." error 0 "OK";
return 1;
}
#
# Handle valid input and write file:
proc val_doEntryWrite {Win} \
{
global LineIn;
if { ([string length $LineIn]>6 && [string length $LineIn]<20)
&& [string is lower $LineIn]
} \
{
# Entry value was valid:
set Sts [writeLine Lab2_Step3.txt "$LineIn"];
if { $Sts == "" } \
{
# Successful file open; assume write was OK:
exit 0;
} \
else {
# Error message:
bell;
tk_dialog .e$Win "File OPEN error!" \
"System or write-permission error? Message was:\n
$Sts" error 0 "OK";
# Return failed validate to allow a new try:
return false;
}
} \
else {
# Trigger the invalid-entry proc:
return false;
}
}
#
# Create the entry and display it:
if { [winfo exists .$Win] } \
{set LineIn [.$Win get]; } \
else {entry .$Win -font {-size 18 -family Courier} -width 22 \
-validate focusout -vcmd "val_doEntryWrite $Win" \
-invcmd "inval_doEntryWrite $Win";
pack .$Win;
}
}
# Runtime:
doEntryWrite x;
bind . <Key> "doEntryWrite x";
# End script
======================= Lab02 Step 4 (OPTIONAL):
# ---------------------------------------------------------------------------------------------------
# Lab 2, Step 4 ans:
# The label is packed first to put it on top.
# --------------------------------------------------------------------------------------------------
#
proc doTextLabel { Win } \
{
wm title . {Lab 2, Step 4};
#
global LineIn;
#
set LineIn "BEGIN: ";
#
# Create and display the label; its display will track
# the -textvariable automatically:
if { ![winfo exists .l$Win] } \
{label .l$Win -font {-size 16 -family Helvetica} \
-bg yellow -fg {dark blue} -textvariable LineIn;
pack .l$Win;
}
# Create the text, keep it copied into a variable,
# and display it:
if { [winfo exists .x$Win] } \
{set LineIn [.x$Win get 1.0 end]; } \
else {text .x$Win -font {-size 16 -family Times} -width 20 -height 1;
pack .x$Win;
}
}
# Runtime:
doTextLabel x;
bind . <Key> "doTextLabel x";
# End script
======================= Lab02 Step 5 (OPTIONAL):
# -------------------------------------------------------------------------------------
# Lab 2, Step 5 ans:
# -------------------------------------------------------------------------------------
#
# Create the entry widget, and handle valid and
# invalid input by subproc's and tk_dialogs:
#
proc doGetNum { Win } \
{
wm title . {Lab 2, Step 5};
#
global LineIn;
#
# Handle invalid input:
proc inval_doGetNum {} { bell; return true; }
#
# Handle valid input:
proc val_doGetNum {Win} \
{
global LineIn;
#
# Initialize the result flag:
set GoodNumber false;
#
# Evaluate input:
if { [regexp {^[0-9.+-][0-9.]*$} "$LineIn"] } \
{
# Must check for multiple decimal points:
set One [string first {.} "$LineIn"];
if { $One == "-1" } \
{ set GoodNumber true; } \
else {
# Check for another decimal point:
set One [expr $One + 1];
set Two [string first {.} "$LineIn" $One];
if { $Two == "-1" } { set GoodNumber true; }
}
}
#
# Take action:
if { $GoodNumber == true } \
{
tk_dialog .d$Win "Numerical Value Report" \
"The number is valid:\n \[$LineIn\]" info 0 "Dismiss";
return true;
} \
else { return false; }
}
# End proc val_doGetNum().
#
# Create the entry and display it:
if { [winfo exists .$Win] } \
{set LineIn [.$Win get]; } \
else {entry .$Win -font {-size 14 -family Courier} -width 20 \
-validate focusout -vcmd "val_doGetNum $Win" \
-invcmd "inval_doGetNum";
pack .$Win;
}
}
# Runtime:
doGetNum x;
bind . <Key> "doGetNum x";
# End script
======================= Lab03 Step 1:
CopyFile script:
#!/bin/sh
# \
exec wish "$0" "$@"
#
# Conceal the inert main wish window; it
# will be destroyed when exit is run:
wm withdraw .;
#
# Make invocation args more accessible:
set SourceF [lindex $argv 0];
set DestF [lindex $argv 1];
#
# Check the source file:
if { ![file exists $SourceF] } \
{
tk_messageBox -title {ERROR: No Source File} -icon error \
-type ok -message "Source file \[$SourceF\] not found.";
exit;
}
#
# Check the destination:
if { [file exists $DestF] } \
{
tk_messageBox -title {ERROR: Overwrite} -icon error \
-type ok -message "Destination file \[$DestF\] exists.";
} \
else {
# All OK; do the copy:
file copy $SourceF $DestF;
}
exit;
#
======================= Lab03 Step 2:
#!/bin/sh
# \
exec wish "$0" "$@"
#
# Define a proc to return the required environment
# values in a format suitable for a TcL array:
proc saveEnv {} \
{
global env;
foreach v {TEMP PWD USER HOME PATH} \
{
# Must handle nonexistent or null variables:
if { [catch {set Junk $env($v)}] } { set env($v) {(not set)} };
if {$env($v) eq ""} { set env($v) {(null)}; }
lappend EnvList $v "$env($v)";
}
return $EnvList;
}
#
# Define a proc to handle the tk_dialog.
# The first while cleans up text windows to allow the label
# Check Env button to be used repeatedly:
proc doDialog {} \
{
set I 1;
while { [winfo exists .t$I] } { destroy .t$I; incr I; }
#
set I 0;
while { [incr I] } \
{
array set EnvArray [saveEnv];
# window title text ... bm def (names)
set Choice [tk_dialog .dWin {Check the Environment} {Pick a variable to check} \
{info} 5 TEMP PWD USER HOME PATH Done];
switch $Choice \
{
0 { text .t$I -bg white -height 1 -width 15;
.t$I insert end "TEMP=\[$EnvArray(TEMP)\]";
pack .t$I;
}
1 { text .t$I -bg white -height 1 -width 15;
.t$I insert end "PWD=\[$EnvArray(PWD)\]";
pack .t$I;
}
2 { text .t$I -bg white -height 1 -width 15;
.t$I insert end "USER=\[$EnvArray(USER)\]";
pack .t$I;
}
3 { text .t$I -bg white -height 1 -width 15;
.t$I insert end "HOME=\[$EnvArray(HOME)\]";
pack .t$I;
}
4 { text .t$I -bg white -height 1 -width 15;
.t$I insert end "PATH=\[$EnvArray(PATH)\]";
pack .t$I;
}
default { destroy .dWin; break; }
}
}
}
#
# Set up the GUI widgets:
set L [label .labelWin -text "Make a choice: " -font {-size 16} -bg yellow -fg {dark green}];
set Bexit [button .bExitWin -text Exit -command {exit;}];
set Benv [button .bEnvWin -text {Check Env} -command {doDialog;}];
#
# Runtime:
pack $L $Bexit $Benv -side left;
#
======================= Lab03 Step 3:
#!/bin/sh
# \
exec wish "$0" "$@"
#
proc doColor {} \
{
set Choice [tk_chooseColor];
tk_messageBox -message "Your choice=\[$Choice\]." -icon info -title Result -type ok;
exit
}
#
# Set up the GUI widgets:
set L [label .labelWin -text "Make a choice: " \
-font {-size 16 -weight bold} -bg yellow -fg {dark green}];
set Bexit [button .bExitWin -text Exit -command {exit;}];
set Bcolor [button .bColWin -text {Choose a Color} -command {doColor;}];
#
# Runtime:
pack $L $Bexit $Bcolor -side left;
#
======================= Lab03 Step 4:
#!/bin/sh
# \
exec wish "$0" "$@"
#
set StartDir /usr;
#
if { [file exists $StartDir] } { cd $StartDir; }
#
proc doDir {} \
{
set Choice [tk_chooseDirectory];
set ChoiceTail [file tail $Choice];
#
tk_messageBox -message "Your choice=\[$ChoiceTail\].\nOK to list contents:" \
-icon info -title Result -type ok;
set DirGlob [glob -nocomplain -tails -dir $Choice .*?? *];
foreach f "$DirGlob" { append DirList "$f\n"; }
#
# This permits repeated listings:
if { [winfo exists .tWin] } { destroy .tWin; };
#
text .tWin -width 10 -height 10 -bg cornsilk;
.tWin insert end "$DirList";
grid .tWin -row 2 -columnspan 3 -sticky {e w};
}
#
# Set up the GUI widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 16 -weight bold} -bg yellow -fg {dark green}];
set Bexit [button .bExitWin -text Exit -font {-size 14} -bd 10 \
-bg red -command {exit;}];
set Bcolor [button .bColWin -text {Choose a Directory} -font {-size 14} \
-bd 10 -bg green -command {doDir;}];
#
# Runtime:
grid $L $Bexit $Bcolor -row 1
#
======================= Lab03 Step 5 (OPTIONAL):
#!/bin/sh
# \
exec wish "$0" "$@"
#
set StartDir /usr;
set WinVim {gvim.exe};
#
if { [file exists $StartDir] } { cd $StartDir; }
#
proc doFopen { WinVim } \
{
set Choice [tk_getOpenFile];
set ChoiceTail [file tail $Choice];
#
tk_messageBox -message "Your choice=\[$ChoiceTail\].\nOK to open in vim:" \
-icon info -title Result -type ok;
if { [catch {set Fr [open $Choice r]} ErrVar] } \
{
set Msg [format "%s\n%s" "doFopen() ERROR: Cant open $ChoiceTail" \
$ErrVar];
tk_messageBox -title {File Open Error} -icon error \
-message "$Msg" -type ok;
} \
else { close $Fr;
if { [regexp -nocase "win" [tk windowingsystem]] } \
{ catch {exec cmd.exe /c $WinVim $Choice}; } \
else { catch {exec vim -g $Choice}; }
}
}
#
# Set up the GUI widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 16 -weight bold} -bg {light blue} -fg red];
set Bexit [button .bExitWin -text Exit -font {-size 14} -bd 8 \
-bg red -command {exit;}];
set Bcolor [button .bColWin -text {Open File ...} -font {-size 14} \
-bd 8 -bg green -command {doFopen $WinVim;}];
#
# Runtime:
grid $L $Bexit $Bcolor -row 1
#
======================= Lab03 Step 6 (OPTIONAL):
#!/bin/sh
# \
exec wish "$0" "$@"
#
set StartDir {~/Lab03};
if { [file exists $StartDir] } { cd $StartDir; }
#
# Use a widget to get the source file name:
proc doFopen {} \
{
global SrcFname;
set SrcFname [tk_getOpenFile];
set SrcFname [file normalize $SrcFname];
set SrcFnameTail [file tail $SrcFname];
#
tk_messageBox -message "File to be saved=\[$SrcFnameTail\]." \
-icon info -title Result -type ok;
if { [catch {set Fr [open $SrcFname r]} ErrVar] } \
{
set Msg [format "%s\n%s" \
"doFopen() ERROR: Cant open $SrcFnameTail for read." $ErrVar];
tk_messageBox -title {File Open Error} -icon error \
-message "$Msg" -type ok;
} \
else {
close $Fr;
doFsave;
}
}
# Use another widget to get the destination file name
# and do the copy:
proc doFsave {} \
{
global SrcFname;
set DstFname [tk_getSaveFile];
set DstFname [file normalize $DstFname];
#
while { $DstFname eq $SrcFname } \
{
tk_messageBox \
-message "\[$DstFnameTail\] can't be saved to same name." \
-icon error -title {Bad Save Destination} -type ok;
set DstFname [tk_getSaveFile];
}
set DstFnameTail [file tail $DstFname];
#
tk_messageBox -message "\[$DstFnameTail\] will be written.\nOK to proceed:" \
-icon info -title Result -type ok;
if { [catch {file copy $SrcFname $DstFname} ErrVar] } \
{
set Msg [format "%s\n%s" \
"doFsave() ERROR: Cant copy to $DstFnameTail." $ErrVar];
tk_messageBox -title {File Open Error} -icon error \
-message "$Msg" -type ok;
} \
}
#
# Set up the GUI widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 16 -weight bold} -bg {light blue} -fg red];
set Bexit [button .bExitWin -text Exit -font {-size 14} -bd 8 \
-bg red -command {exit;}];
set Bcolor [button .bColWin -text {Save New File ...} -font {-size 14} \
-bd 8 -bg green -command {doFopen;}];
#
# Runtime:
grid $L $Bexit $Bcolor -row 1
#
======================= Lab04 directory contents:
The Tk.xbm widget:
======== fileChooseLB.tcl:
proc fileChooseLB { W Dir } \
{wm title . {Listbox to Choose a Filename};
#
set Flist [glob -nocomplain -tails -dir $Dir */*];
#
frame .f$W -background {light goldenrod};
#
set HelpVar {Select any file in the list box on };
append HelpVar {the right. Your choice will be };
append HelpVar {confirmed; then the choice value };
append HelpVar {will be passed to an independent };
append HelpVar {window to simulate useful activity.};
#
label .f$W.lDir$W -text "$Dir" -wraplength {20 c} -bg grey90;
label .f$W.lMsg$W -text $HelpVar -wraplength { 8 c} -bg cornsilk;
listbox .f$W.lBox$W -width 15 -height 6;
#
foreach f "$Flist" { .f$W.lBox$W insert end $f; };
#
grid configure .f$W -row 1 -columnspan 3;
grid configure .f$W.lDir$W -row 1 -columnspan 3 -sticky {e w};
grid configure .f$W.lMsg$W -row 2 -column 1;
grid configure .f$W.lBox$W -row 2 -column 2;
#
proc fileChooseLBsel { W } \
{ global TransferVar;
set Sel [.f$W.lBox$W curselection];
if {$Sel ne {} } \
{set Got [.f$W.lBox$W get $Sel];
set TransferVar $Got;
tk_dialog .f$W.d {Acknowledgement of Selection} \
"You chose $Got" {} 0 {Dismiss};
doIt;
}
}
#
bind .f$W.lBox$W <<ListboxSelect>> "fileChooseLBsel $W;";
}
proc doIt {} \
{ global TransferVar;
tk_messageBox -icon info -type ok -title "New Application Called" \
-message "Now processing $TransferVar";
};
fileChooseLB x ~/Lab01;
#
======== SimplePopupLayout:
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a simple popup menu.
###########################################################################
#
###########################################################################
# Runtime:
# The main window is initialized at (150,150); the popup at (200,220).
# ------------------------------------------------------------------
#
wm title . {My Clever Popup};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
# Set up the Main Menu Bar widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 14 -weight bold} -bg blue -fg yellow];
set B1 [button .b1Win -text {Choice 1} -font {-size 14} \
-bd 6 -bg green -command {bell;}];
set B2 [button .b2Win -text {Choice 2} -font {-size 14} \
-bd 6 -bg green -command {bell;}];
set Bexit [button .bExitWin -text {Exit} -font {-size 14} \
-bd 6 -bg red -command {exit;}];
set Ans [label .ansWin -bg cornsilk];
#
# Runtime:
grid $L $B1 $B2 $Bexit -row 1;
grid $Ans -row 2 -columnspan 4 -sticky {e w};
# End of script.
======== SimplePopupPartial:
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a simple popup menu.
###########################################################################
proc doDirList {Dummy} { tk_messageBox -message "doDirList(): Not implemented"; }
proc doFileOpen {Dummy} { tk_messageBox -message "doFileOpen(): Not implemented"; }
proc doEnvList {Dummy} { tk_messageBox -message "doEnvList(): Not implemented"; }
proc doEnvMod {Dummy} { tk_messageBox -message "doEnvMod(): Not implemented"; }
#
# ------------------------------------------------------------------
# This proc presents the file system popup menu:
proc doPopFil {Win} \
{
if { [winfo exists .$Win] } { destroy .$Win; }
set m [menu .$Win -tearoff 0 -disabledforeground black];
$m add command -label {Filesystem Access} -back green -state disabled;
$m add command -command "doDirList $Win" -label {List Directory Contents...};
$m add command -command "doFileOpen $Win" -label {Open a File...};
tk_popup .$Win 200 220;
bind .$Win <1> "tk_popup .$Win 200 220";
}
#
#
# ------------------------------------------------------------------
# This proc presents the environment popup menu:
proc doPopEnv {Win} \
{
if { [winfo exists .$Win] } { destroy .$Win; }
set m [menu .$Win -tearoff 0 -disabledforeground black];
$m add command -label {Environment Access} -back pink -state disabled;
$m add command -command "doEnvList $Win" -label {List Selected Variables...};
$m add command -command "doEnvMod $Win" -label {Modify the Environment...};
tk_popup .$Win 200 220;
bind .$Win <1> "tk_popup .$Win 200 220";
}
#
###########################################################################
# Runtime:
# The main window is initialized at (150,150); the popup at (200,220).
# ------------------------------------------------------------------
#
wm title . {My Clever Popup};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
# Set up the Main Menu Bar widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 14 -weight bold} -bg blue -fg yellow];
set B1 [button .b1Win -text {Access Files} -font {-size 14} \
-bd 6 -bg green -command {doPopFil ansWin;}];
set B2 [button .b2Win -text {Access Environment} -font {-size 14} \
-bd 6 -bg pink -command {doPopEnv ansWin;}];
set Bexit [button .bExitWin -text {Exit} -font {-size 14} \
-bd 6 -bg red -command {exit;}];
set Ans [label .ansWin -bg cornsilk]; # Now just a placeholder.
#
# Runtime:
grid $L $B1 $B2 $Bexit -row 1;
#grid $Ans -row 2 -columnspan 4 -sticky {e w};
# End of script.
======== SimplePopupDone:
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a simple popup menu.
###########################################################################
#
# ------------------------------------------------------------------
# This proc prompts for a file and opens the file in vim.
# There is no window required, because vim creates its own.
# Based on answer to Lab 3, Step 5 doFopen() proc:
#
proc doFileOpen { Unused } \
{
set WinVim {gvim.exe};
set StartDir {.};
#
if { [file exists $StartDir] } { cd $StartDir; }
#
set Choice [tk_getOpenFile];
set ChoiceTail [file tail $Choice];
#
if { [catch {set Fr [open $Choice r]} ErrVar] } \
{set Msg [format "%s\n%s" "doFopen() ERROR: Cant open $ChoiceTail" $ErrVar];
tk_messageBox -title {File Open Error} -icon error \
-type ok -message "$Msg";
} \
else { close $Fr;
if { [regexp -nocase "win" [tk windowingsystem]] } \
{ catch {exec cmd.exe /c $WinVim $Choice}; } \
else { catch {exec vim -g $Choice}; }
}
}
#
# ------------------------------------------------------------------
# This proc prompts and lists a directory:
# Based on answer to Lab 3, Step 4, doDir() proc:
#
proc doDirList { Win } \
{
set StartDir {.};
#
if { [file exists $StartDir] } { cd $StartDir; }
set Choice [tk_chooseDirectory];
if { [catch {cd $Choice} ErrVar] } \
{set Msg [format "%s\n%s" "doDirList() ERROR: Cant cd to $Choice" $ErrVar];
tk_messageBox -title {Directory Access Error} -icon error \
-type ok -message "$Msg";
} \
else { cd $Choice; }
#
set DirGlob [glob -nocomplain -tails -dir $Choice *];
#
if { [llength $DirGlob] > 0 } \
{ set DirGlob [lsort $DirGlob];
foreach {f} "$DirGlob" { append DirList "$f\n"; }
} \
else { set DirList {(none found)}; }
#
# This permits repeated listings:
if { [winfo exists .$Win] } { destroy .$Win; };
#
text .$Win -height 10 -bg cornsilk;
.$Win insert end $DirList;
grid .$Win -row 2 -columnspan 2 -sticky {e w};
}
#
# ------------------------------------------------------------------
# This proc presents the popup menu:
proc doPopFil {Win} \
{
if { [winfo exists .$Win] } { destroy .$Win; }
set m [menu .$Win -tearoff 0 -disabledforeground black];
$m add command -label {Filesystem Access} -back green -state disabled;
$m add command -command "doDirList $Win" -label {List Directory Contents...};
$m add command -command "doFileOpen $Win" -label {Open a File...};
tk_popup .$Win 200 220;
bind .$Win <1> "tk_popup .$Win 200 220";
}
#
###########################################################################
# Runtime:
# The main window is initialized at (150,150); the popup at (200,200).
# ------------------------------------------------------------------
#
wm title . {My Clever Popup};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
# Set up the Main Menu Bar widgets:
set L [label .labelWin -text "Make a choice: " -height 2 \
-font {-size 14 -weight bold} -bg blue -fg yellow];
set B1 [button .b1Win -text {Access File System} -font {-size 14} \
-bd 6 -bg green -command {doPopFil ansWin;}];
set Bx [button .bExitWin -text {Exit} -font {-size 14} \
-bd 6 -bg red -command {exit;}];
set Ans [label .ansWin -bg cornsilk]; # Just a placeholder.
#
# Runtime:
grid $L $B1 $Bx -row 1;
# End of script.
======================= Lab04 Step 1:
#!/bin/sh
# \
exec tclsh "$0" "$@"
###########################################################################
# This script collects image file names and prints them to the screen.
###########################################################################
set ScriptFname [file tail $argv0];
set DirName [lindex $argv 0];
#
# ------------------------------------------------------------------
# This proc finds all .xbm image files in a directory,
# stores them in an upvar'ed array, and returns:
#
proc doGetXBMs { Dir Array } \
{
upvar $Array ArrayL;
#
if { ![file exists $Dir] } { puts "No such directory as \[$Dir\]."; exit 0; }
#
if { [catch {set Fglob [glob -nocomplain -tails -dir $Dir *.xbm *.XBM]} ErrV] != 0 } \
{
puts "doGetXBMs(): Error listing xbm files in \[$Dir\].\n$ErrV"
exit -1;
}
#
if { [llength $Fglob] > 0 } \
{ set Flist [lsort $Fglob];
foreach {f} "$Flist" { set ArrayL([file rootname $f]) $f; }
} \
else { set ArrayL(none) {(none found)}; }
}
#
# ------------------------------------------------------------------
# This proc Prints the names, if any, in an array:
proc printArray {Array} \
{
upvar $Array ArrayL;
#
foreach {N} "[array names ArrayL]" { puts "$N: $ArrayL($N).\n"; };
}
#
# Runtime:
puts " ######################
$ScriptFname: Reports the xbm files in a directory.";
#
if { $argc < 1 } \
{
puts "Invocation error:
Invoke as $ScriptFname pathname_of_directory."
exit -1;
}
#
array set XBM_Array [list];
#
doGetXBMs $DirName XBM_Array;
puts "$ScriptFname : Directory is:
\[[file normalize $DirName]\].
It contains these .xbm files:"
printArray XBM_Array;
exit 0;
#
======================= Lab04 Step 2 (no implementation involved):
======================= Lab04 Step 3:
Typical test widget (Tk.xbm):
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a GUI-based icon viewer.
###########################################################################
#
wm title . {Icon Viewer};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
proc makeMainWindow { Win } \
{
#
set Dir [pwd];
#
set HelpV { (help message here) };
#
frame .$Win -background {light goldenrod};
label .$Win.lFileBut -text {File...} -bg green -fg black;
label .$Win.lViewBut -text {View Mode...} -bg pink -fg black;
label .$Win.lMesgBut -text {(file attributes here)} -bg white -fg black;
label .$Win.lDir -text "$Dir" -wraplength {20 c} -bg grey90;
label .$Win.lMsg -text $HelpV -wraplength { 8 c} -bg cornsilk;
listbox .$Win.lBox -width 20 -height 6 -bg {light green} -fg black;
#
#foreach f "$Flist" { .$Win.lBox insert end $f; };
#
grid configure .$Win -row 1 -columnspan 3;
grid configure .$Win.lFileBut -row 2 -column 0 -padx {0.5c};
grid configure .$Win.lViewBut -row 2 -column 1 -padx {0.5c};
grid configure .$Win.lMesgBut -row 2 -column 2 -columnspan 2 -sticky {e w};
grid configure .$Win.lDir -row 3 -columnspan 3 -sticky {e w};
grid configure .$Win.lMsg -row 4 -column 1;
grid configure .$Win.lBox -row 4 -column 2;
#
proc makeMainWindowSel { Win } \
{ global TransferVar;
set Sel [.$Win.lBox curselection];
if {$Sel ne {} } \
{set Got [.$Win.lBox get $Sel];
set TransferVar $Got;
tk_dialog .$Win.d {Acknowledgement of Selection} \
"You chose $Got" {} 0 {Dismiss};
doIt;
}
}
#
bind .$Win.lBox <<ListboxSelect>> "makeMainWindowSel $Win;";
}
proc doIt {} \
{ global TransferVar;
tk_messageBox -icon info -type ok -title "New Application Called" \
-message "Now processing $TransferVar";
};
makeMainWindow x ;
#
======================= Lab04 Step 4:
(same test widget)
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a GUI-based icon viewer.
###########################################################################
#
wm title . {Icon Viewer};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
proc makeMainWindow { Win } \
{
#
set Dir [pwd];
#
set HelpV {Choose a directory to open using the [File...] menu. };
append HelpV {All image (xbm) files in the directory will be };
append HelpV {displayed in the listbox to the right. };
append HelpV {You then may use the [View Mode...] menu either };
append HelpV {to see the file size of the image, the dimensions };
append HelpV {of the image, or the image itself.};
#
frame .$Win -background {light goldenrod};
label .$Win.lFileBut -text {File...} -bg green -fg black;
label .$Win.lViewBut -text {View Mode...} -bg pink -fg black;
label .$Win.lMesgBut -text {(file attributes here)} -bg white -fg black;
label .$Win.lDir -text "$Dir" -wraplength {20 c} -bg grey90;
label .$Win.lMsg -text $HelpV -wraplength { 8 c} -bg cornsilk;
listbox .$Win.lBox -width 20 -height 6 -bg {light green} -fg black;
#
#foreach f "$Flist" { .$Win.lBox insert end $f; };
#
grid configure .$Win -row 1 -columnspan 3;
grid configure .$Win.lFileBut -row 2 -column 0 -padx {0.5c};
grid configure .$Win.lViewBut -row 2 -column 1 -padx {0.5c};
grid configure .$Win.lMesgBut -row 2 -column 2 -columnspan 2 -sticky {e w};
grid configure .$Win.lDir -row 3 -columnspan 3 -sticky {e w};
grid configure .$Win.lMsg -row 4 -column 1;
grid configure .$Win.lBox -row 4 -column 2;
#
proc makeMainWindowSel { Win } \
{ global TransferVar;
set Sel [.$Win.lBox curselection];
if {$Sel ne {} } \
{set Got [.$Win.lBox get $Sel];
set TransferVar $Got;
tk_dialog .$Win.d {Acknowledgement of Selection} \
"You chose $Got" {} 0 {Dismiss};
doIt;
}
}
#
bind .$Win.lBox <<ListboxSelect>> "makeMainWindowSel $Win;";
}
proc doIt {} \
{ global TransferVar;
tk_messageBox -icon info -type ok -title "New Application Called" \
-message "Now processing $TransferVar";
};
makeMainWindow x ;
#
======================= Lab04 Step 5:
(same test widget)
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a GUI-based icon viewer.
###########################################################################
#
wm title . {Icon Viewer};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
proc makeMainWindow { Win Array } \
{
upvar $Array ArrayL;
global ArrayL; # Bug: upvar into makeMainWindowSel() doesn't work.
#
set Dir [pwd];
#
set HelpV {Choose a directory to open using the [File...] menu. };
append HelpV {All image (xbm) files in the directory will be };
append HelpV {displayed in the listbox to the right. };
append HelpV {You then may use the [View Mode...] menu either };
append HelpV {to see the file size of the image, the dimensions };
append HelpV {of the image, or the image itself.};
#
frame .$Win -background {light goldenrod};
label .$Win.lFileBut -text {File...} -bg green -fg black;
label .$Win.lViewBut -text {View Mode...} -bg pink -fg black;
label .$Win.lMesgBut -text {(file attributes here)} -bg white -fg black;
label .$Win.lDir -text "$Dir" -wraplength {20 c} -bg grey90;
label .$Win.lMsg -text $HelpV -wraplength { 8 c} -bg cornsilk;
listbox .$Win.lBox -width 20 -height 6 -bg {light green} -fg black;
#
grid configure .$Win -row 1 -columnspan 3;
grid configure .$Win.lFileBut -row 2 -column 0 -padx {0.5c};
grid configure .$Win.lViewBut -row 2 -column 1 -padx {0.5c};
grid configure .$Win.lMesgBut -row 2 -column 2 -columnspan 2 -sticky {e w};
grid configure .$Win.lDir -row 3 -columnspan 3 -sticky {e w};
grid configure .$Win.lMsg -row 4 -column 1;
grid configure .$Win.lBox -row 4 -column 2;
#
proc makeMainWindowSel { Win } \
{
global TransferVar;
global ArrayL;
#
set Sel [.$Win.lBox curselection];
if {$Sel ne {} } \
{set Got [.$Win.lBox get $Sel];
set TransferVar $ArrayL($Got);
tk_dialog .$Win.d {Acknowledgement of Selection} \
"You chose $Got" {} 0 {Dismiss};
doIt;
}
}
#
set Fglob [file normalize [glob -nocomplain -dir $Dir *.xbm *.XBM]];
#
if { [llength $Fglob] > 0 } \
{ set Fglob [lsort $Fglob];
foreach {f} "$Fglob" \
{ set Ftail [file tail $f];
append Flist "$Ftail\n";
set ArrayL($Ftail) $f;
}
} \
else { set Flist {(none found)}; }
#
foreach f "$Flist" { .$Win.lBox insert end $f; };
#
bind .$Win.lBox <<ListboxSelect>> "makeMainWindowSel $Win;";
}
proc doIt {} \
{ global TransferVar;
tk_messageBox -icon info -type ok -title "New Application Called" \
-message "Now processing $TransferVar";
};
#
# Runtime:
#
array set XBM_Array [list];
#
makeMainWindow x XBM_Array;
#
# End of script.
======================= Lab04 Step 6:
(same icon widget)
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a GUI-based icon viewer.
###########################################################################
#
wm title . {Icon Viewer};
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
#
# ------------------------------------------------------------------
# This proc runs the [File...] popup [Choose Directory].
# It has to account for possible dialog [Cancel]:
proc doChooseDir { ListWin } \
{
global Dir;
set Dir [tk_chooseDirectory];
if { $Dir eq "" } { set Dir [pwd]; }
#
makeMainWindowListFiles $ListWin $Dir;
}
#
# ------------------------------------------------------------------
# This proc presents the popup menu:
proc doPopFil {ListWin PopWin} \
{
if { [winfo exists .$PopWin] } { destroy .$PopWin; }
set m [menu .$PopWin -tearoff 0 -disabledforeground black];
$m add command -label {Filesystem Access} -back green -state disabled;
$m add command -command "doChooseDir $ListWin" -label {Choose Directory...};
$m add command -command "exit;" -label {Exit};
tk_popup .$PopWin 200 220;
bind .$PopWin <1> "tk_popup .$PopWin 200 220";
}
#
proc makeMainWindow { Win } \
{
global XBM_Array;
global Dir;
#
set Dir [pwd];
#
set HelpV {Choose a directory to open using the [File...] menu. };
append HelpV {All image (xbm) files in the directory will be };
append HelpV {displayed in the listbox to the right. };
append HelpV {You then may use the [View Mode...] menu either };
append HelpV {to see the file size of the image, the dimensions };
append HelpV {of the image, or the image itself.};
#
frame .$Win -background {light goldenrod};
label .$Win.lViewBut -text {View Mode...} -bg pink -fg black;
label .$Win.lMesgBut -text {(file attributes here)} -bg white -fg black;
label .$Win.lDir -textvariable Dir -wrap {20 c} -bg grey90;
label .$Win.lMsg -text $HelpV -wraplength {8 c} -bg cornsilk;
listbox .$Win.lBox -width 20 -height 6 -bg {light green} -fg black;
#was: label .$Win.lFileBut -text {File...} -bg green -fg black;
# We need both a new window path for the popup, and the main window:
set FileBut [button .$Win.lFileBut -text {File...} -bg green \
-fg black -font {-size 14} -bd 6 -command "doPopFil $Win popWin;"];
#
grid configure .$Win -row 1 -columnspan 3;
grid configure $FileBut -row 2 -column 0 -padx {0.1c};
grid configure .$Win.lViewBut -row 2 -column 1 -padx {0.1c};
grid configure .$Win.lMesgBut -row 2 -column 2 -columnspan 2 -sticky {e w};
grid configure .$Win.lDir -row 3 -columnspan 3 -sticky {e w};
grid configure .$Win.lMsg -row 4 -column 1;
grid configure .$Win.lBox -row 4 -column 2;
#
proc makeMainWindowSel { Win } \
{
global TransferVar;
global XBM_Array;
#
set Sel [.$Win.lBox curselection];
if {$Sel ne {} } \
{set Got [.$Win.lBox get $Sel];
set TransferVar $XBM_Array($Got);
tk_dialog .$Win.d {Acknowledgement of Selection} \
"You chose $Got" {} 0 {Dismiss};
doIt;
}
}
#
# Inline commands converted to proc to call from [File...] popup:
proc makeMainWindowListFiles { Win Dir } \
{
global XBM_Array;
set Fglob [file normalize [glob -nocomplain -dir $Dir *.xbm *.XBM]];
#
if { [llength $Fglob] > 0 } \
{ set Fglob [lsort $Fglob];
foreach {f} "$Fglob" \
{ set Ftail [file tail $f];
append Flist "$Ftail\n";
set XBM_Array($Ftail) $f;
}
} \
else { set Flist {(none)}; }
#
# Clear previous items, if any:
.$Win.lBox delete 0 end;
# Add new items:
foreach f "$Flist" { .$Win.lBox insert end $f; };
}
bind .$Win.lBox <<ListboxSelect>> "makeMainWindowSel $Win;";
}
# End makeMainWindow().
#
proc doIt {} \
{ global TransferVar;
tk_messageBox -icon info -type ok -title "New Application Called" \
-message "Now processing $TransferVar";
};
#
# Runtime:
#
array set XBM_Array [list];
#
makeMainWindow x;
#
# End of script.
======================= Lab04 Step 7:
(same icon)
#!/bin/sh
# \
exec wish "$0" "$@"
###########################################################################
# This script creates a GUI-based icon viewer.
###########################################################################
# Global variables used:
# Version Version number of this script (displayed in banner).
# Dir Current directory chosen by the user.
# XBM_Array Array holding the items displayed in the listbox.
# XBM_Choice Was named $TransferVar. Variable holding the current (one)
# selected listbox item.
# XBM_Txt Variable holding the file attribute displayed text.
# ------------------------------------------------------------------
# Maintenance Log (add new entries at top; bump version):
# -----------+-----+--------------------------------------------------
# Date | Who | Comment
# -----------+-----+--------------------------------------------------
set Version 1.1;
# -----------+-----+--------------------------------------------------
# 2009-05-20 | jmw | v. 1.1 fixed doFileSize() & doImgSize() output
# | | formats.
# -----------+-----+--------------------------------------------------
# 2006-11-12 | jmw | v. 1.0 implemented for Step 7 of Lab 4.
# -----------+-----+--------------------------------------------------
# End Maintenance log; begin script:
####################################################################
#
wm title . " Icon Viewer v. $Version ";
wm iconbitmap . @Tk.xbm;
wm geometry . =+150+150;
####################################################################
#
# ------------------------------------------------------------------
# This proc runs the [File/Choose Directory] menu choice.
# It has to account for possible dialog [Cancel]:
proc doChooseDir { ListWin } \
{
global Dir;
set Dir [tk_chooseDirectory];
if { $Dir eq "" } { set Dir [pwd]; }
#
makeMainWindowListFiles $ListWin $Dir;
}
#
# ------------------------------------------------------------------
# This proc presents the [File...] popup menu:
proc doPopFil {ListWin PopWin} \
{
if { [winfo exists .$PopWin] } { destroy .$PopWin; }
set m [menu .$PopWin -tearoff 0 -disabledforeground black];
$m add command -label {Filesystem Access} -back green -state disabled;
$m add command -command "doChooseDir $ListWin" -label {Choose Directory...};
$m add command -command "exit;" -label {Exit};
tk_popup .$PopWin 200 220;
bind .$PopWin <1> "tk_popup .$PopWin 200 220";
}
#
####################################################################
#
# ------------------------------------------------------------------
# This proc runs the [View Mode/Display Image] menu choice.
# It is a little complicated because of the need to ensure
# unique window paths for any number of images, and unique
# image names.
#
proc doImgDisplay {} \
{
global XBM_Choice;
if { $XBM_Choice eq "" || [file tail $XBM_Choice] eq {none} } \
{ tk_messageBox -title {ERROR: No Image Selected} -type ok -icon error \
-message "Select a directory and then an icon file from the list.";
return -1;
}
#
set ImgTail [file tail $XBM_Choice];
# Fix the path so it will be a legal window name:
set ImgName [regsub -all {[^A-Za-z0-9]} "$XBM_Choice" "x"];
# Change the fixed image name to a window path:
set ImgWin ".z$ImgName";
#
image create bitmap $ImgName -file "$XBM_Choice" -fore {dark green} -back white;
#
if { [winfo exists $ImgWin] } { destroy $ImgWin; }; # Just in case.
#
set t [toplevel $ImgWin]
wm title $t $ImgTail;
set L [label $t.l -image $ImgName -compound bottom \
-text "Image in \[$ImgTail\]" -font {-size 14}];
grid $L;
}
#
# ------------------------------------------------------------------
# This proc runs the [View Mode/Image Geometry] menu choice.
#
proc doImgSize {} \
{
global XBM_Choice;
global XBM_Txt;
#
if { $XBM_Choice eq "" || [file tail $XBM_Choice] eq {none} } \
{ set Msg {(no xbm file selected)}; } \
else { if { [file exists $XBM_Choice] } \
{
if { [catch {set Fr [open $XBM_Choice r]} ErrV]==0 } \
{
# Allow for some comment lines:
set N 1; set x 0; set y 0;
while { $N < 10 } \
{
gets $Fr Line;
if { [eof $Fr] || ($x>0 && $y>0) } break;
#
if { [regexp {#define +.*_width} $Line] } \
{ set x [lindex $Line 2]; }
if { [regexp {#define +.*_height} $Line] } \
{ set y [lindex $Line 2]; }
}
close $Fr;
set Msg "(w x h) = $x x $y pixels";
} \
else { tk_messageBox -title {File read ERROR} -icon error \
-type ok -message "doImgSize(): ERROR: cant read file
\[$XBM_Choice\]
$ErrV";
return -1;
}
} \
else { set Msg "ERROR: cant find [file tail $XBM_Choice]"; }
}
#
set XBM_Txt $Msg;
}
#
# ------------------------------------------------------------------
# This proc runs the [View Mode/Image File Size] menu choice.
#
proc doFileSize {} \
{
global XBM_Choice;
global XBM_Txt;
#
if { $XBM_Choice eq "" || [file tail $XBM_Choice] eq {none} } \
{ set Msg {(no xbm file selected)}; } \
else { if { [file exists $XBM_Choice] } \
{ set Msg "[file size $XBM_Choice] bytes"; } \
else { set Msg "ERROR: cant find [file tail $XBM_Choice]"; }
}
#
set XBM_Txt $Msg;
}
#
# ------------------------------------------------------------------
# This proc presents the [View Mode...] popup menu:
proc doPopView {AttrWin PopWin} \
{
if { [winfo exists .$PopWin] } { destroy .$PopWin; }
set m [menu .$PopWin -tearoff 0 -disabledforeground black];
$m add command -label {Image View Mode} -back pink -state disabled;
$m add command -command "doFileSize" -label {Image File Size};
$m add command -command "doImgSize" -label {Image Geometry};
$m add command -command "doImgDisplay" -label {Display Image};
tk_popup .$PopWin 200 220;
bind .$PopWin <1> "tk_popup .$PopWin 200 220";
}
#
####################################################################
# This proc controls the main GUI window and includes listbox-handling
# procs:
proc makeMainWindow { Win } \
{
global XBM_Array;
global XBM_Txt; set XBM_Txt {(file attributes here)};
global Dir;
#
set Dir [pwd];
#
set HelpV {Choose a directory to open using the [File...] menu. };
append HelpV {All image (xbm) files in the directory will be };
append HelpV {displayed in the listbox to the right. };
append HelpV {You then may use the [View Mode...] menu either };
append HelpV {to see the file size of the image, the dimensions };
append HelpV {of the image, or the image itself.};
#
frame .$Win -background {light goldenrod};
label .$Win.lAtts -textvar XBM_Txt -bg white -fg black;
label .$Win.lDir -textvar Dir -wrap {20 c} -anchor w -justify left -bg grey90;
label .$Win.lHelp -text $HelpV -wrap { 8 c} -justify left -bg cornsilk;
listbox .$Win.lBox -width 20 -height 6 -bg {light green} -fg black;
set ViewBut [button .$Win.lViewBut -text {View Mode} -bg pink \
-fg black -font {-size 14} -bd 6 -command "doPopView Win.lAtts popWin;"];
set FileBut [button .$Win.lFileBut -text {File...} -bg green \
-fg black -font {-size 14} -bd 6 -command "doPopFil $Win popWin;"];
#
grid configure .$Win -row 1 -columnspan 3;
grid configure $FileBut -row 2 -column 0 -padx {0.1c};
grid configure $ViewBut -row 2 -column 1 -padx {0.1c};
grid configure .$Win.lAtts -row 2 -column 2 -columnspan 2 -sticky {e w};
grid configure .$Win.lDir -row 3 -column 0 -columnspan 3 -sticky {e w};
grid configure .$Win.lHelp -row 4 -column 1;
grid configure .$Win.lBox -row 4 -column 2;
#
proc makeMainWindowSel { Win } \
{global XBM_Choice;
global XBM_Array;
#
# Leave the "none" possibility to the callee:
set Sel [.$Win.lBox curselection];
if {$Sel ne {} } \
{set Got [.$Win.lBox get $Sel];
set XBM_Choice $XBM_Array($Got);
}
}
#
proc makeMainWindowListFiles { Win Dir } \
{global XBM_Array;
set Fglob [glob -nocomplain -dir $Dir *.xbm *.XBM];
#
array unset XBM_Array;
if { [llength $Fglob] > 0 } \
{ set Fglob [lsort -unique $Fglob];
foreach {f} "$Fglob" \
{ set Ftail [file tail $f];
append Flist "$Ftail\n";
set XBM_Array($Ftail) $f;
}
} \
else { array set XBM_Array [list none none]; }
#
# Clear previous items, if any:
.$Win.lBox delete 0 end;
# Add new items:
foreach f "[array names XBM_Array]" { .$Win.lBox insert end $f; };
}
bind .$Win.lBox <<ListboxSelect>> "makeMainWindowSel $Win;";
}
# End makeMainWindow().
########################################################################
# Runtime:
########################################################################
#
array set XBM_Array [list];
set XBM_Choice {};
#
makeMainWindow x;
#
# End of script.
(end of lab answers)

J. M. Williams

2009-05-22

Tk Fundamentals

1

Table of Contents
Table of Contents ............................................................................................................ 1 Agenda ............................................................................................................................ 3
Prerequisites .......................................................................................................................3 Course Organization ...........................................................................................................3 Topics...................................................................................................................................4 Schedule ..............................................................................................................................4

References....................................................................................................................... 5 Introduction .................................................................................................................... 5
Relation of Tk to TcL ...........................................................................................................6 Relation of Tk to X...............................................................................................................6 Tk Naming Conventions......................................................................................................6 Elementary GUI Objects .....................................................................................................7 window.....................................................................................................................7 image .......................................................................................................................8 bitmap......................................................................................................................8 palette......................................................................................................................10 text...........................................................................................................................11 widget ......................................................................................................................12 Window Systems and Controls............................................................................................13 tk Command ............................................................................................................13 wm Command ..........................................................................................................14 winfo Command.......................................................................................................17 Packer Geometry Manager ......................................................................................18 Gridder Geometry Manager ....................................................................................19 Placer Geometry Manager.......................................................................................20 Window raise and lower Commands .......................................................................24 wish: The Windowing Shell ................................................................................................25 Running Tk from the OS Command Line ...............................................................26 bitmap and mtpaint utilities ...............................................................................................27 bitmap......................................................................................................................27 mtpaint ....................................................................................................................28

Lab 1: A Tk label Widget and Icons ............................................................................... 29 Text and Font Manipulation ........................................................................................... 30
Font Selection......................................................................................................................30 Text I/O................................................................................................................................31 Widget Execution by Window Path .........................................................................31 The text Widget .......................................................................................................31 Character Indexing in a text Widget ......................................................................34 More text Modification by Script.........................................................................................35 Window Destroy and Replace..................................................................................37 Packed Append of text Value ..................................................................................38 Packed Supplement of text Value ...........................................................................38 Order of Creation Effect ..........................................................................................39 Event Binding......................................................................................................................41 Using global in the label Widget .............................................................................41 The bind Command and a Simple entry .................................................................42 Interactive Text Entry and Validation ...............................................................................45 entry: bind Keywords .............................................................................................45 entry: Window focus ...............................................................................................45 entry: Validation ....................................................................................................46

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->