Running the shell
Tcl shell = /usr/bin/tclsh (tclsh.exe)
Tcl/Tk demo Tcl/Tk shell = /usr/bin/wish (wish.exe)
As usually distributed requires many extra
files
Brian Toby
Here: combined distribution as one file
(starkit)
Includes several extra packages
Starting Tcl/Tk Tcl stuff
Windows: ncnrpack-win.exe The set command
Linux: ncnrpack-linux set var1 value
OS X: ncnrpack-osx set var2 $var1
Requires X11
set var3 var1
Aqua version of Tcl/Tk does not support graphics
demo The set command
Can be run as puts writes a string: $var1
ncnrpack-xxx <script> runs commands puts {w/o substitution: $var1}
in script
ncnrpack-xxx opens console
If-then-else
if {var1 == test} {
Embedded commands if {test1} { puts test done
set list [glob *] statement(s) set var1
} else {
} else { puts not test
Math }
statement(s)
set var [expr {pow(2,3)*10}]
}
looping Tk background
foreach var {1 2 3 a b c} { Master window is named .
puts $var
}
Something inside master is a child
Name of children of master will be
for {set I 1} {$I <= 4} {incr I} { .<name>
puts $I <name> ==> start w/lower case letter
} .b or .bToby not .BT
Some Tk Commands:
Displaying widgets
making widgets
Command label For very quick demos, use pack:
label <child-name> -text label text label .l -text sample
Returns <child-name> pack .l
Command button Better, use grid
button <child-name> -text txt \ grid <child> -column <num> -row <num>
-command tcl command
Returns <child-name> label .l -text sample
N.B. creates child but does not display it grid .l -column 1 -row 1
Demo1 Demo 1
label .label -text "Welcome to the Tcl/Tk demo"
grid .label -column 1 -row 1
button .b -text "Exit" -command "exit"
grid .b -column 1 -row 2
Type the above into console or
Windows: drag file demo1.txt onto ncnrpack-
win.exe icon
or Command line:
Toby$ ncnrpack-osx demo1.txt
or In console (windows may need cd <dir>
to get to right place):
source demo1.txt
Children with children Demo 2
Child windows label .label -text "Welcome to the Tcl/Tk demo"
grid .label -column 1 -row 1
toplevel <name>
button .b -text "Exit" -command "exit"
Frames (containers) grid .b -column 1 -row 2
frame <name> toplevel .w
pack [label .w.l -text child]
Child of child is named .parent.child pack [button .w.b -text kill -command "destroy .w"]
toplevel .win
button .win.b -text child button
pack .win.b Creates a 2nd window. Clicking on kill closes the
child window; clicking on exit closes both
Destroy command deletes widgets & children
destroy .win (deletes .win & .win.b)
destroy . (same as exit)
Demo 2 Demo 3
foreach c {1 2 3} {
foreach r {1 2 3} {
grid [label .$c$r -text "$c-$r"] -column $c -row $r
}
}
Creates a table with grid
Demo 4
Demo 3
Define a new command
# define a routine to delete children of an item
proc cleanup {parent} {
foreach item [winfo children $parent] {
if {$item != .tkcon} {destroy $item}
}
}
Define a new command with:
proc <name> <args> {script}
<name> <arg(s)> then executes command
Demo 4 Demo 3a
foreach c {1 2 3} {
Nothing happens! foreach r {1 2 3} {
grid [label .$c$r -text "$c-$r"] -column $c -row $r
New command has been defined: cleanup }
}
# replace upper left element with frame
Use as cleanup . -- like this: destroy .11
grid [frame .f -relief raised -bd 2] -column 1 -row 1
# fill the frame
foreach c {1 2} {
foreach r {1 2} {
grid [label .f.$c$r -text "$c+$r"] -column $c -row $r
}
}
Creates a table inside a table with grid &
frame
Demo 3a Demo 3b
foreach c {1 2 3} {
foreach r {1 2 3} {
grid [label .$c$r -text "$c-$r"] -column $c -row $r
}
}
# change an element on the fly to show it can be done
.33 configure -text "new element\n33"
Changes an existing label
Demo 3b Graphics demo
package require BLT
pack [blt::graph .g]
.g element create l -xdata {1 2 3 4} -ydata {1 2 9 16}
# oops
.g element configure l -ydata {1 4 9 16}
# allow zooming
Blt_ZoomStack .g
Shows how to use BLT for plotting
Graphics Demo
Running external programs
Many ways -- this one is platform
independent:
set fp [open x.txt w]
puts $fp input
close $fp
exec program < x.txt > x.out
set fp [open x.out r]
while {[gets $fp line] >= 0} {
#do something with line
Zoom --> }
Running interactive
Running external programs
programs: Win9x, -ME
Even better, have program write tcl code as # this creates a DOS box to run a program in
proc forknewterm {title command "wait 1" "scrollbar 1"} {
output, then replace while with: global env expgui
set lines [read $fp] set pwd [file nativename [pwd]]
close $fp # check the .EXP path -- can DOS use it?
eval $lines if {[string first // [pwd]] != -1} {
MyMessageBox -parent . -title "Invalid Path" \
To suppress errors in output -message {Error -- Use "Map network drive" to
access this directory with a letter (e.g. F:) GSAS can't
catch {eval $lines} directly access a network drive} \
-icon error -type ok -default ok \
-helplink "expgui_Win_readme.html NetPath"
return
}
Win-NT/-2000/-XP
if {[info command winutils::shell] == ""} { proc forknewterm {title command} {
MyMessageBox -parent . -title "Setup error" \ global env expgui
-message {Error -- "WINTILS not found. Can't do
anything!"} \ # loop over commands
-icon error -type darn -default darn \ foreach cmd $command {
-helplink "expgui_Win_readme.html Winexec" # replace the forward slashes with backward
return
regsub -all / $cmd \\ cmd
}
# loop over multiple commands exec $env(COMSPEC) /c \
foreach cmd $command { "start [file join $dir gsastcl.bat] $cmd"
# replace the forward slashes with backward }
regsub -all / $cmd \\ cmd }
winutils::shell [file join $dir gsastcl.bat] $cmd
}
}
}
Unix/OS X
proc forknewterm {title command "wait 1" "scrollbar 1"} {
global env expgui
How can you tell where you are?
set termopts {} if {$tcl_platform(platform) == "windows" && \
if $scrollbar { $tcl_platform(os) == "Windows 95"} {
# win-95
append termopts " -sb"
} elseif {$tcl_platform(platform) == "windows"} {
} else {
# win-XP
append termopts " +sb"
} else {
}
# the rest
if {$wait} {
}
set suffix {}
} else {
set suffix {&}
} See file expgui/gsascmds.tcl for more
catch {eval exec xterm $termopts -title [list $title] \
-e /bin/sh -c [list $command] $suffix} errmsg
complete versions of the commands and for
if $expgui(debug) {puts "xterm result = $errmsg"} gsascmds.bat
}