脚本
译者按:余修改了部分代码。
向 ed.tcl 添加下列语句,包含建立对话窗口和相关的行为的脚本的源代码。脚本在以下三个文件中,message.tcl, filesel.tcl 和 popup.tcl:
#source some of the auxillary scripts we will be using #note these can be source in appropriate procedures too source filesel.tcl source message.tcl source popup.tcl
过程 tk_getOpenFile 和 tk_getSaveFile 弹出一个对话框供用户选择要打开或保存的一个文件。tk_getOpenFile 通常与在 File 菜单中的打开命令相关联。它的功能是让用户选择一个现存的文件。如果用户输入了一个不存在的文件,对话框向用户给出一个错误提示并要求用户给出替代的选择。如果一个应用允许用户建立新文件,它应该为此提供一个独立的 New 菜单命令。
tk_getSaveFile 命令通常与在 File 菜单中的 Saveas 命令相关联。如果用户输入了一个不存在的文件,对话框提示用户确认是否覆写这个现存的文件。
文件选择框脚本是捐献的软件并有细微的修改。这个脚本在本书中的代码子目录下的 ch3 中,名字是 filesel.tcl。把这个文件复制到当前的工作路径。读者应当可以把它作为一个对立的单元使用。
文件选择框很简单,如下:
余忽略了 mes.tcl ,使用了 Tk 内置的 tk_messageBox 命令。其格式为:tk_messageBox ?option value ...? 。
这个过程建立并显示一个消息窗口,有有特定于应用的消息,一个图标和一系列按钮。在消息窗口中的每个按钮都由一个唯一符号名字来标识(参见它的手册页中的 -type 选项)。在弹出这个消息窗口之后,tk_messageBox 等待用户选择按钮中的一个。接着它返回选择的按钮的符号名字。
下面的脚本的代码将被放置在文件 file mes.tcl 中:
proc showMessage {mess} {
toplevel .messpop -width 10c -height 4c
grab .messpop
wm title .messpop "Warning"
message .messpop.msg -relief raised -bd 2 -text $mess
button .messpop.okb -text OK \
-com {destroy .messpop ; return 0}
pack .messpop.msg .messpop.okb -side top
}
showMessage 接受一个消息字符串作为参数(过程实质上被参数化(parametrized)了,所以对所有你想对话的消息你都可以变化参数而使用相同的过程)。它显示一个用 Tk 命令 message 建立的消息组件,调用参数是作为输入传递进来的消息串。还包含一个 "OK" 按钮,它连接着在用户在按钮上点击时销毁这个顶层窗口的命令。
顶层窗口也可以被用作弹出式消息窗口。在这种情况下,在建立弹出式消息窗口的过程中,给 Tk 命令 grab 的参数是消息窗口的名字。这将夺取键盘焦点来确保用户注意。在调用过程中,调用 Tk 命令 tkwait window ,参数是消息窗口名字。它在调用过程中挂起处理,直到用户同弹出窗口进行了必须的交互并显式的关闭(销毁)了它。在弹出或顶层窗口中任何 OK、DISMISS 或 Cancel 按钮的命令中销毁它。
使用脚本建立这个消息窗口,用以警告一个文件将被覆盖,看起来如下:
proc FindPopup {} {
global seltxt repltxt
toplevel .fpop -width 10c -height 4c
grab .fpop
wm title .fpop "Find Text"
label .fpop.lab1 -text "Find : "
place .fpop.lab1 -in .fpop -x 2 -y 6
entry .fpop.en1 -width 20 -relief sunken -textvariable seltxt
place .fpop.en1 -in .fpop -x 72 -y 6
label .fpop.lab2 -text "Replace : "
place .fpop.lab2 -in .fpop -x 2 -y 50
entry .fpop.en2 -width 20 -relief sunken -textvariable repltxt
place .fpop.en2 -in .fpop -x 72 -y 50
menubutton .fpop.finb -text Find -menu .fpop.finb.menu
place .fpop.finb -in .fpop -x 2 -y 90
menu .fpop.finb.menu
.fpop.finb.menu add command -label Forward -com {FindWord -forwards $seltxt}
.fpop.finb.menu add command -label Backward -com {FindWord -backwards $seltxt}
menubutton .fpop.finrb -text "Find and Replace" -menu .fpop.finrb.menu
place .fpop.finrb -in .fpop -x 38 -y 90
menu .fpop.finrb.menu
.fpop.finrb.menu add command -label Forward -com {ReplaceSelection -forwards}
.fpop.finrb.menu add command -label Backward -com {ReplaceSelection -backwards}
button .fpop.repall -text "Replace All" -com {ReplaceAll}
place .fpop.repall -in .fpop -x 150 -y 90
button .fpop.tagall -text "Tag All" -com {TagAll}
place .fpop.tagall -in .fpop -x 250 -y 36
button .fpop.dismis -text Dismiss -com {destroy .fpop}
place .fpop.dismis -in .fpop -x 250 -y 90
focus .fpop.en1
}
这个代码与那个消息框顶层窗口一样,同在建立主菜单的章节中曾经描述的相类似。注意命令 "place" 接受两个选项 "-x" 和 "-y",它们的值是整数(在这种情况下是象素)并要求打包器在由"-in"选项给出的组件之中的位置上放置这个组件。
在这个弹出窗口中菜单按钮 Find 、Find 和 Replace 都有下拉菜单来做向前和向后查找。这些过程在下一章中定义。如果你现在打算执行这个脚本并测试它,你可以注释掉在 -com 选项开始之前的行。这将停止 Tk 解释器对未定义命令的抱怨。
执行这个程序的最终结果应该是: