
----------------------------------------------------------------------
An Introduction to Tcl/Tk
Stephen Edwards
Berkeley CAD Group
CAD Seminar, 950118

----------------------------------------------------------------------
All interesting programs interact with people or other programs

Command-line interfaces:

  ls -AFC /tmp
  find . -name espresso -print

Command languages:

  vivaldi 101: gnuplot
  gnuplot> set xrange [0:10]
  gnuplot> set yrange [-1:1]
  gnuplot> plot sin(x)

Graphical User Interfaces (GUIs):

   Mosaic, netscape
   PowerPoint
   FrameMaker

GUIs with languages:

   Emacs
   Apple's Hypercard
   Cadence's framework

----------------------------------------------------------------------
Tcl and Tk provide an easy way to build interactive programs

 Tcl is an interpreted scripting language easily added to a program

  set f [[open lindex $argv 1] r]
  while { [gets $f line] >= 0 } { puts $line }


 Tk is collection of Tcl commands implementing widgets like menus, entries, and scrollbars for the X window system

----------------------------------------------------------------------
One way to use Tcl/Tk is to write a script

 Easiest way for small programs

 Like writing a script for csh, awk, perl, etc.

 Does not use Tcl's ability to be embedded

 No compile/link step necessary: development time reduced

 Run it using one of the standard shells:

   Tcl only  use tclsh
   Tcl and Tk  use wish

 Can be run on many platforms

----------------------------------------------------------------------
A few lines of Tcl can do a lot
This Tcl script emulates grep:

 #!/usr/local/bin/tclsh

 if { $argc != 2 } {
   error "Usage: tgrep pattern fileName"
 }

 set f [open [lindex $argv 1] r]

 set pat [lindex $argv 0]

 while { [gets $f line ] >= 0 } {
   if [regexp $pat $line] { puts $line }
 }

 close $f


----------------------------------------------------------------------
A few lines of Tcl with Tk make a graphical application

This creates buttons that, when pressed, repeat previously-entered commands:

#!/usr/local/bin/wish -f

set id 0
entry .entry -width 30 -relief sunken \
  -textvariable cmd
pack .entry -padx 1m -pady 1m
bind .entry <Return> {
  incr id
  button .b$id -text $cmd \
    -command "exec <@stdin >@stdout $cmd"
  pack .b$id -fill x -ipady 10
  .b$id invoke
  .entry delete 0 end
}


----------------------------------------------------------------------
Tcl/Tk's real strength lies in extending these shells

1.  Write, in C, new application-specific Tcl commands

2.  Link these with Tcl/Tk libraries to produce a custom shell

3.  Write a script for this shell


This framework produces interactive graphical applications easily.  The ideas:

 Interpreted scripts for user interface and ``glue''
   Rapid development with very high-level constructs

 Custom C code for speed-critical or data-intensive tasks
   Speed and power when you need it

----------------------------------------------------------------------
Tcl's C interface is simple
This compares its two arguments for equality:

int EqCmd( ClientData clientData,
  Tcl_Interp *interp,
  int argc, char *argv[]) {

  if ( argc != 3 ) {
    interp->result = "wrong # args";
    return TCL_ERROR;
  }

  if (strcmp(argv[1], argv[2]) == 0 ) {
    interp->result = "1";
  } else {
    interp->result = "0";
  }
  return TCL_OK;
 }

----------------------------------------------------------------------
Examples of Tcl/Tk applications

 These slides are a 1300-line wish script

 My states editor is a 2100-line wish script

 Ptolemy and Hyper both use Tcl/Tk

 ical, a Tcl/Tk C++ hybrid
   3100 lines of C++
   5200 lines of Tcl/Tk

 The commercial presentation package Perspecta Presents!
   29k lines of C (one new widget, thirty new Tcl commands)
   11k lines of Tcl/Tk

----------------------------------------------------------------------
Having an interpreted language around is useful


 File formats are easy: save as a Tcl script.
   Execute this to reload.

 Undo/redo can be implemented by saving Tcl commands and reevaluating them as necessary

 Pass complex data through a Tcl script


