Casual Scripting for the Non-Programmer

This document is (c) copyright Othniel Graichen 2001 and licensed for use under the GPL.
Permission is granted to reproduce this document as is for non-commercial uses.
Formatted for a display resolution of 1024x768 or larger. View the Top 10 reasons to use Tcl/Tk.

Tcl/Tk is the user-friendly way for anyone to produce GUI "windows" applications. A Tcl script does not need to be compiled to be used yet provides much more power than a "bat" file or shell script. Tcl is an open source language designed not as a replacement for Java or C++ but as a scripting language to "glue" software components written in those languages together in a flexible reusable framework. Its' simple rules allow anyone to create a functional GUI which will work in any variant of Microsoft Windows, Linux or even within a web browser. The Tool Command Language, Tcl, and its associated graphical toolkit, Tk are used to implement the examples in this guide. No formal training in Software Engineering or Computer Science is required nor is an advanced computer background assumed. To complete this exercise you will only need access to an MS Windows 95, 98, ME, NT or Linux computer system. After completion of the exercises, the reader will be able to produce medium complexity cross-platform windowed applications and will have an appreciation of the power and flexibility of Tcl/Tk. Links to other free resources regarding Tcl/Tk are provided at the end of this document. Typical time to complete this exercise: 2 hours.
Step 1: Installation of Tcl/Tk.

Linux Mandrake and Redhat users should already have it in their base install. Verify this with the command "rpm -q tcl tk". If not, install these packages from your distribution CD or download from MS Windows users will need to download and install the Cygwin DLL package from Click on the icon in the top-right of this web page to download and run the setup program. The current version of Cygwin is 1.3.2, released on 21 May 2001. Choose the installation defaults.

Step 2: Starting the Windowing Shell, wish

