![]() |
Tcl/Tk GUI Programming
|
| Course content | Enter chat room | Send email
to mailing list |
Check calendar |
In memory of Linda. Worldwide Cancer
sites here.
Canadian Cancer donations here.
In this lesson we are going to learn how to work with the text widget. The text widget will be essential for our final project in this course. It is also one of the most "feature rich" and useful of the Tcl/Tk widgets. In case you are wondering "exactly what is a text widget anyway" ... think of your text editor. The text widget is fully capable of being used as a text editor.
Unfortunately, we are only going to be able to scratch the surface of the capabilities offered by the text widget in this beginner level course.
We are also going to introduce our first Tcl/Tk dialog in this lesson. Although you may not know it you have already used dialogs lots of times in your computer already. Simply put a dialog is the name GUI designers gave to those small windows that pop up when you do things like opening a file, saving a file etc. A typical dialog asks you to supply input and won't let you do anything else with your computer until you have done so ... or hit the Cancel button to dismiss the window.
Before we begin the code for lesson #5, here is a possible solution
to part of the exercise we left you with in lesson #4.
#======================================== # main - entry point #======================================== #======================================== # explicitly setup our main window #======================================== wm geometry . 200x250+10+10 wm title . "lesson 4a" #======================================== # setup the frame stuff #======================================== destroy .myArea set f [frame .myArea -borderwidth 5 -background blue] pack $f -side top -expand true -fill both #======================================== # create a menubar #======================================== destroy .menubar menu .menubar . config -menu .menubar #======================================== # create a pull down menu with a label #======================================== set File [menu .menubar.mFile] .menubar add cascade -label File -menu .menubar.mFile #======================================== # add the Open menu item #======================================== $File add command -label Open #======================================== # add the Quit menu item #======================================== $File add command -label Quit -command exit |
Notice that the only thing we added was another "$File add command"
to give us the Open menu item. In this form the Open
menu item doesn't do anything just yet.
| Some of you may have noticed that if you made a mistake
in the code you could not get it running again because it kept complaining
about the menubar already defined.
If you recall back a couple of lessons we introduced our first computer bug about this very problem with the button widget. The solution here is the same as it was then: add a "destroy .menubar" line somewhere the main area of the program. |
Step 0: preparation for lesson#5 |
For those of you who took the time to complete the exercise in lesson#4 you should simply copy your work into this new folder and rename it "lesson5.tcl".
For those others who didn't have time to complete the exercise use your
text editor and enter the program shown above and save it as "lesson5.tcl".
Step 1: the text widget |
The first "enhancement" we are going to make to our little program is to add the text widget into our frame area.
Using your editor scroll down inside your new "lesson5.tcl" file until
you reach the "set f [ frame" statement. You are
going to insert the text widget lines between this statement and the "pack
$f" statement as illustrated with the code snip below.
set f [frame .myArea -borderwidth 5 -background blue] #======================================== # add the text widget #======================================== text $f.t -bd 2 -bg white -height 5 pack $f.t pack $f -side top -expand true -fill both |
When you run this program with "wish" a small white box should appear near the top of the blue frame area.
That wasn't that hard was it!
You now added a text widget to your program. Try typing something into the little white box that appears. You should be able to do many of the things you are familiar with in your text editor ... things like inserting, overwriting, hiliting, and deleting text.
It would be a subject for a more advanced course to look at all the things you can do with text inside a text widget. We will only be using a tiny fraction of that capability in this exercise.
But first let's not get too far ahead of ourselves and let's look at
the new statements that we have introduced.
| text $f.t -bd 2 -bg white -height 5 |
This statement begins with the widget invocation command "text". This says create me a "text" widget please. This is very similar to the command you used previously to create a button, menu or a frame.
The first argument is a little strange. It says we are going to name our new text widget as "$f.t". Recall that the "$" has special meaning in the Tcl/Tk language. It means substitute the value of the variable in my place. In this case that variable contains the "frame" widget itself.
What $f.t really means to us is simply that the text widget is going to be added as a "child" widget to the frame. Remember the hierarchy ... parent->child -> grandchild etc. Simply put the text widget is inside the frame.
The next argument is short for "border". It simply says leave 2 pixels of space all around the text widget as a border.
The next argument is short for "background". It simply says that we want the background of our text widget to be white.
The final argument says make this widget 5 lines high. In other words it will be big enough to store 5 lines of text.
There are many more arguments that can be used to set attributes of this text widget but the few we have chosen are sufficient for us in this course.
The other new statement:
| pack $f.t |
we have encountered before. For our purposes
it says "render our widget named $f.t visible please".
Step 2: adding some text |
Our text widget would not be of much use if we could not add lines of text to it from within our little program.
Using your text editor once again add the following statements just
after the pack $f statement above.
#========================== # add a line of text #========================== $f.t insert end "abc" tag0 |
When you run your newest version of our little program now the letters "abc" appear in the first line of the text box.
Let's examine what the new statement actually does.
This statement is a lot like the "configure" statement we used in the past with the menubar. In English it would read something like:
"to the end of the visible text in the text box called $f.t insert a new string of text containing "abc" and mark that string with an invisible label called tag0"
To help illustrate how this insert statement works try adding another
insert line immediately after this one like.
| $f.t insert end "def" tag1 |
Notice how the string is now "abcdef". The "insert" simply appended the new text to the end of what was already there.
How do we put "def" on the line below. The easiest way is to add a special character to the end of the first line. This is the same character that would be inserted in your text editor when you hit the "Enter" key on your keyboard. In deference to the days when this key actually did mechanical things on a typewriter it is called the "carriage return" character. In word processors and in text editors it is invisible on the screen but actually exists in the file. That is why if you hit "backspace" at the beginning of a line it suddenly gets merged to the end of the previous line. Reason: you just deleted that invisible "carriage return" character that forced the line separation. In Tcl/Tk this "carriage return" is represented by "\n".
So if we were to modify our "abc" line to look like
| $f.t insert end "abc\n" tag0 |
we would force the "def" to go to the next line.
Now try positioning your cursor at the beginning of the "def" line in the text box and hit "backspace" on you keyboard. Now hit "Enter" on your keyboard. You should be able to move def to end of the abc line or back to the second line.
Invisible characters are a huge part of every word processor program
you have ever used. They control everything from line
spacing to font type and point size.
Step 3: make the Open menu do something |
Recall in lesson#3 we introduced the very powerful concept of procedures. Procedures are used to add new statements to the Tcl/Tk language. In fact computer languages would be next to useless without that ability.
We are going to add a procedure which will be executed when we select the Open button in the menu.
At the top of your lesson5.tcl file add the following few statements
#==========================
# openFile - entry point
#==========================
proc openFile { } {
set fn "openFile"
puts stdout [format "%s: ding" $fn]
} ;# end openFile
|
When you run your program now ... absolutely nothing should change.
OK ... where is he going with this now you ask !!!
What happens if we enhance our Open menu item line to look like
| $File add command -label Open -command openFile |
Now what happens when you run your program and select the "Open" menu item under the "File" menu.
For those of you sceptics ... take a look into your wish console window. You should see the result of that "puts stdout" message on that window:
openFile: dingFor those of you who don't understand how this happened ... review your previous lessons. If you are still confused by all means take the opportunity to ask your fellow students and facilitators in the chat session or mailing list. There is no such thing in this level of course as a "dumb question".
Let's move on and introduce our first dialog.
Step 4: the file open dialog |
Inside the procedure "openFile" add the following statement (just after
the puts stdout ding line is as good as any place).
| set myFile [tk_getOpenFile] |
Now run your program.
![]() |
WOW. This is really starting to look like a "real" program. |
All the "real" programs you have been using on your computer all along are nothing more than more complicated versions of this little program you have written.
To use the writing analogy: the "real" programs are full novels ...
you have learned how to write a paragraph. All
that is required to produce a full novel is to connect lots of paragraphs
together into a cohesive story.
Step 5: final listing |
The full listing of the source code for lesson #5 is below.
#==========================
# openFile - entry point
#==========================
proc openFile { } {
set fn "openFile"
puts stdout [format "%s: ding" $fn]
set myFile [tk_getOpenFile]
} ;# end openFile
#========================================
# main - entry point
#========================================
#========================================
# explicitly setup our main window
#========================================
wm geometry . 200x250+10+10
wm title . "lesson 5"
#========================================
# setup the frame stuff
#========================================
destroy .myArea
set f [frame .myArea -borderwidth 5 -background blue]
#========================================
# add the text widget
#========================================
text $f.t -bd 2 -bg white -height 5
pack $f.t
pack $f -side top -expand true -fill both
#==========================
# add a line of text
#==========================
$f.t insert end "abc\n" tag0
$f.t insert end "def" tag1
#========================================
# create a menubar
#========================================
destroy .menubar
menu .menubar
. config -menu .menubar
#========================================
# create a pull down menu with a label
#========================================
set File [menu .menubar.mFile]
.menubar add cascade -label File -menu .menubar.mFile
#========================================
# add the Open menu item
#========================================
$File add command -label Open -command openFile
#========================================
# add the menu item
#========================================
$File add command -label Quit -command exit
|
For those running PCWindows the result of running this program should be something like:
Summary |
You have been introduced to a bunch of new Tcl/Tk statements and constructs in this lesson. Let's review:
Exercises |
End of Lesson 5.