----------------------------------------------------------------------
Tcl is a shell language sporting many high-level constructs

 Invoke commands with arguments separated by spaces:

  commandName arg1 arg2 ... argn

 Local and Global Variables:

     local variables are created automatically when referred to
     global variables must be declared, e.g., global foo

 Substitution Rules:

  set a $b
  set a [expr $b + 2]
  if {$a < 0} { puts "a is negative" }

 Numeric Expressions:

  expr 5 + 6
    11
  expr sqrt(2)
    1.41421
  expr $a < $b ? sin($a) : (cos($b) + 2.75)

 Conditionals and Loops:

    if else
    while
    switch
    for        Like C's
    foreach    Iterate through a list
    eval       Execute a script in a string

 Strings:

 format "%s is %d years old" $name $age
   Stephen is 5 years old
 scan $s "%d units %f" a b
 regexp {^[Ff]oo} $s

 Lists:

  lindex {a {b {a b} c} {d e} f} 2
   {d e}

 File Access:
 
  set f [open /tmp/foo w]
  puts $f "To foo"
  close $f

 Subprocesses:
 
  exec rm /tmp/foo
  exec make clean &

----------------------------------------------------------------------
The string is Tcl's universal data type

 Arguments to commands are strings

 Commands return a string as their result

 Variables store strings

 Strings may be interpreted as

   Character strings
   Floating point numbers
   Lists
   Filenames
   Tcl scripts

   Type conversion is implicit

----------------------------------------------------------------------
Tcl procedures allow defaults and a variable number of arguments

Simple procedure:

  proc plus {a b} {expr $a + $b}

  plus 5 6
    11

Procedure with defaults:

  proc inc {a {b 1}} {expr $a + $b}

  inc 7
    8
  inc 7 2
    9

Procedure with variable arguments:

  proc sum args {
    set s 0
    foreach i $args { incr s $i }
    return $s
  }

  sum 1 2 3 4 5
    15

----------------------------------------------------------------------
Tcl supports associative arrays

Arrays may be indexed by arbitrary strings:

  set foo(bar) true

  set foo(5) false

  puts $foo(bar)
    true

  puts $foo(5)
    false


----------------------------------------------------------------------
Tcl supports ``variable traces''

These invoke the command varProc whenever the variable is read, written, or unset (deleted):

trace variable variableName r varProc
trace variable variableName w varProc
trace variable variableName u varProc

This facility is useful for imposing constraints among things

----------------------------------------------------------------------
Tk is a set of Tcl commands for manipulating ``widgets''

Widgets, such as buttons, are given a name when created:

 button .b -text "Press Me" -command "destroy ."

and then must be ``packed'' to become visible:

 pack .b


----------------------------------------------------------------------
Tk has many widgets

Create a top-level window (widget) named .ex:
  toplevel .ex

Create a button:
  button .ex.b -text "A button"
  pack .ex.b

Create an entry for entering text:
  entry .ex.e -scroll ".ex.s set"
  pack .ex.e

Create a scrollbar controlling the entry widget:
  scrollbar .ex.s -command ".ex.e view"
  pack .ex.s

Create a canvas and draw a polygon and some text on it:
  canvas .ex.c
  .ex.c create polygon 10 10 100 100 200 10 \
     200 200 75 100
  .ex.c create text 50 200 -text "wow" -fill red
  pack .ex.c

----------------------------------------------------------------------
A Tk application has initialization code and event handlers

 Initialization code builds windows by assembling widgets:

  button .b -text "Press Me"
  menu .m
  scrollbar .sb -orient horiz
  pack .b .m .sb

 Event handlers are Tcl scripts bound to events - invoked because of an event

  bind .m <B1-Motion> {puts "what a drag"}

  bind . <Control-c> "destroy ."

  button .b -text "Press Me"
    -command {puts "Ouch!"}

----------------------------------------------------------------------
Widgets are arranged hierarchically

Each widget has a name like .b, .top.button, etc.

The names are like unix filenames, but with periods instead of slashes.

----------------------------------------------------------------------
Widgets have defaults overridable with arguments

A simple button

 button .b -text "Press Me"

An elaborate button

 button .b -text "Press Me" \    button's label
   -bd 10 \                      size of border
   -padx 5 -pady 5 \             space between
                                  label and border
   -command "buttonPressed pm" \ executed when
                                  button is pressed
   -cursor hand1                 cursor to display
                                  when pointer
                                  inside button

----------------------------------------------------------------------
Widgets have an object-oriented interface

Once defined, methods can be invoked on a widget:

Create it

  button .b -text "Button's First Label"

Change its label

  .b config -text "Button's New Label"

Cause a button press

  .b invoke

Prevent a button from being pressed

  .b deactivate


----------------------------------------------------------------------
Tk arranges widgets using the packer

 Widgets know how to draw themselves, but don't know where to draw themselves.

 The packer controls where groups of widgets are drawn

 Slave widgets are placed within their master, starting from the outside in