Skip to step 3 once you have started the windowing shell, wish. Linux users: first start Xwindows with Gnome, KDE, or your choice of desktop, and then execute "wish80 &". You may type this from an xterm or konsole window. In KDE, you may also press alt-F2, to start a program by name. Windows users: first start Cygwin's bash by double clicking the Cygwin desktop icon which was installed in step 1. To run the windowing shell, type "cygwish80 &" at the bash prompt. You may also use the Start...Run command and browse to C:\cygwin\bin\cygwish80.exe and run it directly without first starting Cygwin. As an aside, Cygwin also provides a completely open (and free!) implementation of Xwindows XFree86 for MS Windows. I've tried it and it works great. Cygwin even comes with OpenSSH 2.9p2 which supports protocols 1.5 and 2.0. [translation: I've deinstalled Hummingbird Exceed, puTTY and Reflection X from my Win98 box]!

Step 3: Practicing WISH

At this point you should see (at least) two windows on your desktop, a Tcl console and one labelled WISH. If not, please return to step 2. The remainder of the discussion will not distinguish between Windows and Linux environments, but we need to learn how to restart the windowing shell, WISH, on our chosen platform. Close the wish window. Notice how the console window disappears also. Do you remember how to restart wish? See step 2 for details. Windows users note that you cannot start cygwish80 from the Run menu without giving the entire path, but you can execute "cygwish80 &" from the bash prompt. FYI -- Cygwin gives you a bash prompt [and vi!] from within MS Windows.

Step 4: Hello, World!

Let's make a simple window which will have a button labeled "Hello, World!" that terminates and disappears when you push the button. Cut the following two lines and paste them into your Tcl Console window.

button .b -text "Hello, World!" -command { exit } pack .b What did we do? We created a button called .b, gave it a label, defined an action to perform when it is pressed and attached it to a window(line #2). In Tcl/Tk, there are 3 ways to connect widgets (such as buttons) to the display window: pack, place and grid. Each is useful for different situations, pack is just the easiest to use. Click on the button. Hey! It worked! Your first Tcl program was a success. It exited... like we told it. Now we have to start wish again (make another wish?) Let's do this exercise again, pasting the lines into the console window one at a time. Notice how the interpreter tells you that the widget .b was successfully created. All Tcl widget names begin with a dot. Notice that the wish window does not update until you "pack" a widget onto it. Click the button. Scripting in Tcl is THAT easy.
Step 5: Source

Notice the 1st choice under the File menu of the Tcl Console program. "Source" is the Tcl word to read in a script file. In a sense it is like the Load menu choice in many programs, but does not remove the previous file which you will experience should you ever source two files (or the same file twice). Cut the following 7 lines and create a file called hello.tcl. Use your multitasking prowess to launch notepad or vi without closing wish. Note that the & lets you run commands simultaneously from the bash prompt. If you didn't use &, the program started by bash must finish before you would be prompted to start another one.

# # Simple Hello world script. # button .b -text "Hello, World!" -command { exit } pack .b # hello.tcl You should use the cat command to verify the contents of the file you created. In what directory did you create this file? pwd will tell you the current directory. Now select File...Source from the Tcl console window to load your script. Click the button. Use the command recall button in bash (the up arrow) to restart wish. Source hello.tcl twice in a row. Error messages are displayed in the console window in red. Did you understand the message? At the top of our script file we typically write #!/usr/local/bin/wish8.0

to indicate the name of the script language processor. This allows others to see just the wish window. We will use the Tcl Console to develop and test our scripts, but you will be pleased to know that the final product will not need a console window. Only the graphical window will be seen.

Step 6: Font Control

Create a file called fontopt.tcl containing the following lines:

# Create a Times font. font create timesfont -family Times -size 12 -weight bold -slant italic # Create an Helvetica font. font create helvfont -family Helvetica -size 16 -weight normal -slant roman -underline true # Create a Courier font. font create courierfont -family Courier -size 20 -weight bold -slant italic -overstrike true # Use fonts in button widgets. button .times -text "Times Font" -font timesfont button .helv -text "Helvetica Font" -font helvfont button .cour -text "Courier Font" -font courierfont pack .times pack .helv pack .cour # fontopts.tcl

Each of the lines beginning with the word font must appear on a single line in the file. If these are broken by cutting and pasting operation you must mark each line break with a backslash continuation character. You may add multiple line continuation characters to suit your style/taste. Source the resulting file into wish. Notice this time that the buttons don't do anything. To exit this program you will need to use the X on the window.

Step 7: Create a file called b1.tcl containing the following lines. # .b1 widget example # button .b1 -text "Push me" -command { puts ouch } pack .b1 # b1.tcl

Source it into wish. Push the button. Notice that the program does not exit. The puts (put string) allows one to trace the operation of the script using the console window while developing the application.

Step 8: Create a file called b2.tcl containing the following lines. set count 0 set widget_text "Click to Reset" button .textvar -textvariable widget_text \ -command { set count 0 } pack .textvar button .count -textvariable count \ -command incr_count pack .count proc incr_count { } { global count set count [expr $count + 1] } # b2.tcl

Source the file into wish. Push the lower button. Push it again several times. Push the top button. Push the bottom button again. This program is responding to your whims. Notice that count is a variable while .count is a widget. Notice the mandatory use of the line continuation character in the definition of .count. Notice that -command can be used with the name of a procedure instead of an in-line bracketed script. Notice also that line continuation characters are not required in command scripts, the lists enclosed by brackets. Read the entire script. How do you assign a variable in Tcl? Do you use parentheses to compute a simple mathematical operation?

Notice that pack is used in the script twice. What would happen if you changed the script to read "pack .textvar .count" on a single line? When you have absorbed this script fully, let's examine what other widgets exist in Tk.

Step 9: Tk widgets
We have used the word, Widget, to refer to visual windowing components. This is not just slang, it is the official terminology in Tk (jargon) for a windowing gadget.
Comprehensive list of Tk WidgetsCommon Widget Options
Widget Name
How it is used.
executes Tcl code when pushed
an all points addressable graphical drawing area
an independent On/Off button
to allow text-entry by user
container object for composing/displaying other widgets
to display text messages
a scrolled list
Hierarchical chooser
Accelerator to pull down Menu
Multiline label
Set of related on/off buttons
Sliding selection
Associated with display of another widget
popup dialog or application window
Widget Option SyntaxWhat the option accomplishes
-activebackground color Background color when active
-activeborderwidth width Width of border when active
-activeforeground color Foreground color when active
-anchor anchor_pos Position info relative to: n ne nw s se sw e w center
-background color Background color when normal
-bg color same as above
-bitmap bitmap Load pattern: error gray12 gray25 gray50 gray75 hourglass info questhead question warning @filename
-borderwidth width Width of border when normal
-bd width same as above
-command tcl_script Executes tcl_script when invoked
-cursor cursor Mouse cursor to display when mouse in this widget
-disabledforeground color Foreground color when disabled
-exportselection state
-font fontname Use fontname for text style
-foreground color Foreground when normal
-fg color Same as above
-geometry widthxheight Can sets horizontal (& optionally vertical) widget size
-height value Set vertical widget size
-highlightcolor color Color to use for widget indicating keyboard focus rectangle
-highlightthickness size Width of highlight area rectangle
-image image Graphic to display in widget
-insertbackground color Background color of insertion cursor
-insertofftime milliseconds Blink 'off' time
-insertontime milliseconds Blink 'on' time
-insertwidth size Width of insertion cursor
-jump on_or_off Delay scrollbar updating until mouse button is released
-justify justification Multiline justification: left right center
-orient orientation horizontal vertical
-padx pad Horizontal padding
-pady pad Vertical padding
-relief relief 3D bevel: flat groove raised ridge solid sunken
-repeatdelay milliseconds Time to first repeat
-repeatinterval milliseconds Time between repeats
-selectbackground color Background when selected
-selectborderwidth width Border width when selected
-setgrid on_or_off Resizing grid state
-state state Set widget to: normal disabled active
-text string Display text string
-textvariable varname Display text variable
-troughcolor color
-underline which_char Which character position in string to underline
-width width Sets horizontal widget size
-wraplength length Word wrapping maximum string length
-xscrollcommand prefix Prefix for command to communicate with horiz scrollbars
-yscrollcommand prefix Prefix for command to communicate with vert scrollbars

Review the information regarding scale. We'll be using it in the next exercise.
Step 10: Slider

Create a file called rgbscale.tcl containing the following lines.

# # RGB color-setting scale. # # Changes background color used by button. proc modify_color { which_color value } { global color red green blue switch $which_color { red { set red $value } green { set green $value } blue { set blue $value } } set color [format "#%2.2x%2.2x%2.2x" \ $red $green $blue] # Change background color of button. .color configure -background $color } global color red green blue set color "Select a color" set red 75 set green 75 set blue 75 button .color -textvariable color -anchor w \ -borderwidth 10 \ -command { puts "Color is: [.color cget -text]" } scale .red -from 0 -to 255 -label "Red" \ -length 300 -orient horizontal \ -command "modify_color red" \ -tickinterval 50 .red set $red scale .green -from 0 -to 255 -label "Green" \ -length 300 -orient horizontal \ -command "modify_color green" \ -tickinterval 50 .green set $green scale .blue -from 0 -to 255 -label "Blue" \ -length 300 -orient horizontal \ -command "modify_color blue" \ -tickinterval 50 .blue set $blue button .exit -text "Exit" -command { puts "Color is: [.color cget -text]" ; exit } pack .color .red .green .blue .exit # rgbscale.tcl

Source it into wish. We'll study it after we see what it does. Choose a color by sliding the scales. Notice that the button background is modified by the modify_color procedure. When you click the exit button (but not the X on the window), the program prints "Color is: <hex color string>" and terminates. FYI, HTML documents use the color number in the specified format, so this is a nice tool for picking exotic background and foreground colors for your web pages. --end of lesson--

What you have seen here is not programming. This is not computer code. This is a Tcl script interacting with Tk widgets. It is a software component glue with which (prior to Tcl) software developers have been dealing with in so much detail as to be unproductive. Do you know how long it would take a Microsoft C++ or Java programmer to write these kind of windows? The answer, my friend, is TOO LONG! Do you know how much studying, experience and skill it takes to even be able to produce such an application? WAY TOO MUCH! There are to many details. Too many things can go wrong! Even though I am a degreed computer scientist I recognize that using the Microsoft Foundation Classes and the object oriented C++ language to produce windows apps is JUST TOO MUCH PAIN. I previously did Visual Basic programming for a year and a half before getting into Linux/open source software and have since learned Perl, Javascript, PHP and HTML. These scripting languages provide so much more power, I will never go back.

Read more about it in John Ousterhout's IEEE article. I hope you are as excited about the possibilities as I am. This cool language is cross-platform meaning the same program can run on Windows, Linux, Macintosh or even in a browser window.
Want to play an on-line TCL version of Tetris It requires a Tcl plug-in for your browser.
A more full-featured version of the RGB color picker is located here.