o
tcl.0 注意事项
$ C1 B% T. B8 i5 u/ a0 }* Eo
tcl.01 tcl?什么是tk? 2 `# q! ~- e7 o2 X! M3 v
o
tcl.02 wish (WIndowing SHell的简称)
; e+ d# r7 L7 C+ M- m) }# A§
tcl.02.01 交谈式示范
. y4 |! A7 M( A8 ]) V§
tcl.02.02 script file 示范 / y' L. x# G# S6 l5 Y' }
§
tcl.02.03 指令格式及范例
4 u2 x+ E' u+ K5 I§
tcl.02.03.01 范例:一般
2 Z' U. p9 z7 c& ]§
tcl.02.03.02 范例:procedure/while/eval/{}/exec/eval
$ R; |7 b8 C F& b6 Q/ l§
tcl.02.03.03 范例:数组 * `- y, H8 r1 {: L
§
tcl.02.03.04 范例:list $ ^( X9 N" b6 t4 O
§
tcl.02.03.05 范例: 控制结构: 6 s5 {0 u, m, B: ?
§
tcl.02.03.06 范例: 子程序: % w* Q& w9 j8 ?# z8 N
§
tcl.02.03.07 范例: 错误&特别状况 0 [ s$ A4 q7 _: s
§
tcl.02.03.08 范例:字符串 % K% g; h) M) a z
§
tcl.02.03.09 范例:其它expr之用法 8 \9 @3 {/ k' I1 e _2 N
§
tcl.02.03.10 范例:离开 $ _$ _ ?0 v) ~+ k7 q) ?
§
tcl.02.03.11 一些特殊键 9 Z+ V) D8 x R9 G5 l% ^
o
tcl.03 Patch for Chinese Tk
8 L) f& a; \$ e0 W/ ]3 k2 ]o
tcl.98 示范程序 ; O( x3 U* l$ ^; z. D
§
tcl.98.01 power
3 B- v' h* u! P5 N§
tcl.98.02 window/history
* |% l% y6 G6 [9 V$ v7 \* L; u2 A7 y! K( p+ t
8 ^7 R6 `3 R E- F+ @tcl.0 注意事项
B! _/ d$ Y7 m7 f$ U5 ~+ F5 ]TCL/TK 速成教材
, E: z, D$ ~; h6 D& \# W# 所有以#开始的行都可以不读, tcl/tk 的批注行亦以此#开始
3 {# J3 v( p4 I0 n0 @2 l9 k9 z/ e
# 为了统一,以ENSYS FAQ格式写.
! y* B% C+ i L! Z
# 目前只有ev004有tcl/tk
& N! R+ S) I& W2 C4 v4 V E+ d
所以用 grep -v '#' 此檔,将得到一个简单的说明,尤其是你用于复习时
! \6 m4 P- B! m: U- o7 A o5 otcl/tk原始码可以在NCTUCCCA:/X/contrib/下找到。
; D: q4 K9 c$ C' Kwish的命令行编辑非常原始,使用者可以用fep 或ile
* \; \$ m+ W4 D两个front end 程序达到类似tcsh/bash/ksh 的行编辑。
+ }# T* _; P; P7 _1 v, w可用 which wish 找wish放那裹
" G3 J8 H* F' o" ?4 H9 ?#Linux的使用者(应该说XFree86的使用者)应该安装时就有tcl/tk了。
6 z0 H8 L3 O7 ]. J$ b0 q1 O$ z S5 x
tcl/tk 指令的连续符号为 \, 同一般shell之用法
" w. ]" v; C) D6 x
tcl/tk在USENET上有自己的讨论群:comp.lang.tcl各位可以参考其FAQ。FAQ可在
* r4 j x+ I2 H$ l# Q* x+ WNCTUCCCA:/USENET/FAQ/comp/lang/tcl拿到。
/ F4 r; B( }' g
#index前有*者,为改自
: Y8 k, _2 K3 F* M
# Shiau Yong-Ching (萧永庆) 的原稿
syc@cc.ntu.edu.tw 3 Mar 1994 11:27
7 ?* ^1 u3 P# M) k9 g
* d! J3 W! V1 U( G
tcl.01 tcl?什么是tk?
% L" z9 d9 a# a" p1 @) j4 @1.tcl 是Tool Command Language 的缩写,
/ I/ J. S' `2 Z% Q8 D" r2.而tk是一个X window的Tool Kits,是tcl在X Window System 的应用。
' d. P, z4 o/ k* B- d" J
3.tcl 是一种解译语言(shell),
% U* u4 u+ d% d
也是一套C的函式库
( ~* E. p( V3 o#tcl的解译器同时被设计成一个C的函式库
: X3 Y. M$ y- r2 b' d# D
#提供基本的命令与控制结构,并且
: x9 s/ a+ W3 I, R/ `+ S8 |#使用tcl 的任何程序皆可以根据tcl 的规格撰写C程序与之链接
. X( V' W0 u A" W' u+ c3 K. U+ R
#增加新的命令,以提高关键程序的效率、或增加新的特色。如tk
6 [7 p# E" _. v- E5 f y#就是这样子的示范。
U) X4 \$ D" r% t/ x4.tclsh 为tcl 的shell,而
: X: g7 K, h3 M$ p' o# n
wish 为tcl + tk 的shell, 语法同tclsh
( U* a2 ?8 K0 r G$ _! P" {4 o. ^# N#此处直接介绍wish,学会wish,即等于学会tclsh
; W$ ]. i, W; ?& q' V( d
C% q1 v4 k% e% o- s4 z
tcl.02 wish (WIndowing SHell的简称)
. X8 N" I/ D8 }9 _tcl.02.01 交谈式示范 6 k! E! |1 J% g( h8 G2 e6 c4 b
请键入
* ^5 {: L8 d3 K. S6 k# |
wish
' W8 O/ C4 m; E7 ` B# d& _#这时您会看到一个wish开了一个窗口
+ h0 [( q4 E) a5 Kbutton .b1 -text "Hello,World!" -command exit
# F4 s8 k! G8 q" _" S
pack .b1
6 D9 z6 ?3 R+ M#下完第二个指令后,原本空白的窗口就变成一个印有Hello,World
, z8 z6 s# L8 J, A Z; n3 P#的立体按钮,而且鼠标移近时会变成高亮度。但是别急,且慢按键
( g- |* j/ G# b8 \6 {* s#在输入两个命令看看:
4 U+ x: E6 ?9 [- F& I
button .b2 -text "Hello,TCL/TK" -command "destroy .b2"
7 d) R# {0 l- s' C9 k5 F O$ vpack .b2
# o3 w D4 u5 \- Y#此时,屏幕上会出现第二个按钮。以下两个命令可以更改颜色:
8 P- D7 ?% I1 Q6 I# e
.b1 configure -background red
0 h9 B% D2 l! Y4 r.b2 configure -foreground green
7 Y' c& h" x: V2 m0 o9 N0 g) U
#按下第二个按钮会使第二个按钮消失,而第一个按钮会结束程序。
- {; b. s, |5 w#每次这样写很麻烦,你亦也可以照UNIX的规矩把程序写成一个文件 │
! i8 ]; b% K0 }9 ?3 M4 q0 R5 J
#案hello,再执行之。如2.2
1 F* \6 _7 G: D" q( N
) j9 W, Z: ^" w" l- Otcl.02.02 script file 示范
" r' c2 ^" X) N9 \' Avi hello
2 M5 A( N$ P6 K8 v: y+ t% v#键入
m# G2 D* Y; J, v
#!/usr/local/bin/wish -f
?$ j1 K" o( @' Qbutton .b -text "Hello,World!" -command exit
$ l Y2 F( W+ o. {: lpack .b
! C+ R' Q; }1 ?
#存盘
: H! v4 U) j" E1 O1 C7 [- w4 b6 ochmod +x hello
) A& R- g9 u3 R G' V% P. x( D3 b
hello
8 H1 u# D. z" J" O8 X#执行
4 Q1 o3 z4 b" w0 ]# C$ [
4 E) p4 y( Y6 E
tcl.02.03 指令格式及范例
4 F" ?4 h! j ~6 n" E; e9 I1.一个tcl/tk 程序是由好几个tcl/tk 指令组成的。
# ~2 V& h/ A) O
2.一个tcl/tk 指令与平常在shell 下面的命令一模一样,
+ P3 V/ K# p+ t* f2 j#如前面hello,world 的例子一样,第一个字是命令,剩下的全部是
/ w j! q, d- `, j7 Y7 [# 该命令的参数。
9 F: S$ v& ^/ R2 o3. 除了命令外就只有变量。变量与shell 变量一样,只有一种型别:字符串。
8 z( P5 n* m4 Z, J$ l
用钱号($)可以取出变量的值。
. u* _% A; `$ ?4 ^; A: P4. 对每一个指令通常只做一次变量代换。而被大括号括住的部份不做任何处理。
0 |/ o7 J. {0 ^! S( e" p9 J
若要变量代换二之以上需结合eval指令.
. _* v, W2 y6 n8 }, H, K. i( ]$ z* ~& x
5. 会优先执行被方括号([])括住的叙述,并将其结果当成原来命令的一部份。
3 a, Z8 J$ F( U6 A/ _2 `5 M# 这与shell 的backquote之功用相同(如mkdir `echo Hello`)
$ m+ h! M0 O& @% y+ K" D7 s# z0 W
tcl.02.03.01 范例:一般
$ F2 H* T! _1 b' f& Q' c; @#改自 Shiau Yong-Ching (萧永庆) 的原稿
syc@cc.ntu.edu.tw 3 Mar 1994 11:27
$ R+ m3 y, I; _! X
unix% tclsh
" J" N `/ l6 o2 P
tcl% set x 100
+ T, b' b- {; o/ i
#输出 100, 设定x变量(这时仍是字符串)
% ?6 w, s( _5 H" t
tcl% set y 200
! t* S b0 v6 @1 x4 ^0 c/ {0 k
tcl% expr $x + $y
# d$ y# I1 j3 L+ Q! M4 i8 g" s0 `
#将$x $y当成数值, 执行 $x + $y,输出 300(但仍为字符串)
& i% O# f" ]( ~) A$ O
tcl% set z [expr $x+$y]
6 e3 \3 T0 f, r/ N* d& E) i
#设定z变量为300
: T, b, b4 e" B- N( O. x
tcl% set a [set b 100]
% u) k- z; v( ]
#设定a = b = 100
2 [4 z& `/ {6 e# ^
tcl% expr (3>4)||(6<=7)
1 e5 I- c7 e4 F. x9 }+ _3 g#执行逻辑指令,输出 1
6 K) ]0 f; c! J; ]9 M4 V" j& o
tcl% expr 14.1*sin($x)
- M) b7 I4 S! e. Q7 m* ^tcl% set organization "Taiwan University"
8 s; x9 U p8 L$ J
tcl% set organization {Taiwan University}
6 w; K- ]+ w$ z4 C( ^; v- K
#以上两指令在此同意,
7 Q7 H6 F1 }$ _. k) X#但若为 set organization "ENSYS

jjkao", 则会
* D* d; w, |1 U- ^# f
# 先做变量代换
- z+ M8 W& ~& ]2 c
3 n' e1 f( Y* @, `5 o0 q
相关的命令:
0 Z4 b$ l. l* c+ t4 Sset 变量 变量值
# K. V. x% m8 C3 U
append 变量 变量值 [变量值2 变量值3 ...]
2 i. O; Z9 O+ j: P8 z! t1 lincr 变量 [increament]
- m. n7 c- x H% M ^1 w% l
# 预设为= 1
' J: }' h5 b ?
unset var [var2 var3 ...]
. d5 e7 O; X0 `! w: `8 RNOTE: unset $var 不WORK
5 [; O! @: h5 x Z0 m
=> eval unset $var
( q- R$ J4 ^3 w3 u, O: r: d( {/ j
' Q/ \: J; e+ x) B3 w) C/ `( ltcl.02.03.02 范例:procedure/while/eval/{}/exec/eval
4 K3 b9 k* [- O) v) Fproc power {base p} {% t% U9 t" R1 H0 O
set result 1
. \ O0 G4 o7 I+ |3 ~% Nwhile {$p > 0} {
/ q4 g0 q) v" A' Z/ H
set result [expr $result*$base]
9 u# I* E1 f: Aset p [expr $p-1]
6 v3 W- v" |1 J* s# U# W
}
' F) H- D& B2 N" Ureturn $result
+ C& y- d% k- Q# z
}
6 i |! ~) p7 c2 |. Qpower 2 6
* p: \! K' w2 X, }2 _
# 可得 64
( T, Z* X$ [9 N! U7 A
power 1.15 5
' H- J# R: R" }% J+ q# 可得 2.01136
, F) y8 ^' H) d7 G
/ [ F2 p: |! Y6 n6 t
仔细观察procedure的demo,其实tcl 并没有procedure结构的语法。
% Y: G0 W" _. s# }% {" w' Qproc只是一个命令,接受4个自变量:
3 I r( ]: I! g6 D
9 Q4 R) V* }( U {( n7 o7 m, T8 R
proc 新命令名字 参数 一段tcl程序代码
, D) e6 F! Z9 {% u
1 J: I7 p$ o/ {. I& x
参数与tcl程序代码用大括号括起来的原因是我们不希望tcl 现在
8 s- [) ~; A( ?7 C0 R4 g8 h- G& J就执行这些程序代码,而是当procedure被呼叫时才执行。while结构也是
8 I9 ]1 x ~& i" K5 o9 z l% L0 U如此:
, @# @0 z6 k3 A) p3 V* f! \while 判断 程序代码
5 X. Z8 n5 L L
因为我们希望每次while执行时$result,$p的值都会变。如果不用大括号
7 f: X( c5 q! y( P6 n括起来,则所有的值在tcl解译的时候就固定了,while循环永远也不会
d0 j( ~9 j! Q结束。
$ } t! r+ F6 I. b
1 K" p, Q$ h! {: A( X与大括号相反,eval命令可以把一个字符串当成tcl 命令执行:
2 a& ]$ s0 \% Y% Z
eval {set x 123} 等于 set x 123
% M# z3 T- t1 e2 R; X' m' Teval "set x 123" 同上
" T- v# v d6 v- L, @# @eval可以造成tcl 对同一叙述parse两次,解决一些难缠的问题:
' c4 V" y5 A0 N4 e3 g" g7 H
exec rm [glob *.o]
" }0 W& p3 B) |/ K9 D4 y) ?# b; k+ E
会告诉你:
# z1 e* l! s/ W+ ~5 s/ B0 w"a.o b.o c.o" not found
# f) ]4 C) H) d
正确的解法是叫tcl 再parse一遍命令行:
1 G& O" E, ?' d" z
eval "exec rm [glob *.o]"
7 a/ y0 T& S( E9 k( M/ Q6 E; `5 P/ y: T1 `
tcl.02.03.03 范例:数组 & [5 r6 x2 x( n3 U# ^4 o9 B# w( r
tcl 的array:不须宣告,直接用即可,但是只有一维数组而已。
: }, X3 {9 P) {; R6 n
set days_of_a_month(Jan) 31
$ J8 Y8 }/ K8 y
set days_of_a_month(Fab) 28
. s) h/ o/ L/ u, o
S1 x# X- ?+ ? }, |多维数组可用单维数组仿真:
9 P% Y% c. o9 C( R, N; @
set matrix(1,1) 100
& R: o+ A1 A* V6 d, l& rset matrix(3,9) 50
, |. }& H8 `3 x) M4 i0 l5 V2 C
set matrix($x,$y) 66
- D' D8 R# t, D) W
set z $matrix(6,6) 77
0 S4 y+ g1 q! T
. o0 b, G: m# b数组的index其实为 "1,1" 、 "3,9" 与 "$x,$y"
( u# ^" D6 B/ ^: l0 B8 o
4 F5 v( ~& Z/ z$ B6 n2 C+ n
tcl.02.03.04 范例:list & S; v- ]+ d. C
#tcl 还有一种数据结构叫list
& a( @- n. @5 [
set x {Sun Mon Tue Wed Thu Fri Sat}
% g& n" P; P7 v( G* {; \9 u) E
lindex $x 1
$ H8 c" D3 d) G5 n8 P
#输出 Mon
4 q) Y7 {- m# C0 a, Xlindex {a b {c d e} f g} 2
) `1 q J& }* w" m, b: A/ O
#输出 "c d e"
6 b( C/ N+ R: W' W! ~+ cconcat {a b} {c d} e
' x6 o6 b& N* H( m- Q1 O/ a1 h#输出 "a b c d e"
* ~1 f; J7 L; @3 O: C2 O* G
list {a b} {c d} e
! y5 O/ Y K1 H. @2 \5 W9 h
#输出 "{a b} {c d} e"
" a" w, i j$ t, s, q% \llength { {a b} e f}
7 h: C5 J4 I8 a. C# m2 C3 z& l
#输出list的长度,此处为3
" b3 R( b, i% `7 Cllength {}
( v/ g" ?" J* \
#输出 0
, z1 C5 r" C8 y
llength a
& h7 F9 R( {, p* B
#输出 1
! ~2 U( x" p5 W# M6 U) X0 _: L
linsert $x 2 a b c
9 U; |* t& q7 ~
#将 a b c 插入 第二个list单元之后 Sun Mon a b c Tue ...
+ X8 ~( L8 d* L ]
linsert $x 0 a
2 \0 T9 l$ A+ Y/ \1 e
#a Sun Mon ...
/ [5 m0 h7 M/ x8 K, w
lreplace $x 0 a
: @5 R/ V( z/ ?5 v1 H1 @, q#取代 a Mon Tue ...
( B/ m/ B! I. ~! S# W
lrange $x 0 1
w) \) o7 r) o, j, }7 D# m#输出list的一区域值 Sun Mon
. L8 B- S8 q$ j: e3 ^, Z5 C) _ N( f
lappend $x a b c
" P$ d- e u. {( @' k
#加 a b c 在list最后
3 {- G+ ^* d5 w2 E) F
lsearch $x Sat
# M- }. g3 m1 h#找Sat在list的那一个位置
# f3 P' i& o! I3 G6 u& K
lsearch -glob $x S*
0 J$ F# Y: \/ L& ^0 W4 m$ E, _, y3 F2 D
#用Wild Cards找
% x# S! h; d) I& t; A4 R3 C2 Hlsearch -regexp ...
5 ]2 o, d j- Q#用regular expression的型式找(若您不知regexp,请看UNIX的书)
' T, E" x% {6 z* L2 O) y: ^
lsort [-decreasing|-integer] $x
( l& k4 Z- e/ H+ v8 S/ g; t#重排list元素的顺序
. D8 D6 x7 E3 T
$ O+ C% p0 e. G, W7 G4 d5 x字符串与list之关系
, u/ G, A3 M/ p; u4 p, {0 E
set x a/b/c
7 r5 F3 U: I% b; D1 y1 Pset y /usr/local/bin/wish
) d9 ?2 }+ O! r
split $x /
/ [4 t" ~1 r' Z. n" z
# spilt 将一个list 所有单元输出
6 T; a; e4 D0 O4 u0 N) R
# 第二个argument设定单元的分隔符, 如此处的 /
! R/ `6 K W/ K1 ]& Y: L# } m# a b c
. H, q( P% Q- ?
split $y /
* `! t6 `/ L) T/ R7 O$ M$ }
# {} usr local bin wish
& n$ q% J/ k3 y/ g6 f
# 注意第一个为空单元
# q& }) z- {7 c* m
反函数为join,可将一些单元组成一个list
' c( J' x9 @4 t9 |+ B |
7 m" I" z1 D& y
Lists & Commands:
- R T- u+ s! o/ o0 m
其实tcl 语言本身就是一个list,瞧,最后一个是command或是
. W/ ^- w' Z/ M4 [7 @- {% q
list:
) S' n- T: X1 @3 n
button .b -text "Reset" -command {set x 0}
" V* P, }5 z; {6 F
% y. q2 e X7 blist可以解决一些难以构成的命令:
( L. Y! M0 v. Z, S假设有一个情况,我们写了下列命令:
4 i0 g; b$ y- e) K
button .b -text "Reset" -command "set x $InitValue"
& Y6 Z/ g% k# m. }6 G
; ~! h; K% Z+ V. t此命令的情况是我们希望Reset button按下后把 x设回
: Q$ U) x. s0 {' f& fInitValue,可是天不从人愿,如果$InitValue设定为"10 20"
% {% M+ H3 Z, a1 y- H5 u8 K
则Command变成set x 10 20,引述个数不对了,因多了一个数。
8 P- e8 i1 {7 I$ @如果改成:
" L2 a1 T+ N5 G
button .b -text "Reset" -command {set x $InitValue}
6 ]9 y9 F# k- j5 L) @
则x 值取决于按钮时的InitValue,而非真正的InitValue
3 P3 Q4 V" N. f! B* p
所以可用下列方法解决:
. `; v9 k2 C+ hbutton .b -text "Reset" -command [list set x $initValue]
' U# W- b0 K& {# j9 K+ y+ X: C4 r8 i: s8 c9 ~
tcl.02.03.05 范例: 控制结构: ! M: ~' M f- Z: a
if:
" f6 r7 @$ y: S# I) G* wif 判断 [then] 叙述 elseif 叙述 elseif 叙述 [else] 叙述
6 ^& ?- g. \; l9 d: U5 \2 q# then 与else 皆可省略。
# z+ z* | M5 R# q( ]0 l4 s6 E# S
while: (make b the reverse of a)
$ y+ I4 F0 l/ o% Y
set b ""
" N. Y: T0 l! ^: n0 ^ `( E
set i [expr [llength $a] -1]
* p" |# M( |2 ?7 t# G1 Y; Rwhile {$i >= 0} {
$ m- O$ P* g3 o* X2 Blappend b [lindex $a $i]
* N/ L" l) |% Y/ V2 ~, b3 r9 A3 H" P9 |
incr i -1
& P# o- l/ G. n6 b; U2 B
}
7 S( i2 r6 `# m, H( i% p" I
1 m% j: g- I5 n8 D$ rfor:
8 e8 N- |2 n A2 |set b ""
: L. u# F- Q% c6 {" D$ D2 q
for {set i [expr [llength $a] -1]} {$i >=0} {incr i -1} {
+ W! G2 }: j- x+ G& `2 K" xlappend b [lindex $a $i]
! y9 h# p! g/ r' D5 ~) m}
- {# t5 V. e" |+ a5 s. m7 [& ]4 v
) `! C8 ?! {. m9 _% ^& `, k+ a% uforeach:
& O9 H$ G& q) O1 D
set b ""
( A$ Z, E" a, j0 B' R+ O5 g u
foreach i $a {
: z# H1 y' h$ [; X: D% ^( u a
set b [linset $b 0 $i]
2 b0 ?. \: s$ N" K% @) G9 C
}
+ X, {5 Q% U( P& H- H2 @) u7 l& \& X) _
注意,受限于tcl 语法,大括号不能独立一行:
% \' j& t$ `" s7 y5 `while {}
; R! k$ t3 K9 y{
" g& Q# ^: {4 j9 ] \3 I. h' ?& H
}
, a! f* m, f4 G0 A: f" G
( O: Y6 R! P6 M; A: R/ f' `break与continue同C的用法
3 M" ?$ J$ k! t) C4 Q. E
# o! T8 P) h3 Y- Nswitch:
9 X( H; w- `( l" W$ H
switch $x {
; r* y5 w! ~) f- e7 J
Mon {incr days(Mon)}
6 M0 a4 }9 p6 G* w8 S8 i% U! p {
Tue {incr days(Tue)}
% k& k5 |& F3 I: x7 U* ^3 v- |5 U
default {...}
6 A9 v* a9 f* L7 M" k- e}
- Q5 Q6 E# Q3 a$ z- s: A8 C, S
6 q" R* n: t/ Z* g& [' a
亦可写成:
5 J* V* T u) h; d0 ^1 ?switch $x Mon {...} Tue {...} default {...}
8 b/ W9 y$ P# K8 z或
; x: o" W- V, Z/ l4 u W
switch $x \
0 q& M( R: G) F9 fMon {...} \
- B5 r0 @2 r- E d- x
Tue {...} \
/ S! \8 d+ u* M* W' odefault {...}
6 t9 O8 \- z b6 F4 |. h
6 C/ F# u' T/ b) L+ S5 t+ M如果数个情状的动作相同可用 - 代表。
) \. ^- D- L% Y. y! C; o4 n
switch $x {
2 F, `2 n; P" }: n% w1 -
; Q8 T! _; `" J0 F' r% y
3 -
- J$ R8 U# E/ \0 C; K# |- V8 g
5 -
% W! E0 p6 ~8 x
7 -
& L+ o8 E) X' R# i5 n( l
9 {incr odd}
" Y! n9 }) t4 ^) G- U% f; C4 b1 \
default {incr even}
# E4 ]( j7 E) q, {: n6 B6 M}
( w& k" a1 @/ ^9 Y
2 D& C; V) }/ F* G
tcl.02.03.06 范例: 子程序:
0 h, N7 w7 E7 [8 Q, C. `同csh,tcl也有source 命令:
, r6 _2 |6 K8 o# Z
source tclInit.tcl
9 H. j8 U$ r+ f2 \9 K* X3 ~& m: xprocedure:
+ @$ S; P( }: a8 o8 u
proc name ArgList Body
8 f2 |* Q+ l. K2 C; z
定义一个叫做name 的procedure,
% D4 }5 H) G Z9 e0 @5 B! c8 _2 i如果ArgList的最后一个为args,则此procedure
% k6 S1 H( H! r$ r, m6 o
为不定自变量函数,而args为一list。
6 R6 ~, F* c" M9 o! Z( _' V) Q; a+ ]
global name1 name2 ...
u+ \* U* J6 q$ N7 y4 \ X
使用global中的name1 name2变量,而非自定local变量
& u* C V" k7 Y H
return value
' E5 T, S+ |5 Z5 m
uplevel [level] script1 script2...
; a' B; h* w+ W% P) u3 ]
类似inline函式,把stript1 script2 ...串起来
! k2 j8 s, |+ l0 s) f9 }6 c
然后在上一层中执行,而非在procedure自己的stack内执行
1 M1 W; u# [9 K9 [(可以更改上一层的变量)。
4 {" O: p. S, @5 H0 O! k$ F% M
upvar [level] name localname [name1 localname1] ...
1 b% B& P; M9 R引用上一层的变量name,但是在本procedure内用
0 [9 }% g9 X' T( R# tlocalname存取之。(call by reference)
/ R* `: R! \& @# ]) A; ]
uplevel例:
9 r7 i) a' [0 v- \* v s
proc do {varName first last body} {
) Q0 U8 u9 W: A E" z: B8 Y) oupvar $varName v
7 r: K5 s0 f1 V- @for {set v $first} {$v <= $last} {incr v}
8 M/ n/ y/ E ]' L" ^
uplevel $body
" m2 y8 @: W" h: I* W3 g0 a. _}
3 s: v( G$ e: Q+ |5 `}
* O' n& O/ n" n/ `- b7 g4 p6 u- k
set a {}
3 @, O, i" G3 d8 I: L
do i 1 5 {
c8 g, O+ U( S4 V
lappend a [expr $i*$i]
$ Z6 r; d J+ ?
}
, U7 S6 u& G5 ]" D/ w! X
set a
8 }. F3 a* x$ e& J
# 显示 1 4 9 16 25
N% |" ]0 _! ?# 如果不用uplevel,则$body就不可能存取到 a变量了。
) ^7 a( O8 d9 h% u. g
6 N- d. n5 F/ j5 E5 ?, l2 Gtcl.02.03.07 范例: 错误&特别状况
+ Q) `* X; a4 L) ~. O @Errors& exceptions:
2 `& B9 e b" a) Q& [catch { tcl 程序代码 } messages
/ V$ o* a( E+ \5 W# S8 h#如果程序代码有错,catch return 1,否则为0,
7 |+ y7 J% {( O0 X, P6 m* Q- j) X) r6 ]% `; d
tcl.02.03.08 范例:字符串
5 ~6 @0 G2 Y- R* n' y' w$ @string length
( m6 b: a0 c% GQUOTE: { }
1 Y# i# p1 l: H; m
#但用此法定义字符串,一些特殊键不能用,如跳行直接打RETURN即可,不能用\n
9 [, m5 M0 d, k& e. n
.canvas configure -width ${size}m 以避免使用变量 sizem
- n# b4 N8 R# G9 h; K1 C. D/ \' d! a! g" K7 q8 Z
tcl.02.03.09 范例:其它expr之用法
3 h; c3 H( f0 R" [5 Jexpr 3 << 2
2 k4 a8 I1 z$ `) g6 p
# 0011 -> 1100
9 e0 S& c: `4 Z. L' D' W/ `1 B
expr (3 > 4) || ( 6 <= 7)
- K# X& x; G6 F: q3 x* F# 1
, a. a5 j$ ^% y2 H+ L9 U: ^+ l K; |
" G* r4 f$ q1 I- |
tcl.02.03.10 范例:离开 , s$ d8 l% C8 }3 ]- o6 @" h! w; j) L h
exit
/ ~. K3 N3 O2 K9 o1 ~! e& x; o
; c/ R, \3 y. f' L" o: T& ftcl.02.03.11 一些特殊键 # l2 S5 o& C9 v# c& X1 g; y# w
\a, \b, \f, \n, \r, \t, \v, \ddd (octal value), \xhh (hex value),
- f+ i8 J' j5 n4 f/ I" f\空白
, R+ y% g! |" i2 _8 S( W6 {
) Z0 f) E& A* N0 _- |; e
tcl.03 Patch for Chinese Tk
8 o& o4 n) i9 ^If you want to uudecode the file, you must delete the leading blank first.
; f6 ^; `5 Y' b2 s, o5 S-- jjkao
; w) L% d3 u0 Q2 G0 H" n9 ]/ F
From
ypyau@sunmp.csd.hku.hk Thu Mar 17 09:38:49 1994
" ^3 d2 X J& B QSubject: Re: (fwd) Re: chinese version of Tcl/Tk
& {+ w. w0 N" A- SDate: Tue, 15 Mar 1994 11:49:32 +0800 (WST)
; K4 @- l& j ?5 l' O1 z9 jFrom: "Carl Y.P. Yau"
' B# {/ Y" i/ M$ [/ R
& i# x5 P2 y" ^$ K% g5 L/ i' ~- l% I0 h* M* m* W* m8 }/ n
Hi,
- x ~- M6 g* B8 u1 {, m
+ l9 X3 m2 A# w# jHere's the patch for tkFont.c and the demo for showing Chinese characters.
$ _0 f' ]: M( d: [Remember to have the Chinese Font ready on local Xserver before running
; U9 g5 P7 J) b& i% S8 ~, L/ qthe demo program. It doesn't, in any way, a perfect solution right now. It
" C7 ?$ r G1 G& @% ~- Wis just an ad hoc trial. I am planning to do a more extensive widget support
2 |8 J$ D- C6 g/ J1 _% _& q: X) Fon Chinese Text which is now only available on Text widget. You're welcome
`7 q- x6 |; a& ^1 _6 S+ Gto comment and join.
* y& k% V2 E* Y5 u5 r( m( F6 q. g. _- o( D( g
Cheers,
8 r$ k' L- a9 J( q' M9 Q7 }# }
% W: u# B2 g0 m" CCarl Y.P. Yau
, j) P% B+ h4 e( j$ F
Systems Research Group
A! r9 |- s$ O. v9 S' T2 p# iCS Dept, HKU.
, M5 T9 r$ i" _) o' S9 ]' i" B# X( H& l! T! a
------->>----HERE'S the PATCH for tkFont.c ----------------------------
1 V6 `, _8 M5 [3 c" g66d65
. a) E% O9 k, K$ @
< #define CHIN_CHAR(c) ((char) c & 0x80)
+ w1 m' ^6 B: @
532,534d530
* G, y5 H! l3 O0 |2 [, Y<
8 A* S- G( z8 S l V8 l2 u
< if (CHIN_CHAR(c)) {p++; maxChars--; } /* */
2 H- H. Y) v+ t" O# O) H0 B0 y
<
& P2 x* F) e/ p) G: S2 [3 t) ]/ P# k9 A674d669
! k+ _" e. p8 d; m
< if (CHIN_CHAR(c)) { p++; numChars--; } /* */
) X" j0 P( y$ O8 J
680d674
% K" b2 |: c+ B0 s Y
<
+ S6 Y: T$ [) C
682,686c676
! ^, a/ T6 b0 z! c
< if (CHIN_CHAR(start[0]))
- D6 `3 t* Z+ @2 w: c; |1 P< XDrawString16(display, drawable, gc, startX, y,
1 p% p0 y# |. u
< start, (p - start)/2 );
$ x0 Y6 f( r6 `! Y
< else XDrawString(display, drawable, gc, startX, y,
8 d9 R1 j5 Y' g; C9 l6 ^
< start, p - start);
3 j( g8 D) f7 I9 z8 N! _---
/ \' Z0 M+ X% |/ J
> XDrawString(display, drawable, gc, startX, y, start, p - start);
% U; j; D+ U" [' k/ _722,727c712
. V9 m* e3 S/ M( H2 W9 T< if (CHIN_CHAR(start[0]))
/ _+ f) Q) E4 S3 @* y) N
< XDrawString16(display, drawable, gc, startX, y,
R8 T; O4 _0 {+ u4 V W< start, (p - start)/2);
) M) s+ ^9 Y" u. M< else
, u4 F6 s! Q6 Q( ~3 C
< XDrawString(display, drawable, gc, startX, y,
9 p3 F [% W s. v( U3 o< start, p - start);
" h. a4 p) Q* M; a- r
---
& i, U" X, z. C& f( C, _) c6 U5 R& G
> XDrawString(display, drawable, gc, startX, y, start, p - start);
$ e2 ^4 P: m. i8 s; b------->>-----------Surprisingly short, isn't it-----------------------
" f" N+ H) p1 E3 R# N1 Q8 X, J: V: O& [0 q' Y* J
------<<--- Here's the uuencoded tcl demo program-------------------------
$ W- o8 }% Z7 B+ q8 }3 |$ V5 S
begin 666 ChinText.tcl
0 T. m" O, ^6 Y$ n1 J) RM(R *(R!4:&ES('!R;V=R86T@:7,@86X@861A<'1A=&EO;B!F<F]M(&UK4W1Y M97)T5VET:%1A9W,@ M+3$@?B,@(&ES(?="E;&

@:6YS=&%L;&5D(&QO8V%L;'DN"B,*"G!R;V,@:6YS" M9&EU;2UR+6YO<FUA;?TM,38M,38P+3<R+3<F]GW<@=&5X="!A2!3='EL97,B"B @("!W;2!I
, P6 Y6 k q5 T" b( x% \$ ?M8V]N;F%M92 N(")497AT(%-T>6QE'0@+G0@+7)E;&EE9B!R86ES960@
5 }& U; y& V1 Y% {( h1 S/ Y" AM+6)D(#(@+7ES8W)O;&QC;VUM86YD("(N<R!S970B("US971G<FEE<FUA;?TM,38M,38P+3<R+3<W!L87D@<W1Y;&5S?@H@(? M(? H* @(?!A8VL@+G0@+65X<&%N9?!Y97,@+69I;&

@8F]T: M(?UF:6QL(?D*(? )I9VAT M(?US:61E(&)O='1O;2 M9FEL;"!X"B @("!P86-K("YS("US:61E(' @(?!A8VL@+F]K M+7)E;&EE9B!F;&%T(?UC;VUM86YD(?(N="!Y=FEE=R(*(" @(?!S8W)O;&QB87(@+G,@ M:&5I9VAT(#(X?B W,? @(?UW:61T:? H)(? M7>6)I9R M9F]N=" M061O8F4M2&5L=F5T:6-A+4)O
& d( c4 U2 l @M;&0M4BU.;W)M86PM*BTR-# M*@H@(" @:68@>UMT:R!C;VQO<FUO9&5L("Y= M @(?!](&5L<F5L:65F(?)A:7-E9?!<?@D)+6)O<F1EPH)+G0@=&%G(&-O;F9I9W5R92!C;VQO<C$@+6)A8VMG<F]U;F0@8FQA8VL@+6)O<F1E<?@D)+6)O<F1E3(U"B @(" N="!T86<@8V]N9FEG=7)E(&9G<W1I<'!L92 H@(? M @+G0@="&%G(&-O;F9I9W5R92!U;F1E6]U('1O(&1I6QE<RX@($1I<W!L87D@<G17:71H5&%G<F]L;&5D(?5S:6YG(&$@;65C:&%N:7-M?F-A;&QE9?!]>6QE6QE<R!A[.O
) g* p$ x% b% ?: p6 KMM,>

U[7;LLK4QKSDHZS'I\#OO:W!ZM*[R-6[N:&C?2!C:&EN"B @("!I;G-E
" t4 n0 a% A2 L$ j9 `7 @M<G17:71H5&%G<G17:71H5&%G<G17:71H5&%GPHR+B!#;VQO<BY](&)I @:6YS97)T5VET:%1A9W,@+G0@ M9PH@(?>R @66]U(&-A;B!C:&%N9V4@96ET
( @/ Z0 h1 w& ~# d1 i0 m# o, e, A
M:&5R('1H92!]"B @("!I;G-E<G17:71H5&%GR!OPIC;VQO<G17:71H5&%G<G17:71H5&%GR @66]U(&-A;B!C875S92!E:71H97(@=&AE
6 {9 h, a. h/ z8 I1 M$ `1 ?
M('T*(" @(&EN<&QE" M<G17:71H5&%G M86='S("YT(&9O<F5G<&QE"B'>R!R
" y* l8 Q1 N/ H" ~3 d- z$ U( E
M86YG97,@;V8@=&5X="X*?0H@(" @:6YS97)T5VET:%1A9W,@+G0@>;PHU+B S
! W. q: k4 e9 ~$ T# Y
M+40@969F96-T<RY](&)I9PH@(" @:6YS97)T5VET:%1A9W,@+G0@>R @66]U
4 o! q# m' C% s3 }$ H
M(&-A;B!A<B!T:&4@8F%C:V=R;W5N9"!T;R!B92!DRX*?0H@
" C" U( {! Y D& X7 I' |0 v
M(" @:6YS97)T5VET:%1A9W,@+G0@>;PHV+B!9970@=&\@8V]M92Y](&)I9PH@
! t3 i1 z# ^. e( O" H# H
M(" @:6YS97)T5VET:%1A9W,@+G0@>R @36]R92!D:7-P;&%Y(&5F9F5C=',@
& d8 l; p; E. F% FM=VEL;"!B92!C;VUI;F<@<V]O;BP@2!T;R!C
+ f2 R% ?8 p) u) S# q# o
M:&%N9V4@;&EN92!J=7-T:69I8V%T:6]N(&%N9"!P97)H87!S(&QI;F4@< end @H* ;(#Q!;GDM16YT97(^(?)F;V-U
% w$ a. ~; K( L+ M' h0 t: H. q9 {& G7 |8 I
tcl.98 示范程序
1 g: k: E# U) u5 p- Y
4 E* C1 N# V! Itcl.98.01 power
: k9 I& Q/ W- _5 |#!/usr/local/bin/wish -f
/ v! I8 R; c0 ?! q
proc power {base p} {
* \* S2 H+ j% V: V/ ~9 S
set result 1
! Q: a& B+ r3 c. h5 C4 Lwhile {$p > 0} {
2 ]& ?; h& D5 [* M6 X; Nset result [expr $result*$base]
9 S3 |: y8 d( k+ E2 j* s
incr p -1
- Q& Q' g a" d% `9 z# P}
' s1 N9 f+ I* i ]- O% z/ \; wreturn $result
) n$ h# B( g7 L. k* T! ^
}
8 S `) U3 J# a. C! p* y
entry .base -width 6 -relief sunken -textvariable base
# K, w, e0 Y5 b
label .label1 -text "to the power"
4 |0 N% b8 Z2 o
entry .power -width 6 -relief sunken -textvariable power
( _' i; Z7 L+ I4 J# _, }
label .label2 -text "is"
: T$ w5 M6 x+ r* E4 z/ |label .result -textvariable result
$ L6 Z, Z1 U C1 V4 A8 G/ _pack .base .label1 .power .label2 .result -side left -padx 1m -pady 2m
# m- }$ o A9 G9 W6 h# y6 y
bind .base {set result [power $base $power]}
) p; ]1 X/ F5 u, Y3 f& ]
bind .power {set result [power $base $power]}
4 l: i+ N# t5 ] g( M
# 注: -relief sunken的意思是凹陷的轮廓。
. T9 A! z1 V8 a+ p1 R2 F6 J
# 本程序产生一个窗口:
4 q9 V8 r! A& m: t& v* t9 U
# ┌──────────────────────────┐
/ N. ?& d" T( O! z* u9 `2 \
# │〔 A 〕to the power 〔 B 〕 is 〔 〕│
9 t% H0 m& x' I5 y( R# └──────────────────────────┘
6 B/ m" [2 X# V9 W% ^
# 只要输入A,B就可以得到A的B次方。
0 {! d* V' R$ i* d
1 T7 h2 |- t3 t; c
' B, |# X! b. ?tcl.98.02 window/history
; o+ N( o# B) }# O" Y4 H4 ~ B#!/usr/local/bin/wish -f
3 R+ N/ W; u& Y l o% C7 Dset id 0
& ^! I9 {1 F3 [( M# @; l" rentry .entry -width 30 -relief sunken -textvariable cmd
9 L% ^5 X+ d2 O$ h' Lpack .entry -padx 1m -pady 1m
) J) W! N8 q% f) q5 v S4 n
# 显示输入行
7 b( _+ @" T. M) g2 ubind .entry {
) f* c% H' m: D) R4 `; n
# 当.entry 收到这个event时
, T9 _( o) G# P9 Z/ J/ Kset id [incr id]
3 C a) o# H7 \9 T, W6 Mif {$id > 5} {
( w. r" S, B2 B7 g$ Zdestroy .b[expr $id -5]
( B% T" W C3 }/ W, p( G; E2 P
# <- tcl的变量名也可以用凑的, 删除第5次前的命令
* e- e) F9 l3 I$ r/ e
}
# B: [; |& c% h& T$ K1 D8 X& p' gbutton .b$id -command "exec <@stdin >@stdout $cmd" -text $cmd
8 [- ~# W8 {& x) `pack .b$id -fill x
" y( J! P; s: g# j4 D# <- 显示按钮,且水平(x)方向填满。
8 S4 v d1 R% i1 p8 J4 g.b$id invoke
' U- v+ C. \3 Q; E$ `# <- 仿真按钮被按下
; f' q) B6 {+ Z
.entry delete 0 end
9 `0 _/ B6 l& C+ O |+ T' P+ }
# <- 清除输入行
5 N/ U! E0 |. s% M}
" s) h ~0 y `% y; Q
#end of file
1 f$ J- s* }5 z0 p5 e `2 B& S: Q1 {
# 本程序产生一个输入行,可以下命令,并且把过去的5个命令记录下来,
- j# G+ I8 N- Q0 J2 P* B$ l0 T
# 用按钮就可以执行。
$ ]+ w: x5 |& q
, n4 }) h' u2 A4 o/ _
% N; V6 t2 r, L& TIf you have any question for this FAQ, please contact
; i$ ~( c, J+ }% a. v: V' B
environ@ev004.ev.nctu.edu.tw.