By default, the widget is packed onto the top
 pack .a

The fill option makes the widget consume the available space
 pack .b -fill x

The anchor option sets where the widget touches its boundary
 pack .c -anchor w

The side option controls where the widget takes its space
 pack .d -side left

These options can be combined
 pack .e -side left -anchor s

The expand option allows the widget to consume extra space
 pack .f -fill both -expand y

The packer can handle multiple levels of hierarchy
  pack .f.a
  pack .f.b -fill x
  pack .f.c -anchor w
  pack .f.d -side left
  pack .f.e -side left -anchor s
  pack .f.f -fill both -expand y

----------------------------------------------------------------------
The text widget is a full-fledged text editor

This window is a bare text widget:

text .t -wrap word
pack .t

----------------------------------------------------------------------
The canvas widget is almost a drawing program
This window is a canvas widget with two bindings

----------------------------------------------------------------------
Tk's ``send'' command supports interapplication communication

 This sends a command to another Tcl interpreter (shell), which executes it:

  send appName command

 Limited, but a step in the right direction

 This sort of thing can be a gigantic security hole.  E.g., anybody could send

  send foo "exec rm -rf ~"

  Some security exists (i.e., xauth), but is a blunt instrument


----------------------------------------------------------------------
Tcl/Tk is better than other approaches

 Motif under X

  C-based library with many widgets

  + Attractive, thoughtfully-designed widgets
  + Very flexible
  - Low-level, requires many lines of code
  - Compile/link paradigm, no interpreter
  - Expensive, proprietary

 Visual BASIC on Windows

  Direct-manipulation interface assembles widgets with attached BASIC code 

  + Has many of the same widgets
  - Does not have a canvas widget
  - No ``packer'' for geometry management
  - Underlying language is BASIC, no interpreter
  - Affordable, but from that company in Redmond, WA

 Hypercard on the Mac

  Page-based direct manipulation interface with hypertext facilities

  + Card metaphor simple
  - Few ``widgets''
  - Few different applications possible
  - Scripting language weak
  + Widely available

----------------------------------------------------------------------
Tcl and Tk are not perfect, but are the best so far

Problems:

   Typeless variables and parameters enables bugs

   Missing important high-level widgets (file dialogs, printing)

   Not enough standardization

   send a good idea, but too primitive to be very useful

   Simple data types make large programs infeasible
      [incr Tcl] extension some help

   It's too tempting to turn little programs into big ones


----------------------------------------------------------------------
Recap


 Tcl is an embeddable scripting language

 Tk is a set of object-oriented user-interface widgets accessible from Tcl

 One way to use Tcl/Tk is to write a script for a standard shell: tclsh or wish

 Tcl can easily be embedded into a program and extended

 Having an interpreted language around is helpful

----------------------------------------------------------------------
We should consider writing a Tcl interface to the MDD package


 Our algorithms are well-described by high-level operations

 Developing and testing algorithms would be faster

    no compile/link cycle

    smaller programs; fewer lines to debug

----------------------------------------------------------------------
We should consider adding Tcl/Tk to HSIS


 The existing command language is primitive

 Tcl's C interface is similar to the existing one

 Many new functions could be implemented as scripts, saving development time

----------------------------------------------------------------------
To learn more, mimic examples and read Ousterhout's book

The widget demo, part of the Tk distribution, has examples of nearly everything

/usr/sww/tcl/lib/tk/demos/widget

Ousterhout's book, Tcl and the Tk Toolkit (Addison-Wesley, 1994), is a necessity.  It's well-written and widely available.

Detailed information about each widget is available from the man pages supplied with Tk.

----------------------------------------------------------------------
The best way to learn Tcl/Tk is to pick a little problem and solve it using Tcl/Tk

 I believe this applies to learning any programming language

 Think of some little utility you need - something that would make your life easier - and write it using wish

----------------------------------------------------------------------
Tcl/Tk is in the public domain, and has a rapidly-growing user community

 There is a large WWW-accessible archive of many Tcl/Tk programs and extensions

 We will be seeing many more Tcl/Tk applications in the future

----------------------------------------------------------------------
Your programs can benefit from the use of Tcl/Tk; you should use it

 In the future, most things will have graphical user interfaces.

    Tcl/Tk makes them easy to build

 Shifting toward higher-level languages like Tcl accelerates development and makes for more intelligent programs
