[MJ] - The following is a work in progress. I couldn't find a good event tutorial starting from basics anywhere. If this exists please include a link. '''A Tcl event tutorial''' The goal of this page is to give an introduction to the Tcl eventloop suitable for Tcl beginners. If you make changes to this page please keep that in mind. Assumptions, it is assumed that you are reasonably versed in Tcl. This means that you should know: * How Tcl handles quoting and grouping This means you know the difference between $var, "$var", {$var} and [[$var]] if you ddon't know this difference, read man Tcl. * You know how to create procedures (see man proc) * You know how Tcl handles global variables (see man variable and man global) * You know the basic concepts of programming in Tcl If you don't know this it is better to start with a generic Tcl tutorial first (links here) '''What is event based programming''' * event queues * eventloop * why would you use/need events? * terminology queues, handler, bind, event loop, dispatcher When you write an console based application and you don't use events. The commands in your script will be executed in a specific order. For example the script: set a 1 set b 2 puts $a puts $b will: * set a to 1 * set b to 2 * show the value of a * show the value of b For a large class of applications this is not a limitation and you can get a long way without ever needing events. Now imagine you write an application that takes user input and based on that user input takes a certain action. For instance you have a very simple application that add two numbers a and b that are entered by the user. One way to write this is like: proc sum {} { puts -nonewline "a: " flush stdout gets stdin a puts -nonewline "b: " flush stdout gets stdin b set result [expr {$a + $b}] puts "$a + $b = $result" } sum With a typical output like: a: 12 b: 412 12 + 412 = 424 Note that in this example the order of events (user input, program output) is very well defined. So if the user enters an incorrect value for a, he will have to stop the program and restart again. If you want to allow the user to take actions in a more random order this approach will be fairly limited. It would be nice if after calculating the sum for a = 133 and b = 134 the user could change the value of b and calculate the sum again without having to reenter a. This will lead to something more like: set a 0 set b 0 proc showvalues {} { global a b puts "a: $::a, b: $b" } proc showoptions {} { puts "Valid commands are:" puts "a - set the value for a" puts "b - set the value for b" puts "= - calculate the sum" puts "q - quit" } puts "Welcome to sum." puts -------- showoptions puts -------- showvalues while 1 { puts -nonewline "Command: " flush stdout gets stdin input switch $input { a {puts -nonewline "new value for a: " ; flush stdout ; gets stdin a ; showvalues} b {puts -nonewline "new value for b: " ; flush stdout ; gets stdin b ; showvalues} = {showvalues ; puts "$a + $b = [expr {$a + $b}]"} q {exit} default {showoptions} } } With an example output: Welcome to sum. -------- Valid commands are: a - set the value for a b - set the value for b = - calculate the sum q - quit -------- a: 0, b: 0 Command: a new value for a: 133 a: 133, b: 0 Command: b new value for b: 134 a: 133, b: 134 Command: = a: 133, b: 134 133 + 134 = 267 Command: b new value for b: 135 a: 133, b: 135 Command: = a: 133, b: 135 133 + 135 = 268 Command: q Although this program is quite a bit longer than the first example, we have created a lot of flexibility. The user is now pretty much free to take his own path through the application instead of having to follow the predefined steps as in the earlier example. Closer examination shows that the major part of the program is implemented in the while loop. This shows the beginnings of a rudimentary event loop. The system is waiting for an event (the user presses a key) and takes an appropriate action (execute the correct switch case) or to make the correspondance even clearer: Here the while is the eventloop, the gets generates the event and the switch handles the event. When you start building GUIs it is even more clear that you will need to act on events, because the user has a very large number of possible actions he can perform at any given moment in time. Think about: * Pressing a button * Opening a menu * Typing some text in a text box If all of these actions generate events and we have some way of reacting to these events we can take the correct action based on what the user does without knowing when he will do it (e.g. he might enter some text first and then press a button or vice versa) '''How does Tcl use event based programming''' * file events * eventloop * callbacks * after * event sources '''Events in Tk''' '''Common pitfalls when using events in Tcl''' * event callbacks execute in global scope * events should not take long to handle * Difference in time between callback definition and execution, leading to * callback `quoting hell` -> use procs + list '''Where to go from here''' Links to event related man pages