第3部分 TK基础
23 TK基本原理
23.1 TK中的Hello,World!
我们的第一个Tk脚本非常简单。它创建了一个按钮,当你点击它时,就向标准输出设备打印“Hello,World!”。在按钮控件上方是一个由窗口管理器提供的标题栏,本例中在X视窗系统中是twm。
23.1.1 例23-1 “Hello,World!”Tk程序
#!/usr/local/bin/wish button .hello -text Hello / -command {puts stdout "Hello, World!"} pack .hello -padx 20 -pady 10 |
第一行标识了脚本的解释器:
#!/usr/local/bin/wish |
如果此脚本象其它NUIX命令文件那样被调用,则这个特殊的行是必要的,第2节描述了如何设置脚本于不同的平台上。
在这个脚本中有两个TCL命令:一个用来创建按钮,一个用来使其在显示上可见。button命令创建一个按钮的实例:
button .hello -text Hello / -command {puts stdout "Hello, World!"} => .hello |
按钮的名字是.hello。按钮上的标签是Hello,与此按钮相关联的命令是:
puts stdout "Hello, World!" |
pack命令将按钮映射到屏幕上。并提供了一些堆叠参数,所以在按钮周围有空间。
pack .hello -padx 20 -pady 10 |
当你将这两个命令键入wish中时,当button命令给出时,你不会看到任何东西。然而,在pack命令之后,你将会看到空的主窗口将会收缩到足以容纳按钮和其添充空隙(padding)。包装器的行为在第24和第25章进行深入的讨论。
Tk使用一种基本对象的系统来创建和命令控件。与每一种小控件(如按钮)相关联的是一个用于创建此种类别控件实例的命令。当小控件被创建时,一个作用在这个控件实例上的一个新的TCL命令就定义了。例23-1创建了一个名为.hello的按钮,并且我们可以使用其名字作为一个TCL命令来操纵此按钮。例如,我们可以使用此按钮高亮几次:
.hello flash |
或者,我们可以运行与此按钮相关联的命令:
.hello invoke => Hello, World! |
Tk有控件类和实例,但是它并不是完全面向对象的。不可能去对一个控件类派生子类并继承。相反,Tk,提供了非常灵活的控件,可以通过多种方式调节其外观。资源数据库可以存储被许多控件共享的配置信息,并且新的类也可以被引入到组资源中。控件行为通过使用分缓绑定的绑定标签得到共享。Tk使用部件(composition)来组装共享行为和属性的控件。
23.2 Tk小控件的命名
按钮实例名字.hello中的句点是必需的。Tk使用了一种可以反映出控件所在层次的命名系统。层次的根就是应用程序的主窗口,其名字就是一个简单的点(也就是.)。这与UNIX系统中的目录命名习惯很相似,其跟目录名为/,/也用来分隔文件名的组成部分。Tk以同样的方式使用句点。主窗口的每一个子窗口控件以象.foo这样来命名。.foo的一个子控件将是.foo.bar,等等。正如文件系统中目录可以作为其它文件和目录的容器一样,Tk窗口层次使用框架控件作为其它控件和框架的容器。
构成Tk路径的每一部分必须以小写字母或数字开头。显然也不能包含句点。小写字母是为了避免与以大写字母开头的资源类名冲突。一个资源名可以包含Tk路径组成部分和Tk控件类别,并使用大小写来区分它们。第31章详细描述了资源。
« 用变量存储控件名。
Tk命名系统有一个缺点。如果你的界面变化足够多以至导致某些控件改变了他们在控件层次中的位置。在这种情况下,它们可能需要改变其名字。你可以通过使用变量来保存重要控件的名字这种方式与这个程序麻烦相隔离。使用一个变量的引用而不是控件的路径名以便你需要改变什么,或者你想不其它的界面是得用你的代码。控件创建命令返回控件的名字:
set b [button .hello -text "Hello" -command {puts "Hello!"}] |
你可以将$b当作命令来操作按钮:
$b configure -background green |
23.3 Tk小控件的配置
例23-1展示了Tk命令中普遍使用的一种命名参数的传递方式。成对的参数指定了控件的属性。属性名以-开始,如-text,下一个参数就是这个属性的值。即使是简单的Tk控件也可能有一打或更多的可以通过这种方式指定的属性,复杂控件可能有30或更多属性。然而,Tk的魅力在于你仅需要指定默认值不太好的属性。这个可以通过Hello,World例子的简易性得到证明。
最后,每一个控件实例都支持一个configure操作,可以简写为config,它可以查询和改变这些属性。Config的语法,使用相同的创建控件时使用的命名参数对。例如,我们可以改变这个按钮的背景与红色,即使它已经被创建并已经被映射到屏幕上:
.hello config -background red |
控件属性可以在任何时候重新定义,即使是按钮在创建时的text和command。下面的命令将.hello变成一个goodbye按钮:
.hello config -text Goodbye! -command exit |
控件有一个cget操作来查询某个属性的当前值:
.hello cget -background => red |
你可以用不带参数的configure来得到关于一个控件属性的更多细节:
.hello config -background => -background background Background #ffe 4c 4 red |
返回的信息包括命令行开关,资源名称,类名,默认值和当前值。类名和资源名与31章中描述的资源机制有关。如果你只指定configure不指定属性,则将返回控件所有属性配置信息的一个列表。例23-2运用这个来打印出关于一个控件的所有信息:
23.3.1 例23-2查看控件的所有属性
proc Widget_Attributes {w {out stdout}} { puts $out [format "%-20s %-10s %s" Attribute Default Value] foreach item [$w configure] { puts $out [format "%-20s %-10s %s" / [lindex $item 0] [lindex $item 3] / [lindex $item 4]] } } |
23.4 Tk小控件的属性和资源数据库
一个控件属性以三种不同的方式命名:通过命令行选项,通过资源名、通过其资源类。命令行选项就是TCL脚本中使用的形式。此种形式都是小写字母并以连字符(例如,-offvalue)作前缀。属性的资源名没有前导连字符,内部单词边界有大小字母(如,offValue)。资源类以大写字母开头且内部单词边界有大写字母(如,OffValue)。
« 本书中的表格使用资源名列出控件的属性。
如果你想通过资源机制来指定控件的属性,你需要知道这些命名习惯。命令行选项可以通过将资源名映射为全部小写字母衍生得到。使用资源来指定属性的优点是,你不必更改代码中的属性值。仅是通过少数资源数据库项,你就可以为你的所有控件指定属性。另外,如果属性是通过资源指定的,用户可以提供交互式的资源值(或规格?)来由应用程序提供的值。对于像颜色和字体的属性,对于用户来说是重要的。资源规格在31章是详述。
23.4.1 Tk手册页
本书提供了所有Tk命令的总结,控件的属性,默认绑定。然而,为了绝对正确,你可能需要读随Tk的联机手册页。它提供了Tk命令的完全参考。你应该使用UNIX的man程序去读它们:
% man button |
UNIX手册页中的tkman程序提供了非常友好的图形用户界面。在Macintosh平台上,手册页格式化为HTML文档,可以在Tcl/Tk发行版本中的HTML Docs目录中找到。在Windows中,手册格式化成帮助文档。你可以在这个WEB上找到手册页:
有许多属性对于大多数Tk控件是通用的。这些属性在一个单独的名为options的手册页中进行描述。每一个手册页以标准选项(STANDARD OPTIONS)部分开始,它列出了这些标准属性所适用的标准选项。但是,你得看一下options手册页的描述。作为对比,本书中的表格列出所有控件的属性。
23.5 Tk命令总结
下面的表格列出了由Tk所加的TCL命令。表格中的页码是命令的主要参考,同时在索引中也有其它参考。
23.5.1 控件命令
表23-1列出了创建控件的命令。在Tk中有18种不同的控件,虽然其中的4种是按钮的变体,5种专用于不同风格的文本显示。
表 23-1. Tk 控件创建命令 | ||
命令 | 页码. | 描述 |
button | 454 | Create a command button. |
canvas | 557 | Create a canvas, which supports lines, boxes, bitmaps, images, arcs, text, polygons, and embedded widgets. |
checkbutton | 458 | 创建一个与一个TCL变量相关联的toggle button |
entry | 507 | 创建一个单行文本条控件. |
frame | 485 | 创建一个使用布局管理器的容器控件. |
label | 490 | 创建一个只读多行文本标签. |
labelframe | 485 | 创建一个与布器管理器一起使用的有额外标签属性的容器控件. (Tk 8.4) |
listbox | 519 | 创建一个面向单行的可滚动文本控件. |
menu | 462 | 创建一个菜单. |
menubutton | 462 | 创建一个可以弹出一个菜单的按钮. |
message | 493 | 创建一个只读多行文本消息. |
panedwindow | 429 | 创建一个容器控件,以窗格风格控制其控件. (Tk 8.4) |
radiobutton | 458 | 创建与一个变量相关联的一组单选按钮. |
scale | 495 | 创建一个调节一个变量值的缩放按钮. |
scrollbar | 499 | 创建一个可以链接到另一个控件的滚动条. |
spinbox | 511 | 创建一个由按钮控制ENTRY控件值的组合成的旋钮控件. (Tk 8.4) |
text | 531 | 创建一个通用可纹的文本控件. |
toplevel | 485 | 创建一个新的顶层窗口的框架. |
23.5.2 控件操纵命令
表23-2列出了操纵控件并提供像输入焦点、事件绑定、布局管理相关联的功能的命令。
表 23-2. Tk 控件操纵命令 | ||
命令 | 页 | 描述 |
bell | 497 | 使终端响铃设备响铃. |
bind | 435 | 绑定一个TCL命令到某事件上. |
bindtags | 437 | 创建绑定类和控制绑定继承. |
clipboard | 594 | 操作剪贴板. |
destroy | 605 | 删除一个控件. |
event | 446 | 定义并产生虚拟事件. |
focus | 603 | 操作输入焦点. |
font | 641 | 设置查询字体属性的尺寸. |
grab | 604 | 从其它操作窃取输入控制权. |
grid | 419 | 以约束条件排列控件到栅格中. |
image | 626 | 创建、操纵图像. |
lower | 409 | 降低一个窗口的堆叠次序. |
option | 477 | 设置、查询资源数据库. |
pack | 409 | 经约束条件Pack一个控件在显示区域中. |
place | 427 | 按位置放置控件在显示区域中. |
raise | 409 | 升高一个窗口的堆叠次序. |
selection | 593 | 操纵选择操作. |
send | 648 | 发送一个TCL命令到另一个Tk应用程序中. |
tk | 669 | 查询或设置应用程序名字或全局符号. |
tkerror | 202 | 后台错误的处理者. |
tkwait | 605 | 等待一个事件. |
update | 608 | 通过经历(穿越going through)事件循环来更新显示. |
winfo | 663 | 查询窗口状态. |
wm | 657 | 与窗口管理器交互. |
23.5.3 支撑过程
表23-3列出了一些实现标准对话框、可选菜单和其它功能的支撑过程。
Table 23-3. Tk 支撑过程support procedures | ||
命令 | 页 | 描述 |
tk_bisque | 621 | 安装桔黄颜色族. |
tk_chooseColor | 602 | 颜色选择对话框. (Tk 4.2) |
tk_chooseDirectory | 600 | 目录选择对话框. (Tk 8.2) |
tk_dialog | 599 | 创建简单对话框. |
tk_focusFollowsMouse | 603 | 安装鼠标跟踪焦点模式. |
tk_focusNext | 604 | 按tab顺序聚焦文本控件. |
tk_focusPrev | 604 | 按tab顺序聚焦前一个控件. |
tk_getOpenFile | 600 | 打开已存在文件对话框. (Tk 4.2) |
tk_getSaveFile | 600 | 打开新文件对话框. (Tk 4.2) |
tk_messageBox | 600 | 消息对话框. (Tk 4.2) |
tk_optionMenu | 465 | 创建一个选择菜单. |
tk_popup | 465 | 创建一个弹出菜单. |
tk_setPalette | 621 | 设置标准调色板. (Tk 4.2) |
23.6 其它控件集
本书描述了由核心Tk发布版本所提供的控件集。也有些其它Tk的控件集。一些由TCL过程实现,它将基本控件组成有用的组合(如BWidgets)。其它是由基于C的控件(如Tix和BLT)组成的。一些更流行的控件集列在这里:
23.6.1 BLT
George Howlett创建了BLT。它包括一个可以有效支持大型数据集的主要图表控件。也包括标签笔记本和树形视图控件。其忙录控件用一个透明的仅显示一个监视光标的控件覆盖应用程序,当应用程序忙于做某事且你不想接受鼠标点击时,这个是非常方便的。这是一个基于C的工具包。
http://www.sourceforge.net/projects/blt/
23.6.2 Tix
Tix由Ioi Lam所创建,现在由一些志愿者组成的小组所支持。它包括几个控件和一个在TCL中创建控件的基础组织。特色包括气球提示、标签窗口、窗格窗口和一个层次游览器。虽然它包含一些由TCL组合成的控件,但还是一个基于C的工具箱。
23.6.3 [incr Tk] and [incr Widgets]
[incr Tk]是一个使用[incr Tcl]对象系统来创建组合控件的基于C的框架。它包括很多控件,从简单的标签项控件到HTML显示控件。这些工作在Chad Smith的书[incr Tcl] from the Ground Up (Osborne-McGraw Hill, 1999).中有描述。
http://incrtcl.sourceforge.net
23.6.4 BWidgets
BWidgets是一个基于TCL控件集。包括多种组合控件,包括标签记事本、组合框、层次游览器。位于标准TCL库的WEB站点:
http://www.sourceforge.net/projects/tcllib
23.6.5 TkTable
TkTable是一个网格几何管理器和几个基于文本控件的组合。它使一些像电子数据表这样的表列数据很容易的显示出来,同时也提供了很多对单元格和其数据格式化的控制。