Journal Articles
Browse in : |
All
> Journals
> CVu
> 172
(12)
All > Topics > Programming (877) Any of these categories - All of these categories |
Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.
Title: Introduction to Tcl/Tk
Author: Administrator
Date: 03 April 2005 13:16:11 +01:00 or Sun, 03 April 2005 13:16:11 +01:00
Summary:
Body:
There are lots of different ways to program a computer.
Computers are essentially very stupid.
Even the fastest desktop computers can only understand a hundred or so commands in their microprocessor "brains". These commands in and of themselves are very simple things like "add these two numbers", "compare these two values" or "fetch this value from memory". How then could computers possibly appear to be so "smart"?
The simple answer is that they are able to do lots of simple things extremely quickly. So quickly that the typical desktop computer can easily do several million such commands every second.
While some people still occasionally program computers by setting up these millions of microprocessor commands directly by hand, you can appreciate that writing something like a computer game or wordprocessing program in this manner would be extremely laborious and tedious. You see humans and computers don't speak the same language.
To help with this immense problem associated with programming a computer, people began to invent tools called "programming languages" and other tools to translate these "human programming languages" into the language that the microprocessor understands.
There are many programming languages used to program modern computers. The one we are going to speak about in this article goes by the name Tcl/Tk which stands for "Tool Control Language with a Tool Kit". It is affectionately known by the 500000 or so users world wide by the name "tickle tee kay".
Tcl/Tk is a very good language to start to learn about computer programming because:
-
the language and associated tools are open sourced and hence free
-
the language has been implemented for almost every conceivable computer type (IBM clones, Macintosh, Linux to name but a few)
-
it has been around for over 10 years and is widely used in the real world for everything from eCommerce on webpages to quality control in microprocessor factories
-
it is a very simple language without too many quirky syntax issues
The amount of work you will need to do to get set up to write programs in Tcl/Tk will depend on the type of computer you are using.
For Linux users you are likely not going to have to do anything because Tcl/Tk tools are included with most Linux distributions including the very popular Knoppix live CD version. Microsoft Windows or Macintosh users, however are going to have to download and install the Tcl/Tk tools from the Internet.
Tcl/Tk is maintained today by a company which goes by the name Active State (http://tcl.activestate.com). All the basic tools you will need to start exploring Tcl/Tk as a programming language are freely available for download at the Active State website following the link above.
The only other tool you will require for the code examples in this series of articles is a very simple text editor.
Once again Linux and Mac users will have plenty to chose from. For Windows users the simplest chose will be Wordpad. The important thing to note is that you'll need a text editor and not a word processor, as the latter adds lots of hidden characters into the resulting file to control fonts and formatting.
At this point you should have the Tcl/Tk tools set installed on your machine.
You must be anxious to write your very first computer program.
We are going to be using a feature of the Tcl/Tk tools that are not available in every computer language: the ability for the program to be written and run interactively. In other words we are going to type something and then immediately run the program. This mode of programming is often called "interpretive mode" and it is a great way to test out simple programs and programming constructs.
The instructions below will describe how to write this program using Windows. For others the procedure will be similar.
One of the tools you installed on your computer goes by the name wish. Which stands for window shell.
This should bring up two windows: one called Wish and the other, Console. The console window will usually have a % character (this may vary though) on the left hand side of the first line. This character is the prompt.
This program is going to contain the following line (to be typed after the prompt)
puts stdout "hi Bob"
If you end the line by hitting the <enter> key you should see the string inside the "" appear on the line below
Congratulations!
You have just written your very first Tcl/Tk program!
Feel free to experiment with the words inside the "" ... perhaps by inserting your name.
Notice that you can use the "up arrow" key to recall the previous line and make changes by using the "left or right arrow" to edit the line.
Tcl/Tk is a particularly simple language and every statement will always have the same elements:
command arg1 arg2 arg3 ...
In our little programming example the command was puts. This command is used to "put things" or "display things".
The first argument in our example was: stdout
For us stdout will always mean the console screen.
One thing you will find is that programmers in general are a lazy lot. The laziest programmers of the bunch are those who write operating systems or programming languages. That is why we end up often with cryptic commands like puts and clipped arguments like stdout ... it saves typing.
The second argument in our example was: "hi Bob"
The "" were used to group these words into a single argument ... otherwise the wish program would have taken "hi" as the second argument and "Bob" as the third.
The puts command would only be expecting 2 arguments and our little program would not have worked very well. This concept of grouping is in almost every computer language ... they don't always use "" as the group markers, however. The series of words inside the "" are often referred to as a "string" ... which is short for "string of characters".
When computers were first invented the way you interacted with them was far from friendly.
Humans like colour and graphics.
Computers find those things a big pain in the chips.
The simple one line program above was an example of a command line or text based interface. The input was all done with the keyboard and the output was in the form of more text on the console.
To this day this remains one of the most economical ways to interact with a computer.
Many programmers prefer to type commands rather than use the mouse to click icons. Nonetheless, graphics and graphical user interfaces (or GUIs as they are called) are very common on modern computers.
Fortunately for us Tcl/Tk comes with very capable and powerful graphical "sidekick": Tk.
Tk looks at the graphical world as being composed sets of what it calls widgets. Like real world widgets, Tk widgets have a basic shape with a colour, texture, size etc.
The widget model is a good one for us as programmers because we don't have to concern ourselves with the thousands of details that go into teaching a computer how to draw buttons on the screen.
The Tk language looks after that for us. All we have to do is decide how our button is going to look.
-
How big it will be.
-
What colour it will be.
-
What shape it will be.
-
What text will appear inside the button.
These characteristics of a button are all modifiable from within our program. This gives us a very rich set of combinations of button attributes that we can use in our particular program.
Just as we did above for our text program we need to be running wish.
In the console window at the prompt you want to type the following line
button .hello -text "hi Bob" pack .hello
When you hit <enter> this time the wish window should change and a button should appear. The words "hi Bob" should appear on the face of the button.
Congratulations! You have written your very first graphical program.
Just to refresh our memory all Tcl/Tk statements are composed of:
command arg1 arg2 arg3 ...
In the first statement of our program the:
command = button arg1 = .hello arg2 = -text arg3 = "hi Bob"
The command button specifies the type of widget we want Tk to create for us.
arg1 specifies the name we wish to give to our newly created button.
The "." in front of the name is important.
We will describe this more fully shortly ... but for now think of the "." as standing for the top level window shell (wish) window.
.hello then means name the widget hello and put in into the toplevel wish window.
arg2 specifies one of the many attributes for this button that we want to set. In this case we want to set the text which will appear inside the button.
arg3 then specifies the actual text string that we want to place in the text attribute for our button called hello.
At this point we have only told Tk to create our button. We have not told Tk where to draw the button on our toplevel window. The second statement in our little program
pack .hello
tells Tk to draw our button widget called hello. When this statement gets executed our button magically appears on the wish window.
As with all programs, it is a good idea to save them. You do this as you would any text file, just following the time honoured protocol of adding .tk as the extension. When you come to reload the program, you should be able to run the program directly from your filemanager - or can you?
The wish program is complaining that window name hello already exists in parent.
The reason for this is that widgets stay around inside the wish program until we explicitly destroy them. Because we had already created the button called hello when we typed our program into the wish console by hand, we are being told that we can't create another button widget of the same name.
Don't worry about the word parent ... in computereeze windows that start from other windows are referred to as "children" and higher level windows as "parents". In this context "parent" simply refers to the environment in which you are running your program.
To fix our little bug we need to add another Tcl/Tk statement to the beginning of our computer program. Here is where the file comes in really handy. You need to return to your text editor program and load up the file where you stored your previous two statement program. You need to open a new line at the beginning of your file and insert the following statement.
destroy .hello
This tells the Tk program to get rid of the previous button widget named hello ... because we want to recreate it.
If you now save your file again and repeat the above File/Source procedure to run the program it should work like it did in step one. In fact you can repeat this over and over again and the program will always run.
Have some fun experimenting with different strings inside the double quotes ("") on the button line in your program. For those of you who are really ambitious try adding another attribute to the end of the button line which will set the button colour. The format for that attribute is:
-background red
As you may have gathered by now programming has a healthy dose of repetition involved.
In fact the sequence of steps that you have just been through is so repeated in every programming language that is often referred to as the "Programming Cycle".
While there are many books written on this subject and many opinions as to which variation of this cycle is best in large development projects ... we fortunately do not have to concern ourselves with anything but the basics. With our Tcl/Tk toolset our cycle consists of the following steps:
-
entering/changing lines of code via our text editor
-
saving those changes to a file
-
telling the Wish console where that file is and instructing it to Open the file and run the program
-
observing the resulting program behaviour
While our little program had only a simple "bug" in it and with our hints it only took one iteration to solve it, this will not always be the case for larger more complex programs. In fact it is often very desirable to attack a complex programming problem by starting with a very simple program and adding features to it step by step. At each step you would iterate through one complete programming cycle as described above. If you take nothing else away from this article remember this:
"all complex programs can be built up from simple parts which already work"
Any computer language contains a relatively small set of basic commands.
If that is all that the language could do it would not be very useful or practical. It would be better if we could extend existing commands or create entirely new ones as we needed them. Fortunately Tcl/Tk has just that capability.
Before we begin we need to discuss and reinforce the relationship between the "Wish" program and our little programs.
Tcl/Tk is what is known as an "interpreted language". What this really means is that the statements in our little programs are "digested" one by one inside the "Wish" program as they execute. This has no real impact on what we are learning except that phrases such as "Tcl/Tk interpreter" or "interpreted by Wish" etc. will appear in the article as we go forward.
Suffice to remember that our programs require Wish in order to run.
Let us illustrate how to extend the basic Tcl/Tk commands by way of an example.
Using the editor you used above create the following program by typing in these statements:
# first extended command example # scott - entry point proc scott {mycolour} { puts stdout [format "lastcolour was %s" $mycolour] return $mycolour } ;# end of proc scott # main - entry point # These statements will be executed at startup set lastcolour red destroy .hello button .hello -text "change me to green" \ -background red \ -command {set lastcolour [scott $lastcolour]} pack .hello -padx 20 -pady 20
The first thing you will notice is the statements which begin with the # character. The Tcl/Tk interpreter program (eg. Wish) will simply ignore these statements. This type of statement is used to add some description to a computer program. In addition blank lines are ignored as well with one important exception noted below.
Occasionally Tcl/Tk statements get very long. Long statements are very difficult to read because a portion of those long lines is often "off the visible screen". To make long statements more readable Tcl/Tk has assigned the \ character a special significance. It is often referred to as the continuation character.
What the \ tells the Wish program is that the line that follows is really to be treated as part of the same line that the \ appears on. As such you cannot follow a line ending in \ with a blank line. In the example above we have used the continuation character to divide this line into two lines:
button .hello -text "change me to green" \ -background red \ -command {set lastcolour [scott $lastcolour]}
Notice that we have also introduced another argument for the button widget. This argument is the -command argument. It is probably the single most powerful feature of the Tk part of the Tcl/Tk language.
What we are saying is "whenever you press the button with the mouse jump and execute the statement enclosed by the {} immediately following the -command argument".
This is what allows Tk programs to actually interact with us humans.
Before we try to understand the -command we have for our button we need to understand a couple of other new Tcl/Tk ideas.
In Tcl/Tk variables are set using the set command. An example in our code is:
set lastcolour red
In this example our variable is named lastcolour and the value we are assigning to that variable is red.
We can then use that stored value at other places in our program by adding a $ symbol to the front of the variable name. You can see a couple of examples of this in the program example above. The most interesting of these statements also merits further explanation:
puts stdout [format "lastcolour was %s" $mycolour]
In this statement we have introduced the first of our "statement within a statement" constructs. The inside statement is enclosed in []. The way the Wish program handles this is that it first executes the inside statement. In this case:
format "lastcolour was %s" $mycolour
As with any Tcl/Tk statement this produces a result. The Wish program then executes the outer statement
puts stdout "whatever the result was from the format statement"
Compound statements are very important Tcl/Tk constructs to understand.
The format statement itself is a very powerful and important Tcl/Tk statement.
The format statement can be viewed as a kind of "text creation statement". It is often desirable in a computer program to display the result of a computation or the value stored in a variable as part of a human friendly phrase. For this purpose we use the Tcl/Tk format statement. If you examine the first argument to the format statement:
"lastcolour was %s"
You can readily identify a portion of the "human friendly" phrase. In this case it would be lastcolour was. We would like to be able to finish this phrase using the contents of the variable, mycolour. We do this by using a special format character called a placeholder. In this case it is %s. The format statement understands a whole range of placeholder types. The %s means that "the variable I'm holding the place for is a text string". The third argument in our format statement identifies the variable value that we wish to have stuffed into the spot held open by the placeholder. In our case that is:
$mycolour
The resulting phrase in our example might be something like:
lastcolour was red
if the value stored in the mycolour variable was in fact red.
We now have talked about all the new Tcl/Tk constructs in our little program example with the exception of the statement:
proc scott {mycolour} {
The command proc in this statement is informing the Wish interpreter program that we want to create our very own new Tcl/Tk command. In this case we are calling our new Tcl/Tk command scott.
The first matching set of {} tells Wish that our new command will accept a single argument ... and with our command that argument will be named mycolour. The single { at the end of the line denotes the beginning of the block of Tcl/Tk code which will constitute our new command called scott. This logic will continue until we encounter the closing brace } as in:
} ;# end of proc scott
We have introduced another form of Tcl/Tk comment here as well. If you want to add a comment to the same line as a Tcl/Tk statement is on you must use two characters ;# together to denote the beginning of this comment string.
The return statement presents the result that we want our new scott command to give back or return. In this simple example we are simply returning the same value that we gave in as an argument.
return $mycolour
Everything between the braces constitute the logic associated with our new command called scott.
In our simple example the puts statement and the return statement are the only statements contained within scott. Our new commands can be as simple or complicated as we need to make them. This capability gives our computer language a huge degree of flexibility and richness. It is as if we can take words in our spoken language and combine them together to create brand new words of our own.
Having defined our new command we can now have it execute every time we press the button with the mouse by adding the following to the -command argument:
set lastcolour [scott $lastcolour]
Remember how the compound statements execute. Inner part first ... outer part next.
Go ahead and type this program in and execute it. Remember to press the button with your mouse. You should see an output that looks something like this:
Let's go ahead now and make our little example more useful.
# a more useful example # scott - entry point proc scott {mycolour} { puts stdout [format "lastcolour was %s" $mycolour] if {$mycolour == "red" } { .hello configure -text "change me to red" \ -background green set newcolour green } else { .hello configure -text "change me to green" \ -background red set newcolour red } ;#end if else puts stdout [format "newcolour is %s" $newcolour] return $newcolour } ;# end of proc scott # main - entry point set lastcolour red destroy .hello button .hello -text "change me to green" \ -background red \ -command {set lastcolour [scott $lastcolour]} pack .hello -padx 20 -pady 20
What we have done in this enhanced example is added some new statements to our scott command.
The first of those new constructs is what is known as the if ... then ... else branching construct.
Computers excel at this kind of true or false branching decisions. Most of the so called "intelligence" in computer software can be traced back to statements like these in the code. The if statement allows our little program to alter its execution path depending on the contents of a variable.
It begins with the statement (and it is important that in your code it is written this way):
if {$mycolour == "red" } {
In our little example this code block includes:
.hello configure -text "change me to red" \ -background green set newcolour green
Here we have introduced our final Tcl/Tk concept for this article ... the ability to alter the attributes on a Tk widget even after it has been drawn on the screen.
We can alter the colour of our button. We can alter the text in our button. We can do all these things based on how we code our program logic and flow The statement which does all this magic is:
.hello configure ...
Recall that when the button was defined it was given the name .hello.
Thus the .hello configure command construct is saying "I want to change something about the widget I have called .hello ... in this case a button widget".
Notice in this example we are changing the text in the button as well as its background colour. When this statement executes that is exactly what will happen on the screen.
The other statement inside our true branch of our if statement simply allows us to remember the new colour we have assigned to our button.
The closing } for our true branch is found as part of the else statement below:
} else {
Which then moves on to the false branch as you'd expect.
It is hard to see from this very simple example, but this is how computers get much of their apparent intelligence. You can see that it isn't intelligent at all! The intelligence is all supplied by the human programmer in the form of these true and false blocks of code.
Our false branch in our code simply mirrors the true branch in that we will alter the text and colour to reflect a red button and remember that colour in our newcolour variable.
.hello configure -text "change me to green" \ -background red set newcolour red
The false branch block is ended by the single closing } as below
};# end if else
If you now type in this program and run it you should see the button toggle between red and green each time you click on it with your mouse.
The contents of this article were derived with permission from several of the online iCanProgram lessons offered at http://www.icanprogram.com/nofeecourses.html
iCanProgram offers all its courses online for no fees. All we ask of the students is that they make a Cancer Research donation to a local charity in memory of one of our founders.
Notes:
More fields may be available via dynamicdata ..