快速图形界面开发语言Tcl/Tk
0.前言.在unix like系统下,有没有像VB一样的快速图象界面开发工
具呢?很多人大概马上会想到Kylix,基于Java的一些图形开发工具
。但是数百兆的安装大小对于一些简单用途是否小题大做了呢?其实,
很多脚本语言如Perl,Python本身就已经包含Tk库,可以用来建构图
形界面。不过,这些也都是数十兆的软件包,图形也并非主要用途,Tk
库往往不是缺省就包含的。那么设想有这样一种工具,它可以逐行运
行,即时显示图象效果和事件驱动效果,拥有简单的语法提示,又可
简单的回溯修改,系统不过数兆,除命令行外还拥有简单的类似VB,Kylix
的窗口界面开发工具,可以简单移植到各种软件平台,包括Palm掌上
电脑,软件不需要一行修改,你会考虑使用它吗?
在你的X Window界面下的Xterm里面输入wish,或者xwish,wish80,tix
等,有相当大概率会出现一个控制台和一个空白的窗口,恭喜,在你
不知道的时候,您已经拥有了它。
1.特点Tk是一套在Unix like,Mac,Windows下可移植的快速图形开发
工具ToolKit的缩写。它有多种语言界面,如C,Perl,Python等。而其
中其中常见也最方便短小的界面语言是Tcl。Tcl/Tk在有X window的unix
like系统下基本是缺省配置,在windows下的wrapper也不过几百k。
相对于其他图形界面开发语言来说实在是短小精悍。通过Visual Tcl,
你可以获得如同Visual Basic一样简单的快速开发能力。而Visual Tcl
这样一个强大的工具本身全部均为Tcl/Tk写成,大小不过数兆,可见
它的能力和容易程度。
它的缺点是:Tcl语言是一种几乎没有数据类型的语言!这是短小、
可移植带来的代价。它是一种几乎只用list作数据类型的语言,构造
十分精巧,写起它的语法解释程序时很简单。反过来,在写应用程序
时面对复杂的控制和计算有点麻烦(但是仍然能够解决,而且也不是
他的设计目的)。本文在此仅为介绍,细节请自己阅读mannual。相
关章节是n,例man n entry。
windows下的tcl/tk手册为一个HLP文件。
Tcl一个著名的扩展就是expect,可以作用来自动连接telnet等script
无法处理的智能应答工作。
Tcl/Tk的基本系统窗口类型比较少,常见的扩展有Tix,和面向对象的
版本itcl/itk(incr Tcl)。两者已包含在大多数Tcl/Tk系统中。
Tcl/Tk可以通过装载package来扩展命令和窗口类型。
可以通过下载别人写好的package,自己编写package,或者将Tcl/Tk
嵌入到C来完成复杂任务。
2。需求与安装、运行在unix like系统(Sun,Linux)下,Tcl/Tk需
要X支持(废话),但是Tcl本身不需要。在Mac、Windows下,需要安
装Tcl/Tk的移植版本。可以在http://dev.scriptics.com下载,最新
版本在8.3左右(2003年初)。您也许还需要Visual Tcl工具包,可
以在同一网址下载,它需要最新版本的Tcl/Tk支持。windows下全部
开发系统下载约5.2M,其中tcl/tk 2.5M(含手册,C调用Tcl/Tk的头
文件,库文件),Visual Tcl 2.9M。相对于Tk的C开发包庞大的身材
(当然也对应强大的功能),在简单的窗口开发中您也可以考虑采取C
内嵌Tcl/Tk的开发模式。
安装时Mac/Windows直接运行安装程序。
unix like系统下Tcl/Tk一般作为一个部件在安装X Window同时就装
好了(因为很小),没有安装的情况下也有rpm,binary.gz等包可以
安装。
windows下unix仿真程序cygwin32系统里面也包含Tcl/Tk。
运行Tcl语言的命令行程序名为tclsh,也许包含软件版本,如tclsh83
。cygwin里面的为cygtclsh83.exe。
运行Tk图形界面的命令为wish,同样可能包含数字后缀或者其他前缀
。
Tix,itcl,itk的命令行程序名分别是tix,itclsh,itkwish。
如果执行命令找不到而软件已安装,请将包含上述命令的路径包含到
您的path变量里面。
in unix(~/.profile)加入如下行: set path=$path:/local/bin/tcl/
(缺省不需要,因为就在X目录或者/bin里面就有)in windows(autoexec.bat)
加入如下行: path %path%;"c:Program FilesTclBin"具体目
录名在此仅为举例,不一定和您安装的目录一致,请自己修改。
Tcl可以被编译(须购买相应软件,可以提高运行速度),或者在windows
下直接wrap成一个独立运行的可执行文件(使用Visual Tcl工具包里
面的freewrap objectfile.tcl)。在普通模式下tcl在运行时也被编
译为机器无关的bytecode,不过你不需要知道细节。
3.Tcl简介
3.1 基础
Tcl语句为 Command [-option1 value1 [-option2 value2...] arg1 [arg2 arg3...]
在控制台输入命令后回车,命令即被执行并打
印当前命令的返回值。当一行写不下时可用续行,欲在一行包含多个语句可用;分开。
比如exec ls *.cTcl里面基本只有四种数据类型:简单字符串,数组,
表,变量。而字符串可以看作表的最基本单位,变量可以看作系统数
组里面以变量名为下标的字符串。平常所用的变量,命令等全部是字符串。
变量可以用variable来定义,通过set来赋值,unset来消除。变量用$
开头。
set a "this is good"
将$a赋值为"this is good"
set a [expr 3+$b]
此命令将3+$b的结果赋值给$a。
不带第二个参数将返回$a的值因为Tcl
里面没有数字类型,必须用expr来求字符串表达式的数学运算。
[]表示将括号内的表达式求值。在Tcl里面要使用命令的结果作为另一个命令的参数,就要用[]。
{}和()在Tcl里面已经有其他含义。
数组(或者说哈希表hash table)的下标是表(list),或者最简单的表:
不含空格和特殊字符的字符串,下标用()表示。
它可以用array来定义。
set ms(haha) a
set b ms
set c haha
则$b($c)的值为a。
变量或者数组无需定义即可使用,不过第一次使用时必须赋值。
表包含0到多个元素。
set a "this is a pen"
set b {this is a pen}a和b是等价的。
a的第一个元素是this,第二个是is,余下依次类推。
如果没有界定符,缺省界定符是空格,即set a "asdfg"和set a {asdfg}
和set a asdfg是等价的。
set a this返回只有一个元素this的表$a,或者说简单字符串$a。
表可以是空表set a ""set b {}表的元素也可以是表,空表和没有元
素是不同的如{a}不同于{a {}},{}不同于{{}}。
set a {this is a list {a b c}}则表的第5个元素是{a b c}
可以用lindex a n
来取得a的第n+1个元素,n必须为数字。因为元素位置是从0开始的。
比如lindex a 4返回{a b c}linsert a index元素1元素2...返回在
在表a的位置index处插入元素后的新表,注意a是变量的情况下表a本
身没有变化。
set a [linsert $a 2 not]将$a变为{this is not a list {a b c}},
如果漏了$,则$a为{a not}。仅linsert $a 2 not命令不会改变$a。
表的其他操作命令为lappend list llength lrange lreplace lsearch
lsort,具体请参看手册。
set ms() heihei其实是将ms({})赋值为heihei。
数组的下标还可以是{a {b c}}等复杂形式,虽然我们平时最好不要
这么用。
如果需要二维数组,可以使用set array($a,$b) value的变通形式,
虽然其实数组其实是下标为"$a,$b"的字符串组成的一维数组,但是
大多数情况下可行。
""和{}的区别是是否作代换。
""内对变量$和作变换而{}保持不变。
试执行set a coolputs "$a haha "(返回cool haha回车)
和set a coolputs {$a haha } (返回$a haha 原样的结果)
, , ,$,/等含义同C语言和shell。
puts是打印结果的命令,当第一个参数代表文件时输出到文件(channel)。
对应为gets channel ?varName?注意和puts不同,gets必须带文件参数
3。2流程控制if语句if expression {statement} ?else {statement2}?expression
为一简单字符串或返回简单字符串的[语句*****]调用,{}内为执行的语句,类型为
一个表,else部分可选。
为了语法的美观,当目前行遗留有未配对的{或者"作用时,回车换行
不代表语句结束,这对于所有的表均成立。
set a 3if $a>0&&$a<5 {puts $aincr a}expression用法类似于C语
言。
incr a返回$a代表的数字加一,$a本身产生变化。
for语句for {start} {expression} {next} {statement}例如for {set
i 0} {$i<5} {incr i} {puts $i}注意if里面的判断可以不用{},
但是for里面的就必须用,因为if里面只判断一次,而如果for里面不
用{},则判断语句在第一次解析时就已经决定,以后不再变化。在上
例中就是永远返回第一次的值"0<5",循环不会结束了……注意这也
是大多数使用{}而非""的原因,即不希望立刻被语法解析。
foreach a {aa bb cc} {puts $a}返回aabbcc该命令依次将variable
代换为列表元素并执行
其他还有while break continue等语句,用法均类似C。
switch命令用法不同。
switch string pattern1 {expression1} pattern2 {expression2}
当string符合pattern时返回对应的expression值多行写法switch
xyz { a - b { # Correct Comment Placement format 1 } a* {format
2} default {format 3}}注意因为是返回表达式,在此不需要C语
言里面的break语句。
该语句可以带-regex选项匹配正则表达式。
函数proc name args body 例set ss "aa"proc newcmd {a b c} {upvar
$ss dglobal ssputs "$d is $b $d"set $ss areturn $c}注意如果
不用upvar重命名或者global指出为全局变量,子程序不能直接用上
级或者全局变量
3。3字符串和文件处理format命令类似于printf语句的输出风格set
a 1format "%03d haha " $a返回"001 haha "这个字符串对字符
串的其他处理用string命令string bytelength $a取$a按byte计算的
长度(因为string可能不是英文)
string compare ,string equal,string first,string index,string
is,string last,string length,string map,string match等命
令自己查mannual。
如果没有手册,可以使用tcl语言的模糊查找功能。
只要不引起歧义,命令名可以只输入一部分。如果有歧义,tcl会告
诉你匹配的命令列表。
输入命令时,如果参数或者子命令错误,通常会告诉你可以使用的参
数或者子命令列表输入string atcl输出错误信息bad option "a": must
be compare, first, index, last, length, match, range, tolower,
toupper, trim, trimleft, trimright, wordend, or wordstart输
入stringtcl输出错误信息wrong # args: should be "string option
arg ?arg ...?"输入stcl输出错误信息,包含所有s开头的命令ambiguous
command name "s": scale scan scrollbar seek selection set socket
source split string subst switch输入?Tcl给出所有可用命令
获得系统时间用clock命令clock current 获得当前时间(数字表示)
clock format [clock current]获得当前时间(字符串表示)
捕获错误catch {script}当出错时返回一个非0值。用此命令可以防
止因为局部错误退出整个程序。
3。4系统命令和eval在tcksh里面可以直接执行系统命令,如dir,ls,pwd
等。注意在作为脚本执行时这是不正规的,也无法在[]内解析。
这时应该用exec syscommand args args来执行eval可以按tcl语法解
析字符串,因为tcl语言对语句仅解析一遍,当使用glob等返回匹配
列表的命令时很有用。
set ll [glob *.tcl]返回{a.tcl b.tcl c.tcl}虽然puts $ll显示a.tcl
b.tcl c.tcl但是exec ls $ll时却出错,因为这相当于执行exec ls
{a.tcl b.tcl c.tcl}而不是exec ls a.tcl b.tcl c.tcl此时应该
用eval exec ls $ll对文件和目录的操作(内容读写除外)和获得状
态,大部分使用file命令,它的子命令为atime, attributes, copy,
delete, dirname, executable, exists, extension, isdirectory,
isfile, join, lstat, mtime, mkdir, nativename, owned, pathtype,
readable, readlink, rename, rootname, size, split, stat, tail,
type, volumes, or writable大部分可直接望文生义。
pwd和cd是tcl的内建命令。
3。5文件输入输出类似C语言set f [open $filename w]puts $f "haha"close
$f将haha写进$filename为名的文件。
open的方式为w写r读a添加+同时可读写的组合。
set a [gets $f]读一行set a [read $f]全部set a [read $f 300]
读300字节eof $f返回$f是否已经结束tell $f当前位置seek $f 100
start/current/end文件位置移动到开始/当前/结尾100字节后处。
3。6杂项执行其他tcl文件用source文件名命令。
载入库文件使用package require pkg_asdf 命令,package其他子命
令为forget, ifneeded, names, provide, require, unknown, vcompare,
versions, or vsatisfies为了防止库文件命令和本程序名字冲突,
库一般使用namespace命令创建新命名空间。库带有版本控制。
例如,Http库内的函数调用方法为::http::config类似于C++的写法,
一般最前面的::可以省略,直接写成http::config如果是载入动态链
接库(unix下的.so或者windows下的dll文件)里面的命令和变量,使
用load文件名。
如果写较为复杂的可重用程序,可以考虑使用itcl,面向对象的tcl
语言,它支持继承,重载,属性,方法,私有属性等。
4。Tk简介运行wish程序,出现一个控制台(console)和一个最高层
窗口(toplevel)。
试在控制台执行以下程序button .b1 -text "Hello! World!" -command
{destroy .b1}pack .b1然后点击出现的窗口。恭喜,你已经建立了
一个GUI的程序。
窗口的名字有如下形式.window1.window2.windows3.....最高层窗口
的名字是".",它包含的子窗口都带有".a",".b",".c"的形式。如果.a
是一个frame等可以包含下级窗口的窗口。则它里面的窗口则有".a.s1",".a.s2"
的形式。它称为pathName,其名字反映了层次关系。
常用窗口有button,entry,radiobutton,checkbutton,frame,listbox,text,canvas,label
等。
4。1创建button pathName ?options? 定义一个名为pathname的button
窗口,带有options等性质。同时创建了一个同名的命令,用来执行
和这个窗口相关的操作。
button 的性质有-activebackground -cursor -highlightthickness -takefocus-activeforeground -disabledforeground -image -text-anchor -font -justify -textvariable-background -foreground -padx -underline-bitmap
-highlightbackground -pady -wraplength-borderwidth -highlightcolor -relief
其中text是按钮上的文字,command是被按下时执行的命令。
background(可缩写成bg)和foreground是按钮的背景和字体颜色颜
色可以是X定义的颜色字符串,如red,blue,yellow,或者#99c,#9934FF,#999001023
形式的十六进制字符串,数字必须为依次为红,绿,蓝三个等长的数
字。类似于html里面的定义方法。
font是字体,用font create创建,font configure配置font create
bigunder -size 20 -family {Ms Gothic} -underline 1它的可选
属性为-family, -size, -weight, -slant, -underline, or -overstrike,
分别对应名称,大小,是否有粗体,斜体,下划,上划线性质。
-relief是3D类型,值为raised, sunken, flat, ridge, solid, and
groove,分别为凸起,凹陷,平,边框凸起,平边框,边框凹陷.
entry 为输入字符串的窗口-background -highlightbackground -insertontime -selectforeground-borderwidth -highlightcolor -insertwidth -takefocus-cursor -highlightthickness -justify -textvariable-exportselection
-insertbackground -relief -xscrollcommand-font -insertborderwidth -selectbackground-foreground -insertofftime -selectborderwidthtextvariable
指定的变量就是输入的字符串,可读也可写在wish的控制台输入entry
.e -textvariable as(注意和incr,set一样,此处定义不用$)
pack .e然后里面输入几个字符puts $as看看$as是否如同输入set $as
aaa看看entry里面的字符是否随之变化。
如果窗口建立后发现属性设置错误,可以用pathname configure -option
value来改正。
例输入.e conf 返回.e的全部属性列表,每个属性列表分别包含参数
名,属性名,所属类,缺省值,当前值。
.e conf -fg blue输入框里面的字体变成蓝色。
4。2安放前面定义一个窗口后立刻使用pack .pathname ?-options?,
这是因为刚定义时窗口还没有安放到上级窗口里面,这个时候是不可
见的。
-after other排在某同级窗口后面-anchor anchor值为n,s,e,w或其
组合sw,se,nw,ne。e,s,w,n分别指东南西北,也就是左上右下-before
other-expand boolean boolen为1或0。是否随上级窗口变化大小-fill
style为x,y或both。是否充满某个方向-in other放在其他窗口内-ipadx
amount-ipady amount-padx amount和周围的间隔,可以是象素如5,
或者屏幕距离1.3c,20m(c,m分别代表厘米,毫米)
-pady amount-side side值为left, right, top, or bottom.缺省为top.
pack的安排很灵活,当toplevel或者上级窗口变化时能够随之变化,
但是和人类的直觉有点不一致。
需要安排复杂位置时可以使用frame窗口分层次安放。这是最基本的
安放方法。
frmae .f -expand 1 -fill bothbutton .f.bentry .f.epack .f .f.e
.f.b如果pack错误可以重新用新的参数pack一次,只改变放置方式
。
如果想销毁窗口destroy .f查看所有子窗口winfo children .winfo
children .fwinfo还可以查看窗口的很多其他信息。
其他的安放方式有:
place window option value ?option value ...? place configure
window option value ?option value ...? place forget window
place info window place slaves window 可选属性为-in master-x
location -relx location -y location-rely location-anchor where-width
size象素点-relwidth size和主窗口比例-relwidth 1.0-width 5 makes
the slave 5 pixels wider than the master. -height size-relheight
size-bordermode mode其中x,y,width,height都是用象素(和屏幕
宽度)作单位,rel前缀的用主窗口比例作单位,变化范围0.0到1.0,
二者可以并用。
第三种gridgrid .base.button -row 1 -column 0 -columespan 3行
和列都从0开始算起。上面的命令将.base.button放在.base窗口里面,
排在第2行第1列,宽3列。
列宽由本列最宽的窗口决定。rowspan同上,可选。
该命令同样有-padx,-pady,-sticky(类似pack的anchor)-in otherwindow
属性grid rowconfigure $master $index ?-option?定义$master窗
口内第index个row的排法。属性-minsize, -weight and -pad.
radiobutton有-value,-variable属性,一组radiobutton公用一个variable,
它的值就是选定的那个按钮的value属性。
checkbutton只有-variable属性,反映它按下与否。
label标签,用来指示旁边的窗口的用途,无交互作用。
scrollbar滚动条scrollbar .sc -after .t -fill y -side right -command
".t yview"-orient 指示是横是竖,值为horizontal或vertical -command
滑动时执行的命令。基本都是和它联系的窗口的xview或者yview命令
。
上面命令建立一个竖的滚动条贴在.t窗口右边,并带动它滚动常用的
可滚动窗口有entry,listbox,text和canvas窗口。
窗口建立后想再更改其属性使用configurepathname configure ?-option?
value例.t conf -bg red获得其属性pathname cget -option取得option
的值
4。3bind命令使某个窗口发生指定事件时执行一系列命令bind pathname
?sequence? {script}例bind .e <Return> {open $as r}任何时候
在.e里面按下回车键时打开输入文件名代表的文件。
事件sequence为Control Mod2, M2Shift Mod3, M3 Lock Mod4, M4Button1,
B1 Mod5, M5 Button2, B2 Meta, MButton3, B3 AltButton4, B4 DoubleButton5,
B5 TripleMod1, M1和按键或者Activate Enter MapButtonPress, Button Expose MotionButtonRelease FocusIn MouseWheel Circulate FocusOut PropertyColormap Gravity ReparentConfigure KeyPress,
Key UnmapDeactivate KeyRelease VisibilityDestroy Leave窗口
事件的组合,Any表示任意一种修饰(如Ctrl,Alt)。
<1>鼠标左键单击a (注意不含<>)a被按下,相当于<key-a>的简写<Double-Button-1>
鼠标左键双击<Control-Key-F1>ctrl-F1被按下<Control-Key-c> Ctrl-c<Enter>
鼠标进入窗口在script里面可以用%f,%K等参数获得进一步信息。
常用的有%b被按下的按钮。注意3键鼠标左中右分别为123%k被按下的
键盘键,数字%t事件发生的时间,单位为毫秒%x%y鼠标指针位置,从
当前窗口算起%A被按下的键盘键,单个字母%D滚轮鼠标的滚动值%K以"F1","Alt_L","a"
表示的系统键表示%N以数字表示的系统键表示%T时间类型%W当前窗口%X%Y
鼠标指针位置,从根窗口算起(大多数情况,即屏幕左上角)
用event add <<event_virtual>> <event_simple>可以定义虚拟事件,
从而把多个不同的事件用同一方法处理,比如把ctrl-V和Shift-Ins
都定义为<<paste>>event delete删除虚拟事件
4。4 listbox pathname ?option?列表框pathName curselection返
回当前选择的项目列表pathName insert index ?element element ...?
加入条目,index可以是数字或者end,从0开始计数pathName delete
first ?last?pathName get first ?last?如名称pathName see index
将第index条移动到当前可见范围(因为它是可滚动的,see和xview,yview
一样是text,canvas等可滚动窗口共有的属性)
属性-wrap(一行长度超过右边界是否折行显示)-width,-height
text pathname ?option?多行文本窗口很多命令使用如下位置参数》
绝对字符位置index1.0第一行第1个字符2.3第2行第4列end尾部@30,45
在象素点30,45处的字符》相对字符坐标modifier+/-count lines/chars
例+3 chars从指定位置再向后3个字符linestartlineendwordstartwordend
移动到行/字的首/尾
常用命令pathname get index1 ?index2?取得index1和index2之间的
文字(包含tag属性)
pathname dump -text index1 ?index2?(仅输出文字)比如set a [.t
get 1.0 end]就将.t的全部内容赋值给$apathName insert index chars
?tagList chars tagList ...?插入一段文字,可以带颜色,大小等tag
指定的属性tagList是用pathName tag configure tagName ?option?
?value? ?option value ...?定义的一个属性标签比如.t tag configure
fly -bg red -fg blue.t insert end "I like this" fly就在最后
插入红色背景蓝色文字的I like this..t tag add fly 1.0 1.5 2.5
2.7这将1.0到1.4和2.5-2.6这几个字符变成红底蓝字类似有tag delete
操作有一个缺省的tag名为sel对当前选择文字起作用。
pathName tag bind tagName ?sequence? ?script?将有tagname属性
的字符发生的事件联系到处理程序pathname window create newpathname
?option?在窗口内建立别的子窗口。
pathName search ?switches? pattern index ?stopIndex?寻找指定
字符串,返回第一个发现的位置switch为-forwards-backwards-exact-regexp-nocase-count
varName-elidepathName mark option ?arg arg ...?设置mark位置,
该mark名称可以作为位置参数使用
4。5 Canvascanvas是用来画图的。
canvas pathname ?option?pathname create type arg arg ?option?
注意如果要对该对象进一步操作,一定要指定tag,这里的tag意义和text
里面不一样,是对象的代号。
canvas .c pack .c.c create oval 1 1 300 300 -fill red -tags
o1在.c画了一个红色的园,标签为o1..c move o1 20 30将o1向右下
移动20,30象素scale是放大,delete是删除,bind联系命令,raise/lower
提高降低上下顺序(因为会互相遮蔽)
.c postscript -file a.ps将.c的内容存到a.ps文件里面.c itemconfigure
o1 -fill blue将o1的填充换为蓝色all是一个包含所有对象的tag-dash
pattern线条类型-outline color线条颜色对象类型弦,饼:pathName
create arc x1 y1 x2 y2?option value option value ...?-extent
degrees-start degrees-style type可选为pieslice chord arc位
图pathName create bitmap x y?option value option value ...?-bitmap
bitmap-foreground color-background color图片pathName create
image x y?option value option value ...?-image nameimage是
用image create bitmap|photo -file filename定义的图片bitmap与
之类似属性有-gamma -height -width除了用-file也可以用-data {
字符串}来定义,字符串是对应文件的uuencode结果
线pathName create line x1 y1... xn yn?option value option value
...?-arrow where可选first,last,both,none-smooth-splinesteps
number-fill -width椭圆pathName create oval x1 y1 x2 y2?option
value option value ...?多边形pathName create polygon x1 y1
... xn yn?option value option value ...?矩形pathName create
rectangle x1 y1 x2 y2?option value option value ...?文字pathName
create text x y?option value option value ...?-font fontName-text
string-width lineLength子窗口pathName create windowx y?option
value option value ...?
注意带有scrollbar的时候请设置-scrollregion {x1 y1 x2 y2}属性
和-xscrollcommand {$hscroll set}和/或对应的y方向属性同时带有x,y
方向的scrollbar时一般用如下安放法frame .fcanvas .f.cs -scrollregion
{x1 y1 x2 y2} -xscrollcommand {.f.hscroll set} -yscrollcommand
{.f.vscroll set}scrollbar .f.hscroll -orient h -command {.f.cs
xview}scrollbar .f.vscroll -command {.f.cs yview}grid .f.cs
-row 0 -column 0 -sticky newsgrid .f.hscroll -row 1 -column
0 -sticky newsgrid .f.vscroll -row 0 -column 1 -sticky newspack
.f -expand 1 -fill both
4。5系统对话框tk_getOpenFile ?-filetypes filePatternList?返
回文件名tk_getSaveFile ?-filetypes filePatternList?同上set types
{
{{Text Files} {.txt} }
{{TCL Scripts} {.tcl} }
{{C Source Files} {.c} TEXT}
{{GIF Files} {.gif} }
{{GIF Files} {} GIFF}
{{All Files} * }}set filename [tk_getOpenFile
-filetypes $types]
if {$filename != ""} {
# Open the file ...}因为tk没有好的文件选择组件(在扩展的Tix
和itk里面有),这两个很好用。
部分tk还有tk_getColor等对话框
4。6菜单menu pathName ?options?-type menubar, tearoff, or normal
当为tearoff时可以移动位置,menubar横向menu窗口可以也必须被nemubar
和toplevel调用,是菜单的主体,因为它本身是无法被pack到窗口上
的。
pathName activate index添加条目pathName add type ?option value
option value ...?type为cascade, checkbutton, command, radiobutton,
or separator,-tearoff是否可以被撕下(与一般情况兼容的话最好
设为0)
-label text-accelerator value快捷键-command value指定选择时
使用的命令-menu value当类型为cascade时指定下级菜单-underline
value第value个字符有下划线pathname insert index type option...pathName
delete index1 ?index2?菜单条可以有bitmap,颜色等属性
menubutton pathName ?options? -menu指定下拉菜单,由menu定义
这个一般作窗口菜单,因为可以自由安放位置(比如把help菜单安放
在最右)
toplevel pathname ?option?在当前总窗口外创一个新的最上层窗口,
比如运行对话框时。
-menu指定一个menu为窗口菜单toplevel窗口可以用wm命令进行隐藏,
显示,最小化等操作。
wm command pathname可选命令aspect, client, command, deiconify,
focusmodel, frame, geometry, grid, group, iconbitmap, iconify,
iconmask, iconname, iconposition, iconwindow, maxsize(最大
化), minsize, overrideredirect, positionfrom, protocol, resizable
(是否固定大小), sizefrom(改变大小), state, title(标题),
transient, or withdraw(隐藏)
tk_popup menu x y弹出一个pop菜单,注意x y是相对于屏幕而非窗
口bind .t <2> {tk_popup .rightbuttonmenu %X %Y}
4。7消息提示和对话框dialogvwaitafter 100after控制台console hide/show/title
另开一个新Tcl进程
5。大型程序在tcl内执行某个.tcl脚本文件的方法source filename
隔离名字空间namespace命令,定义后使用aa::get形式的变量和函数
使用Http package可以读取WWW网页,itk,Tix扩展package可以增加
复杂的窗体类型
tcl的命令的有限的,也不能指望用内置语句编出什么复杂的底层功
能如多媒体、复杂计算来,tcl/tk主要也不是用来作这个。
一般的扩展其功能的方法为:
用exec执行外部命令。比如用来作rc文件配置的前端,或者传输复杂
参数给命令行。
使用package。用swig协助编写C语言动态连接库,用load命令装载后
可以增加新的变量和函数使用C语言内嵌tcl/tk。这个可以很精细的
控制其运行,增加新命令,tcl/tk只作界面。这个通常都比直接用C+Tk
编程快而且易于调试。
应用举例1.比如想用wget或者curl批量下载,配置其参数。给新手配
置程序的简单界面。在Palm等掌上电脑键盘输入不方便的情况。
2.或者在图形界面时要用带输入参数的脚本,比如命令行的电子字典,
你又懒得新开一个xterm,情愿鼠标点+copy/paste完成工作。
3.用canvas作图。当你有很多类似的图形要画,特别是那些用gnuplot
不方便作的图,难道你会因此去啃整套windows/X编程吗?
或者即使你愿意,你能保证你的程序不会太大、可移植吗?你的系统
上有X的开发工具吗?
当然基于文本的替代方案是你可以用latex的作图工具或者直接写Postscript,
真的如此我觉得你太强了。
另外一个是替代是java,Perl,Python等其他语言,但是系统都偏大
。而且不一定装了Tk支持。
实际上作图正是我开始研究、熟悉tcl/Tk的主因