第 25 章 Tcl, Tk 和 Expect

Tcl 是 John Ousterhount 1987 年 在 加 州 大 学 伯 克 利 分 校 开 发 的 一 种 通 用 命令 语 言 。 该 语 言 起 先 是 为 应 用 程 序 进 行 定 制 时 设 计 的 , 但 它 现 在 已 经 成 为 一 种功 能 强 大 的 语 言 。 与 Perl 和 gawk 相 同 , 用 户 可 以 建 立 自 己 的 Tcl 脚 本 文 件 , 开 发 自 己 的 Tcl 程 序 。 Tcl 是 一 种 使 用 非 常 简 单 的 语 言 。

随 着 Tcl 应 用 程 序 的 不 断 发 展 , Tcl 语 言 本 身 的 功 能 也 越 来 越 强 。 使 用 合 适的 应 用 程 序 , Tcl 程 序 可 以 创 建 图 形 化 界 面 , 与 其 它 程 序 相 互 通 讯 , 甚 至 可 以 对声 音 记 录 进 行 管 理 。 使 用 Tk 应 用 程 序 可 以 非 常 简 单 地 开 发 交 互 式 图 形 界 面 的 应用 程 序 , 开 发 者 可 以 很 简 单 地 实 现 带 有 按 钮 和 文 本 框 的 窗 口 和 对 话 框 。XF 在 Tk 的 基 础 上 又 前 进 了 一 步 , 它 为 开 发 者 提 供 了 图 形 组 件 的 实 现 方 法 。 Expect 应 用程 序 则 可 以 实 现 Tcl 程 序 与 交 互 式 应 用 程 序 ( 如 ftp, Telnet) 的 相 互 通 讯 。 Tcl-DP 为 Tcl 应 用 程 序 行 发 提 供 了 支 持 。 AK 则 提 供 了 音 频 功 能 , 如 录 音 、 回 放 和 电 话控 制 等 。

Tcl 通 常 与 Tk 同 时 使 用 以 建 立 图 形 化 的 应 用 程 序 。 Tk 用 来 创 建 窗 口 等 图 形组 件 , Tcl 则 用 来 完 成 相 应 的 程 序 动 作 , 如 对 用 户 输 入 进 行 响 应 等 。 同 Java 一样 , Tcl/Tk 是 一 种 跨 平 台 的 应 用 程 序 。 用 Tcl/Tk 编 写 的 程 序 可 以 在 任 何 安 装 了Tcl/Tk 解 释 程 序 的 平 台 上 运 行 。目 前 ,在 W indows 、Mac 和 UNIX 系 统 ( 包括 LINUX

上 都 有 Tcl/Tk 的 解 释 程 序 。 用 户 可 以 在 LINUX 上 开 发 Tcl 应 用 程 序 , 然 后 在W indows 或 Mac 上 直 接 运 行 。 新 版 的 Tcl 和 Tk 8.0 甚 至 可 以 自 动 搜 索 当 前 使用 的 操 作 系 统 ,然 后 相 应 地 在 Mac 系 统 上 使 用 类 似 Mac 的 窗 口 ,而 在 W indows 95 上 则 使 用 W indows 风 格 的 窗 口 。

与 Perl 相 同 , Tcl 是 一 种 解 释 语 言 , 拥 有 自 己 的 shell 解 释 程 序 。 在 命 令 行上 使 用 tclsh 命 令 可 以 调 入 Tcl shell 。 用 户 可 以 在 shell 中 执 行 Tcl 命 令 , 也 可以 将 Tcl shell 调 用 语 句 和 Tcl 命 令 储 存 在 一 个 Tcl 程 序 中 , 然 后 直 接 调 用 该 程序 。 Tcl 语 言 及 其 应 用 程 序 的 一 个 显 著 优 点 是 它 与 C 语 言 完 全 兼 容 , 可 以 在 C 语 言 中 直 接 调 用 Tcl 库 。 这 样 , 用 户 就 可 以 开 发 出 编 译 后 的 执 行 速 度 非 常 快 的Tcl 程 序 。

在 系 统 中 安 装 Tk 和 Tcl 的 同 时 ,也 将 安 装 Tcl/Tk 命 令 的 帮 助 文 件 。使用 man 命 令 和 Tcl/Tk 命 令 名 可 以 得 到 该 命 令 的 详 细 信 息 。例 如 , man switch 将 显 示 Tcl switch 命 令 的 详 细 信 息 , man button 则 将 显 示 Tk button 组 件 的 详 细 信 息 。 在安 装 了 Tk 后 , 可 以 运 行 一 个 名 为 饰 件 的 演 示 程 序 ,该 程 序 将 显 示 所 有 可 用 的 Tk 组 件 。 饰 件 程 序 使 用 Tcl/Tk 示 例 程 序 并 可 以 显 示 每 个 程 序 的 源 代 码 。 饰 件 演 示程 序 位 于 Tk 的 demos 目 录 下 ( 这 里 的 tk* 代表 Tk 所 在 的 目 录 , 目 录 名 由 tk 和相 应 的 版 本 号 组 成 , 如 4.1 版 本 的 目 录 名 为 tk4.1 , 而 8.0 版 本 的 目 录 名 则 为tk8.0 )。

cd /usr/lib/tk*/demos

在 Xterm 窗 口 中 只 需 要 键 入 命 令 饰 件 即 可 。 也 可 以 单 独 查 看 某 一 个 演 示 文件 并 对 其 进 行 修 改 。 如 果 在 安 装 Tk 时 不 是 使 用 默 认 的 /usr/bin 目 录 而 采 用 了

/usr/local/bin 目 录 , 那 么 demos 目 录 将 位 于 /usr/local/lib/tk* 下 。

25.1 Tcl/Tk 产 品 和 版 本

目 前 , Tc l、 Tk 和 其 它 相 关 的 软 件 都 是 由 Sun 公 司 开 发 并 提 供 支 持 的 , John Ousterhout 领 导 Tcl/Tk 的 研 究 工 作 。当 前 最 新 的 Tcl 和 Tk 发 行 版 本 为 8.0 。Sun 公 司 还 同 时 为 因 特 网 和 其 它 应 用 程 序 开 发 提 供 3 种 其 它 的 Tcl/Tk 产 品 : Tcl/Tk 网 页 插 件 、 TclHttpd 网 络 服 务 器 和 SpecTcl Tcl/Tk GUI 开 发 工 具 。 表 25-1 中给 出 了 可 用 的 Tcl/Tk 软 件 列 表 。 Tcl/Tk 网 页 插 件 允 许 用 户 在 自 己 建 立 的 网 页 中插 入 Tcl/Tk 程 序 , 这 些 Tcl/Tk 程 序 通 常 被 称 作 Tclets 。 Tclhttpd 是 一 种 网 络 服务 器 , 可 以 简 单 地 插 在 应 用 程 序 中 使 其 能 够 提 供 对 网 络 的 支 持 。 SpecTcl 则 是一 个 Tcl/Tk 编 辑 器 , 通 过 它 可 以 方 便 地 建 立 应 用 程 序 的 图 形 界 面 。 Spec 可 以同 时 生 成 相 应 的 Tcl/Tk 和 Java 代 码 , 可 以 用 来 建 立 可 单 独 运 行 的 Tcl/Tk 应 用程 序 或 网 络 Tclets 。 SpecTcl 是 一 个 基 于 窗 口 系 统 的 程 序 , 可 以 通 过 菜 单 和 图标 方 便 地 创 建 应 用 程 序 的 图 形 界 面 。

所 有 这 些 产 品 , 包 括 最 新 版 的 Tcl 和 Tk 程 序 , 都 可 以 从 下 面 列 出 的 Tcl/Tk 网 址 免 费 获 取 。 在 这 个 网 址 上 还 可 以 得 到 每 个 产 品 的 详 细 文 挡 说 明 , 包 括PostScript, Adobe PDF 和 HTML 等 格 式 。 HTML 格 式 的 文 档 可 以 在 线 进 行 查看 。

http://sunscipt.sun.com

目 前 的 OpenLinux 光 盘 中 只 包 含 Tcl 和 Tk 的 旧 版 本 , 版 本 号 分 别 为 7.5 和

  1. 。 大 部 分 的 Tcl/Tk 产 品 都 不 能 在 这 些 旧 版 本 上 运 行 , 因 此 应 该 从 以 上 的 网 址下 载 安 装 新 的 8.0 版 本 。 从 RedHat 公 司 的 ftp 站 点ftp.redhat.com/pub/contrib/i386 可 以 得 到 最 新 的 Tcl/Tk 8.0RPM 软 件 包 。 用 户在 下 载 时 应 该 同 时 下 载 Tcl 和 Tk 的 RPM 包 和 相 应 的 开 发 程 序 包 。 这 里 列 出 了这 些 文 件 的 文 件 名 。 在 下 载 之 后 , 就 可 以 使 用 rpm -i 命 令 安 装 这 些 程 序 。 注 意 , 如 果 系 统 中 存 在 旧 的 Tcl/Tk 版 本 , 在 安 装 前 ,必 须 使 用 Lisa (或 rpm -e tk 和 rpm

-e tcl) 将 其 删 除 ( 使用 rpm qi tk 可 以 检 查 是 否 存 在 这 些 版 本 )。rpm -i tcl-8.0-1.i386.rpm

rpm -i tk-8.0-1.i386.rpm

rpm -i tcl-devel-8.0-2.i386.rpm rpm -i tk-devel-8.0-2.i386.rpm

在 删 除 旧 的 Tcl/Tk 包 前 , 应 该 对 它 们 的 共 享 库 , /usr/lib/libtcl7.5.so 和

/usr/lib/libtk4.1.so 作 一 个 备 份 ( 改 名 )。 有 一 些 Tcl/Tk 应 用 程 序 如 XF86setup 需要 旧 共 享 库 的 支 持 。 因 此 在 运 行 XF86Setup 之 前 需 要 暂 时 将 libtk.so 和 libtcl.so 目 录 连 接 到 备 份 的 旧 目 录 , 在 程 序 运 行 结 束 后 再 将 其 指 回 原 来 的 目 录

/usr/lib/libtcl8.0.so 和 /usr/lib/libtk8.0.so 。

从 Tcl/Tk 网 站 上 可 以 下 载 最 新 的 源 程 序 代 码 。 这 些 源 程 序 代 码 都 经 过 压 缩 , 后 缀 名 为 .tar.gz。 使 用 gunzip 和 tar xvf 命 令 就 可 以 对 该 文 件 进 行 解 压 缩 , 解压 后 的 文 件 分 别 存 放 在 tcl8.0 和 tk8.0 目 录 下 。 解 压 后 可 以 查 看 tcl8.0 目 录 中 的README 文 件 得 到 相 应 的 指 令 信 息 , 在 unix 目 录 下 的 README 文 件 可 以 得

到 如 何 编 译 并 使 用 这 些 软 件 代 码 的 办 法 。 这 些 源 代 码 使 用 一 个 配 置 脚 本 文 件 可以 极 大 地 简 化 编 译 的 操 作 。 下 面 的 命 令 可 以 在 OpenLinux 系 统 上 运 行 , - enable-gcc 选 项 选 择 gcc 编 译 器 。

./configure -enable-gcc make

make install

对 Tk 的 源 程 序 代 码 也 需 要 进 行 同 样 的 工 作 。tk8.0 目 录 中 也 存 在 相 应 的 unix 子 目 录 。 执 行 完 make 命 令 后 , 将 建 立 两 个 名 为 tchsh8.0 和 wish8.0 的 程 序 。这 两 个 程 序 存 放 在 /usr/local/bin 或 /usr/bin 目 录 中 。 make install 操 作 则 安 装 相应 的 帮 助 文 档 、 函 数 库 和 例 子 程 序 。

# ln /usr/local/bin/tclsh8.0 /usr/bin/tclsh # ln /usr/local/bin/wish8.0 /usr/bin/wish

T cl

Tcl 是 一 种 易 于 使 用 的 编 程 语 言 。 Tcl 中 的 语 句 由 相 应 的 命 令 和 所 带 的 参 数组 成 , 当 然 在 Tcl 中 也 存 在 包 括 while 和 for 循 环 在 内 的 一 套 完 善 的 控 制 结 构 。分 号 和 换 行 都 可 以 表 示 一 条 语 句 的 结 束 。 Tcl 命 令 就 像 一 条 函 数 调 用 语 句 , 命 令名 即 为 函 数 名 , 所 带 的 参 数 就 是 调 用 使 用 的 参 数 。 不 过 , 与 函 数 调 用 不 同 的 是 , 在 调 用 参 数 的 前 后 没 有 使 用 括 号 或 引 号 等 符 号 来 显 式 进 行 说 明 , 只 需 要 使 用 空格 将 函 数 名 和 参 数 分 开 即 可 。

在 Tcl 赋 值 语 句 set 中 可 以 很 清 楚 地 看 到 这 种 格 式 的 特 点 。 在 对 变 量 进 行 赋值 时 , 首 先 输 入 赋 值 命 令 se t, 然 后 输 入 变 量 名 和 所 赋 的 值 。 赋 值 命 令 、 变 量名 和 所 赋 的 值 中 间 用 空 格 隔 开 。

下 面 的 例 子 将 字 符 串 "larisa "赋 值 给 myname 变 量 , 将 11 赋 值 给 变 量 age 。set myname "larisa"

set age 11

与 gawk 和 Perl 相 同 , 变 量 的 类 型 由 变 量 的 使 用 方 式 决 定 。 赋 值 为 整 数 的变 量 将 为 整 数 类 型 , 赋 值 为 字 符 串 的 变 量 则 为 一 个 字 符 数 组 。

tclsh shell 和 脚 本 文 件

在 Tcl shell 中 可 以 执 行 相 应 的 Tcl 命 令 。 执 行 命 令 存 在 两 种 不 同 的 方 式 , 可 以 在 Tcl shell 提 示 符 下 交 互 式 地 输 入 命 令 , 一 步 一 步 地 执 行 , 也 可 以 将 这 些命 令 写 入 一 个 脚 本 文 件 , 然 后 一 次 执 行 这 些 命 令 。 键 入 命 令 tclsh 可 以 启 动 Tcl shell 。 shell 的 提 示 符 为 % , 在 shell 中 可 以 输 入 Tcl 命 令 , 当 按 下 回 车 键 后 就可 以 执 行 该 命 令 。 输 入 exit 命 令 或 按 下 CTRL-D 组 合 键 都 可 以 退 出 Tcl shell。

$ tclsh

% set age 11

% puts $age 11

% exit

$

可 以 将 Tcl 脚 本 程 序 以 单 独 的 程 序 运 行 , 也 可 以 使 用 Tcl shell 命 令 tclsh 显式 读 入 该 文 件 然 后 运 行 。 Tcl 脚 本 程 序 的 后 缀 名 为 .tc l。 例 如 , myread.tcl 脚 本程 序 可 以 使 用 下 面 列 出 的 方 式 来 读 入 并 执 行 :

$ tclsh myread.tcl

如 果 需 要 将 该 脚 本 作 为 单 独 的 程 序 运 行 , 应 该 在 脚 本 中 调 用 tclsh 命 令 。 可以 采 取 两 种 方 式 完 成 这 项 操 作 。 第 一 种 是 在 脚 本 程 序 的 第 一 行 中 显 式 指 出 调 用tclsh 命 令 的 路 径 , 如 下 所 示 :

# ! /usr/bin/tclsh

第 二 种 方 式 不 需 要 显 式 指 定 tclsh 所 在 的 路 径 , 而 是 在 指 定 的 系 统 上 执 行tclsh 命 令 。 这 样 做 的 好 处 是 , 即 使 不 同 系 统 中 tclsh 所 在 的 目 录 不 同 , 脚 本 程序 也 可 以 正 常 运 行 。

# ! /bin/sh

# the next line restarts using tclsh \ exec tclsh "$0" "$@"

本 节 中 的 myread 例 子 脚 本 程 序 将 使 用 显 式 调 用 的 方 案 , 而 myreport 脚 本

则 使 用 第 二 种 非 显 式 调 用 的 办 法 。

表 达 式

Tcl 中 表 达 式 的 处 理 与 命 令 相 同 。 expr 命 令 计 算 表 达 式 的 值 并 将 计 算 的 结 果

作 为 字 符 串 返 回 。它 的 参 数 即 为 表 达 式 的 运 算 数 和 运 算 符 。Tcl 支 持 标 准 的 算 术 、比 较 和 逻 辑 操 作 。 算 术 表 达 式 的 结 果 与 参 与 计 算 的 运 算 数 的 类 型 相 同 。 如 果 运算 数 均 为 实 型 , 计 算 的 结 果 也 是 实 型 。 在 表 达 式 中 可 以 混 合 使 用 多 种 类 型 , Tcl 会 自 动 进 行 相 应 的 转 换 。 如 果 操 作 数 中 同 时 存 在 实 型 和 整 型 , 计 算 时 Tcl 会 将整 形 转 换 为 实 型 。 在 下 面 的 例 子 中 , expr 命 令 计 算 了 4 和 3 的 和 以 及 25 和 2 的 乘 积 。

expr 4 + 3

expr 25 * 2

可 以 使 用 括 号 创 建 复 杂 的 表 达 式 , 最 里 层 的 括 号 中 的 表 达 式 将 首 先 进 行 计算 。 在 下 面 的 例 子 中 , 将 首 先 计 算 25*2 , 然 后 从 结 果 中 减 去 20 。

expr (25 * 2) - 20

任 何 Tcl 命 令 返 回 的 结 果 值 都 是 一 个 字 符 串 。 对 于 算 术 表 达 式 来 说 , Tcl 将首 先 将 计 算 的 结 果 转 换 为 字 符 串 , 然 后 再 将 转 换 后 的 字 符 串 返 回 。

嵌 套 命 令

Tcl 中 可 以 将 命 令 嵌 套 使 用 。 在 使 用 表 达 式 的 结 果 对 变 量 进 行 赋 值 时 经 常 使用 嵌 套 命 令 。 这 里 将 使 用 两 个 命 令 , set 命 令 用 来 执 行 赋 值 操 作 , expr 命 令 用来 计 算 表 达 式 的 值 。 命 令 嵌 套 时 应 使 用 方 括 号 , 方 括 号 中 的 命 令 返 回 的 结 果 作为 外 层 命 令 的 某 个 参 数 。 下 面 的 例 子 将 算 术 运 算 25*2 的 结 果 赋 值 给 num 变 量 。expr 25 * 2 在 set 命 令 中 嵌 套 使 用 。 方 括 号 中 的 表 达 式 , 25*2 将 首 先 被 执 行 ,

随 后 将 计 算 的 结 果 50 赋 给 变 量 num 。

set num [expr 25 * 2]

变 量

Tcl 支 持 算 术 和 字 符 串 变 量 , 也 支 持 包 括 关 联 数 组 在 内 的 数 组 变 量 。 所 有 变量 的 内 容 都 以 字 符 串 的 形 式 进 行 储 存 。 不 过 , 如 果 字 符 串 由 数 字 组 成 , 该 字 符串 仍 然 可 以 直 接 在 算 术 表 达 式 作 为 整 数 或 实 数 使 用 ,Tcl 将 自 动 对 字 符 串 进 行 相应 的 转 换 。 转 换 后 参 与 运 算 完 毕 后 , 得 到 的 结 果 再 转 换 为 字 符 串 返 回 。 因 此 , 开 发 人 员 不 必 对 变 量 的 类 型 进 行 声 明 , 甚 至 根 本 就 不 必 对 变 量 进 行 定 义 。 变 量都 将 在 第 一 次 使 用 时 自 动 定 义 。

可 以 使 用 set 命 令 对 变 量 进 行 赋 值 , set 命 令 使 用 的 参 数 为 变 量 名 和 赋 给 该变 量 的 值 。 变 量 名 可 以 由 字 母 或 数 字 字 符 以 及 下 划 线 组 成 , 变 量 名 中 不 允 许 使用 点 号 或 其 它 字 符 。 在 语 句 中 使 用 变 量 值 时 需 要 对 变 量 进 行 计 算 , 即 使 用 变 量的 值 代 替 变 量 名 参 与 语 句 运 算 。 在 变 量 名 前 加 上 $ 符 号 前 缀 就 可 以 完 成 这 种 转 换工 作 。 在 下 面 的 例 子 中 , 首 先 将 5 赋 值 给 变 量 mynum 。 然 后 使 用 $mynum 将变 量 的 值 在 表 达 式 中 使 用 。

set mynum 5

expr 10 * $mynum

如 果 需 要 将 变 量 的 值 在 字 符 串 中 使 用 , 只 需 要 在 字 符 串 中 对 变 量 进 行 计 算即 可 , 变 量 的 值 将 成 为 字 符 串 的 一 部 分 。 在 下 面 的 例 子 中 , 变 量 myname 的 值

就 作 为 字 符 串 的 一 部 分 使 用 , 该 字 符 串 为 "My name is Larisa " 。set myname "Larisa"

set mystr "My name is $myname"

Tcl 中 存 在 一 些 特 定 的 对 变 量 进 行 操 作 的 命 令 。 append 命 令 可 以 连 接 字 符串 和 变 量 , incr 命 令 可 以 对 整 数 进 行 增 值 操 作 , 而 unset 命 令 则 可 以 取 消 对 变量 的 定 义 , 释 放 其 所 占 的 空 间 。 表 25-3 中 列 出 了 这 些 操 作 。

数 组

使 用 set 命 令 可 以 对 数 组 元 素 定 义 并 赋 值 。 下 面 的 例 子 对 weather 数 组 中的 第 二 个 元 素 赋 值 为 字 符 串 "rain "。

set weather(2) rain

在 对 数 组 元 素 进 行 引 用 时 , 需 要 在 数 组 名 的 前 面 加 上 $ 前 缀 。

puts $weather(2) rain

Tcl 允 许 使 用 任 何 字 符 串 作 为 数 组 的 索 引 串 , 也 就 是 说 , 它 提 供 了 对 关 联 数组 的 支 持 。 下 面 的 例 子 可 以 在 city 数 组 中 添 加 两 个 索 引 串 为 Napa 和 Alameda 的 元 素 。

set city(Napa) 34

set city(Alameda) 17

关 联 数 组 中 的 元 素 引 用 与 一 般 数 组 相 同 , 在 数 组 名 前 加 上 前 缀 $ , 然 后 在 数

组 后 的 括 号 中 写 入 索 引 串 即 可 。

puts $city(Napa) 34

列 表

Tcl 支 持 列 表 类 型 , 这 是 一 种 在 其 它 的 编 程 语 言 中 很 少 可 以 见 到 的 类 型 。 列表 是 使 用 括 号 包 围 起 来 的 一 组 单 字 、 字 符 串 或 数 字 。 Tcl 中 存 在 一 套 非 常 灵 活 的列 表 命 令 ,使 用 这 些 命 令 可 以 对 列 表 进 行 联 接 、分 隔 、添 加 或 删 除 元 素 等 操 作 ( 见表 25-2 )。 在 引 用 列 表 时 , 可 以 简 单 地 引 用 列 表 名 , 也 可 以 列 出 括 号 和 括 号 中 的所 有 元 素 。

使 用 set 命 令 同 样 可 以 将 列 表 的 值 赋 给 变 量 , 下 面 的 例 子 将 三 个 单 字 的 列 表赋 给 变 量 weathe r。 注 意 这 里 使 用 空 格 来 分 隔 列 表 中 的 组 件 。

set weather {sun rain wind}

Tcl 提 供 了 一 系 列 的 命 令 , 通 过 这 些 命 令 可 以 对 列 表 进 行 访 问 和 操 作 。 大 部分 这 些 命 令 都 根 据 元 素 在 列 表 中 的 位 置 对 该 元 素 进 行 访 问 。 列 表 中 的 位 置 从 0 开 始 。 因 此 , 在 上 面 的 例 子 中 , sun 的 位 置 为 0 , rain 为 1 , w ind 为 2 。

lindex 命 令 根 据 元 素 的 索 引 位 置 在 列 表 中 返 回 该 元 素 , 它 使 用 列 表 和 所 需的 索 引 位 置 作 为 参 数 。 lreplace 命 令 将 列 表 中 指 定 位 置 的 元 素 替 换 为 新 的 值 , linsert 命 令 的 参 数 与 lreplace 相 同 : 列 表 , 索 引 位 置 和 新 元 素 。 下 面 的 例 子 将列 表 中 的 第 二 个 元 素 ( 索 引 位 置 为 1)blue 替 换 为 green 。 这 条 语 句 将 返 回 列 表

(red green yellow ) 。

lreplace (red blue yellow) 1 green (red green yellow)

也 可 以 将 列 表 赋 值 给 变 量 , 然 后 使 用 给 变 量 名 对 列 表 进 行 操 作 。 注 意 这 里

花 括 号 和 $ 前 缀 的 使 用 方 法 。

set mycolors {red blue yellow} lreplace $mycolors 1 green puts $mycolors

也 可 以 使 用 类 似 数 组 的 方 式 对 列 表 进 行 操 作 , 如 使 用 (1 )可 以 引 用 第 二 个 元

素 。

set mycolors(1) green

控 制 结 构

Tcl 中 的 控 制 结 构 与 Perl 、 gawk 、 C-shell 和 C 语 言 中 的 结 构 非 常 相 似 。 Tcl 中 也 存 在 重 复 作 某 事 的 循 环 结 构 和 作 条 件 选 择 的 条 件 结 构 。 表 25-3 中 列 出 了 这些 控 制 结 构 的 具 体 情 况 。 Tcl 中 的 控 制 结 构 使 用 Tcl 命 令 块 进 行 操 作 , 命 令 块 则由 括 号 中 的 Tcl 命 令 行 组 成 。 开 括 号 必 须 与 使 用 该 命 令 块 的 语 句 放 在 同 一 行 , 语 句 块 以 闭 括 号 结 束 , 该 闭 括 号 单 独 位 于 一 行 。 一 个 语 句 块 在 语 法 上 与 一 条 Tcl 命 令 等 价 。 控 制 语 句 将 顺 序 执 行 语 句 块 中 的 语 句 。

if 控 制 结 构 允 许 程 序 选 择 不 同 的 执 行 路 线 。 if 命 令 使 用 两 个 参 数 , 一 个 测 试

表 达 式 和 Tcl 命 令 或 命 令 块 。 表 达 式 用 来 测 试 是 否 执 行 相 应 的 命 令 , 如 果 表 达式 为 真 , 将 执 行 该 命 令 , 否 则 将 跳 过 该 命 令 。 下 面 给 出 了 if 结 构 的 语 法 。 可 以使 用 else 块 指 定 表 达 式 为 假 时 执 行 的 命 令 , 使 用 elseif 命 令 可 以 实 现 if 语 句 的嵌 套 。

if { 测 试 表 达 式 } { Tcl 命 令

} elseif ( 测 试 表 达 式 ) { Tcl 命 令

} else { Tcl 命 令

}

switch 结 构 允 许 在 多 个 可 能 的 执 行 路 线 中 进 行 选 择 , 选 择 的 标 准 是 将 字 符串 的 值 和 一 些 可 能 出 现 的 模 式 进 行 比 较 。 每 一 种 模 式 都 对 应 自 己 的 一 块 Tcl 命令 语 句 。 如 果 出 现 某 种 匹 配 情 况 , 就 可 以 执 行 对 应 的 语 句 块 。 如 果 所 有 可 能 出现 的 模 式 都 不 能 形 成 匹 配 , 程 序 将 执 行 default 关 键 字 后 的 语 句 。 switch 结 构 以关 键 字 switch 开 始 ,然 后 是 前 缀 - 和 匹 配 时 使 用 的 选 项 ,需 要 进 行 匹 配 的 字 符 串 , 以 及 所 有 可 能 出 现 的 模 式 和 对 应 的 动 作 。 下 面 给 出 了 switch 结 构 的 语 法 。

switch - 选 项 字 符 串 {

模 式 { Tcl 命 令

}

模 式 { Tcl 命 令

}

default { Tcl 命 令

}

}

选 项 指 定 了 模 式 匹 配 使 用 的 方 法 , 下 面 给 出 了 命 令 可 以 支 持 的 选 项 :

-exact 在 比 较 字 符 串 和 模 式 时 使 用 精 确 匹 配 , 缺 省 模 式

-glob 使 用 全 局 模 式 进 行 匹 配

-regexp 使 用 正 则 表 达 式 模 式 进 行 匹 配

-- 选 项 结 束 标 识 , -- 参 数 后 的 字 符 串 为 需 要 进 行 匹 配 的 字 符 串 ( 即 使 该 字 符 串以 - 开 始 )

-regexp 选 项 可 以 使 用 正 则 表 达 式 进 行 匹 配 , -glob 则 可 以 使 用 与 shell 文 件名 搜 索 类 似 的 匹 配 方 式 。 在 使 用 全 局 模 式 时 , 可 以 使 用 特 殊 字 符 * 、 [] 和 ? 对 字符 串 进 行 匹 配 。 使 用 -regexp 选 项 时 , 可 以 对 非 常 复 杂 的 正 则 表 达 式 进 行 匹 配 。 while 循 环 可 以 重 复 执 行 命 令 。 在 Tcl 中 , while 循 环 由 while 命 令 和 两 个 参

数 组 成 , 一 个 测 试 表 达 式 和 一 个 Tcl 语 句 或 语 句 块 。 Tcl 命 令 块 由 与 while 关 键字 位 于 同 一 行 的 开 括 号 表 示 开 始 ,单 独 位 于 一 行 的 闭 括 号 结 束 。下 面 给 出 了 while 循 环 结 构 的 语 法 。

while ( 测 试 表 达 式 ) {

Tcl 命 令

}

for 循环

for 循 环 的 功 能 与 while 循 环 相 同 , 但 格 式 略 有 差 别 。 for 循 环 使 用 4 个 参 数 , 前 3 个 参 数 为 表 达 式 , 最 后 一 个 参 数 为 Tcl 命 令 或 语 句 块 。 三 个 表 达 式 分 别 为初 始 表 达 式 、 测 试 表 达 式 和 增 量 表 达 式 , 每 个 表 达 式 都 使 用 花 括 号 进 行 封 装 。

for { 表 达 式 1} { 表 达 式 2} { 表 达 式 3} { Tcl 命 令 ;

}

foreach 循 环 是 为 顺 序 使 用 列 表 中 的 值 设 计 的 , 它 和 C-shell 中 的 for-in 结构 非 常 相 似 。 foreach 结 构 使 用 三 个 参 数 : 变 量 、 列 表 和 Tcl 命 令 块 。 列 表 中 的每 一 个 值 都 顺 序 赋 给 指 定 的 变 量 , 然 后 参 与 循 环 中 的 命 令 块 操 作 。 当 到 达 列 表的 结 尾 时 , 循 环 停 止 。 和 while 循 环 相 同 , Tcl 命 令 块 前 后 都 有 括 号 。 foreach 循 环 的 语 法 为 :

foreach 变 量 ( 值 列 表 ) { Tcl 命 令

}

Tcl 子 程 序 : proc

在 程 序 中 使 用 proc 命 令 可 以 定 义 自 己 的 Tcl 命 令 , 即 可 以 建 立 新 的 子 程 序 ,

这 一 点 与 其 它 编 程 语 言 中 的 子 程 序 和 子 函 数 相 似 。 proc 命 令 存 在 3 个 参 数 : 新子 程 序 的 程 序 名 , 子 程 序 使 用 的 参 数 列 表 和 需 要 执 行 的 语 句 。 程 序 名 后 所 跟 的参 数 列 表 前 后 都 有 花 括 号 , 表 示 使 用 子 程 序 时 所 接 收 的 参 数 。 proc 命 令 的 语 法为 :

proc 子 程 序 名 { 参 数 } { Tcl 命 令

}

下 面 的 例 子 实 现 了 lsearch 命 令 , 它 的 功 能 是 在 列 表 中 搜 索 某 个 特 定 的 模

式 。

proc mysearch {mylist pat} { set i 0

set len [ length $mylist ] while { $i < $len } {

if { [lindex $mylist $i] == $pat} return $i

}

}

Tcl 字 符 串 命 令 : string

Tcl 中 的 string 命 令 可 以 对 字 符 串 进 行 各 种 操 作 。 根 据 完 成 的 任 务 不 同 , 它

有 各 种 不 同 的 选 项 形 式 。 这 些 选 项 在 string 命 令 后 输 入 , 根 据 选 项 的 不 同 完 成字 符 串 搜 索 、 取 子 串 或 获 取 字 符 串 长 度 等 功 能 。 命 令 使 用 的 参 数 根 据 选 项 的 不同 也 有 变 化 。 表 25-3 中 列 出 了 这 些 Tcl 字 符 串 命 令 。

在 使 用 string match 命 令 时 , 只 能 在 字 符 串 中 完 成 基 本 的 搜 索 操 作 , 该 命令 不 提 供 对 正 则 表 达 式 进 行 匹 配 的 功 能 。 但 该 命 令 提 供 了 对 * 、 ? 和 []特 殊 字 符 的支 持 。 该 命 令 使 用 两 个 参 数 , 搜 索 使 用 的 模 式 和 需 要 进 行 搜 索 的 字 符 串 。

string match report* $fname

string range 命 令 返 回 字 符 串 中 指 定 的 子 串 。 该 命 令 带 有 3 个 参 数 : 字 符 串 、开 始 和 结 束 位 置 。 结 束 位 置 上 的 end 表 示 对 字 符 串 的 剩 下 所 有 的 部 分 进 行 拷 贝 。

string range 4 9 string range 3 end

string index 命 令 返 回 字 符 串 中 指 定 位 置 的 单 个 字 符 。 该 命 令 使 用 2 个 参 数 : 字 符 串 和 需 要 返 回 的 字 符 位 置 。

string index $mystring 5

string length 命 令 返 回 字 符 串 的 长 度 。

string length $mystring

使 用 regexp 命 令 可 以 完 成 正 则 表 达 式 的 搜 索 工 作 , regexp 命 令 和 egrep 命 令 类 似 , 可 以 支 持 所 有 的 正 则 表 达 式 扩 展 属 性 。 它 使 用 2 个 参 数 : 正 则 表 达式 模 式 和 需 要 搜 索 的 字 符 串 。 如 果 搜 索 到 指 定 的 模 式 , 该 命 令 返 回 1 , 否 则 返回 0 。 下 面 的 例 子 将 在 mystring 变 量 中 寻 找 数 字 。

regexp [0-9 ]+ $mystring

regsub 是 Tcl 中 的 替 换 命 令 。 它 和 regexp 类 似 , 在 字 符 串 中 进 行 使 用 正 则表 达 式 进 行 匹 配 , 然 后 将 匹 配 的 部 分 替 换 为 指 定 的 字 符 串 , 将 返 回 的 值 储 存 在一 个 新 的 变 量 中 。 regsub 使 用 4 个 参 数 , 前 面 两 个 参 数 与 regexp 相 同 , 分 别为 正 则 表 达 式 模 式 和 需 要 搜 索 的 字 符 串 。 第 3 个 参 数 为 替 代 字 符 串 , 第 4 个 参数 为 修 改 后 的 字 符 串 存 放 的 变 量 名 。

Tcl 输 入 、 输 出

Tcl 使 用 gets 命 令 从 标 准 输 入 设 备 或 文 件 中 读 取 输 入 数 据 , 使 用 puts 命 令向 标 准 输 出 设 备 或 文 件 输 出 数 据 。 下 面 的 例 子 将 从 标 准 输 入 设 备 中 ( 通 常 是 键 盘 ) 读 入 一 行 , 读 入 的 内 容 将 储 存 在 变 量 line 中 。

gets line

puts 命 令 将 向 标 准 输 出 设 备 或 文 件 输 出 数 据 , 命 令 的 参 数 为 需 要 输 出 的 字符 串 。

puts $line

gets 命 令 将 读 入 的 一 行 内 容 储 存 在 指 定 的 变 量 中 , 可 以 使 用 该 变 量 对 读 入的 内 容 进 行 处 理 。

例 如 , 可 以 在 puts 命 令 中 使 用 line 显 示 输 入 的 内 容 。

myread

#! /usr/bin/tclsh gets line

puts "This is what I entered: $line"

$myread

larisa and aleina

This is what I entered: larisa and aleina

使 用 print 命 令 可 以 向 文 件 或 标 准 输 出 设 备 输 出 数 据 , 文 件 句 柄 名 放 在 print

命 令 和 输 出 的 数 据 之 间 。 如 果 没 有 指 定 文 件 名 , print 将 输 出 到 标 准 输 出 设 备 。

Tcl 文 件 句 柄

使 用 open 命 令 可 以 为 某 个 文 件 或 管 道 建 立 句 柄 ( 表 25-3 中 列 出 了 可 用 的 Tcl 文 件 命 令 ) 。 open 命 令 使 用 两 个 参 数 : 文 件 名 字 符 串 和 文 件 打 开 的 模 式 , 该 命令 将 返 回 一 个 文 件 句 柄 , 通 过 该 句 柄 就 可 以 对 文 件 进 行 操 作 。 文 件 名 字 符 串 可以 是 一 个 文 件 名 , 也 可 以 是 储 存 该 文 件 名 的 一 个 字 符 串 变 量 。 文 件 模 式 是 打 开文 件 时 的 权 限 , r 表 示 只 读 , w 表 示 只 写 , a 表 示 为 追 加 模 式 。 如 果 需 要 对 文 件进 行 覆 盖 或 更 新 , 应 在 文 件 模 式 中 使 用 + 。 r + 表 示 可 读 写 模 式 。 open 命 令 的语 法 为 :

open ( 文 件 名 字 符 串 , 文 件 模 式 );

一 般 来 说 , 应 在 set 命 令 中 使 用 open 命 令 , 这 样 可 以 直 接 将 open 命 令 返回 的 文 件 句 柄 赋 值 给 某 个 变 量 。 使 用 该 变 量 就 可 以 对 打 开 的 文 件 进 行 访 问 。 下面 的 例 子 使 用 只 读 权 限 打 开 reports 文 件 , 然 后 将 返 回 的 文 件 句 柄 赋 值 给 变 量myfile 。

set myfile [open "reports" r]

文 件 名 一 般 储 存 在 某 个 变 量 中 , 这 样 就 需 要 使 用 $ 前 缀 对 该 文 件 名 进 行 引用 。 在 下 面 的 例 子 中 , 文 件 名 "reports "储 存 在 filen 变 量 中 。

set myfile [open $filen r]

在 文 件 使 用 完 毕 后 , 应 该 使 用 close 命 令 关 闭 该 文 件 。 close 命 令 的 参 数 为需 要 关 闭 的 文 件 使 用 的 文 件 句 柄 。

close $myfile

gets 和 puts 命 令 可 以 使 用 文 件 句 柄 对 特 定 的 文 件 进 行 读 写 操 作 。这 里 的 gets 命 令 将 使 用 2 个 参 数 : 文 件 句 柄 和 变 量 。 该 命 令 将 从 文 件 句 柄 指 定 的 文 件 中 读取 一 行 ,然 后 将 读 入 的 结 果 储 存 在 指 定 的 变 量 中 。如 果 没 有 指 定 的 文 件 句 柄 ,gets 命 令 将 从 标 准 输 入 设 备 中 读 取 数 据 。 下 面 的 命 令 将 从 myfile 变 量 指 定 的 文 件 中读 取 一 行 , 读 入 的 结 果 储 存 在 line 变 量 中 。

gets $myfile line

puts 命 令 也 使 用 两 个 参 数 : 文 件 句 柄 和 字 符 串 。 该 命 令 将 字 符 串 的 内 容 写入 到 文 件 句 柄 指 定 的 文 件 中 。 如 果 没 有 指 定 的 文 件 句 柄 , puts 命 令 将 向 标 准 输出 设 备 输 出 数 据 。 下 面 的 命 令 将 line 变 量 中 储 存 的 字 符 串 输 出 到 myfile 变 量 指定 的 文 件 。 注 意 这 里 的 line 变 量 前 有 一 个 $ 前 缀 , 但 前 面 的 gets 命 令 中 没 有 。这 是 因 为 puts 对 字 符 串 进 行 操 作 , 而 gets 的 操 作 对 象 为 一 个 变 量 。

puts $myfile $line myreport

#! /bin/sh

# 下 一 行 使 用 tclsh

exec tclsh "$0" "$@" set reps [open "reports" r] while (gets $reps line)

{

puts $line;

}

close reps

Tk

Tk 应 用 程 序 对 Tcl 进 行 了 扩 展 , 它 提 供 了 一 系 列 创 建 和 管 理 图 形 对 象 的 命令 , 如 窗 口 、 图 标 、 按 钮 、 文 本 框 等 。 Tk 命 令 使 用 X-Windows 系 统 创 建 图 形对 象 , 与 直 接 使 用 X11 工 具 箱 相 比 , 使 用 Tk 命 令 编 写 X-Windows 图 形 程 序 要容 易 得 多 。 使 用 Tk 可 以 很 方 便 地 为 应 用 程 序 创 建 复 杂 的 基 于 窗 口 的 用 户 界 面 。 Tk 语 言 根 据 不 同 的 图 形 对 象 ( 如 窗 口 、 按 钮 、 菜 单 和 滚 动 条 等 ) 进 行 分 类 。

这 些 对 象 通 常 称 为 饰 件 。 每 一 种 饰 件 都 有 自 己 的 一 些 命 令 来 完 成 创 建 过 程 。 例如 , 使 用 button 命 令 可 以 创 建 一 个 按 钮 , 使 用 window 命 令 可 以 创 建 一 个 窗 口 。每 一 种 类 型 的 饰 件 即 为 一 个 类 , 创 建 该 饰 件 的 命 令 称 为 类 命 令 。 该 命 令 将 创 建该 类 的 一 个 实 例 , 一 个 该 类 型 的 饰 件 。 button 是 创 建 按 钮 的 类 命 令 , 表 25-4 中列 出 了 Tk 中 可 用 的 饰 件 。

wish shell 和 脚 本

Tk 在 X-Windows 系 统 下 运 行 , 在 系 统 中 , Tk 使 用 自 己 的 wish shell 来 运行 Tk 命 令 。 在 运 行 Tk 程 序 时 , 需 要 首 先 启 动 X- W indows 系 统 , 然 后 使 用 wish 命 令 启 动 wish shell , 这 样 会 打 开 一 个 可 以 运 行 Tk 命 令 的 窗 口 。

在 w ish shell 中 可 以 交 互 式 地 运 行 Tk 命 令 , 即 一 步 一 步 地 输 入 命 令 并 执 行 , 也 可 以 将 这 些 命 令 存 放 在 一 个 脚 本 文 件 中 , 然 后 执 行 该 脚 本 文 件 。 一 般 都 使 用后 面 的 执 行 脚 本 程 序 的 方 法 。

同 Tcl 脚 本 相 同 , Tk 脚 本 文 件 的 后 缀 名 也 为 .tc l。 例 如 , 可 以 在 Xterm 窗 口中 输 入 以 下 命 令 , 读 取 名 为 mydir.tcl 的 Tk 脚 本 文 件 并 执 行 文 件 中 的 命 令 。

$ wish mydir.tcl

如 果 希 望 象 命 令 那 样 , 创 建 可 独 立 执 行 的 脚 本 , 需 要 在 脚 本 中 调 用 wish 命令 。 同 tclsh 相 同 , 有 两 种 方 法 可 以 达 到 该 目 标 。 第 一 种 方 法 是 显 式 给 出 wish 命 令 的 路 径 名 , 脚 本 程 序 的 第 一 行 为 :

# ! /usr/bin/wish

第 二 种 方 法 不 需 要 显 式 指 定 wish 所 在 的 路 径 , 这 样 就 提 高 了 该 脚 本 程 序 的通 用 性 。 在 下 面 的 m ydir1 和 mydir2 脚 本 中 都 使 用 了 这 种 不 进 行 显 式 指 明 的 方法 。

#! /bin/sh

# 下 一 行 调 用 wish exec wish "$0" "$@"

在 建 立 独 立 执 行 的 脚 本 后 , 必 须 使 用 chmod 命 令 修 改 文 件 的 权 限 , 使 其 能够 直 接 执 行 。 修 改 完 成 后 , 就 可 以 简 单 地 键 入 文 件 名 来 执 行 该 程 序 了 。

$chmod 755 mydir1

$ mydir1

Tk 饰 件

Tk 程 序 有 许 多 类 命 令 组 成 , 使 用 这 些 类 命 令 可 以 创 建 各 种 图 形 饰 件 。 类 命令 的 参 数 为 该 饰 件 的 名 字 和 该 饰 件 的 选 项 参 数 值 。 Tk 命 令 的 格 式 与 Tcl 相 同 , 首 先 是 命 令 名 , 然 后 是 命 令 使 用 的 参 数 。 但 Tk 命 令 比 Tcl 要 复 杂 得 多 , 因 为 图形 界 面 需 要 大 量 的 参 数 来 对 相 应 的 饰 件 进 行 设 定 。 例 如 , 一 个 按 钮 就 需 要 一 个对 象 名 、 按 钮 上 需 要 显 示 的 标 题 和 选 取 该 按 钮 后 需 要 进 行 的 操 作 。 许 多 Tk 命 令都 将 使 用 各 种 选 项 指 定 对 应 的 饰 件 的 特 性 , 表 25-5 中 列 出 了 Tk 饰 件 常 用 的 一些 选 项 。 下 面 的 例 子 使 用 button 命 令 建 立 了 一 个 按 钮 。 button 命 令 的 第 一 个 参数 为 该 按 钮 的 对 象 名 , 然 后 给 出 了 各 个 选 项 的 值 。 -text 选 项 及 其 后 的 字 符 串 指定 了 按 钮 上 需 要 显 示 的 标 题 , -command 选 项 及 其 后 的 命 令 则 给 出 了 按 钮 被 单击 后 应 执 行 的 操 作 。 该 button 命 令 将 显 示 一 个 标 题 为 "Click me" 的 按 钮 , 单 击该 按 钮 将 退 出 Tk shell 。

button .mybutton -text "Click me" -command exit

在 创 建 工 作 界 面 时 , 为 了 一 个 特 定 的 任 务 一 般 需 要 定 义 多 个 不 同 的 饰 件 。其 中 一 些 饰 件 是 为 管 理 其 它 饰 件 而 创 建 的 , 如 滚 动 条 就 是 为 管 理 窗 口 而 创 建 的 。

其 它 的 一 些 类 似 文 本 输 入 框 的 饰 件 可 以 与 Tcl 程 序 交 互 通 讯 , 而 菜 单 选 项 可 以根 据 用 户 的 选 择 运 行 不 同 的 程 序 组 件 。

饰 件 的 组 织 方 式 为 分 层 结 构 。 例 如 , 为 建 立 一 个 用 来 输 入 数 据 的 窗 口 , 需要 创 建 一 个 图 形 框 , 然 后 在 框 中 放 置 相 应 的 文 本 框 和 按 钮 。 饰 件 的 对 象 名 就 反映 了 这 种 层 次 性 , 饰 件 的 对 象 名 即 采 用 其 上 层 饰 件 的 对 象 名 作 为 前 缀 。 如 果 该图 形 框 的 对 象 名 为 report, 文 本 框 的 对 象 名 则 可 能 为 report.monda y。 在 每 一 层中 以 点 号 作 为 表 示 层 次 的 间 隔 。 这 样 , 在 report 框 中 名 为 ok 的 按 钮 , 其 对 象名 可 能 为 report.ok 。

在 建 立 饰 件 时 , 需 要 指 定 该 饰 件 的 几 何 尺 寸 。 这 些 几 何 尺 寸 给 定 了 饰 件 的大 小 和 位 置 。 Tk 中 存 在 三 种 几 何 尺 寸 管 理 命 令 , pack, place 和 grid 。 在 下 面 的例 子 中 , 都 将 使 用 pack 命 令 。 在 创 建 某 个 饰 件 后 , 就 应 该 使 用 几 何 尺 寸 命 令 决定 饰 件 的 大 小 和 位 置 。 只 有 在 决 定 了 大 小 位 置 后 , 该 饰 件 才 会 在 屏 幕 上 显 示 出来 。 下 面 的 例 子 使 用 pack 命 令 决 定 .mybutton 饰 件 的 几 何 尺 寸 。 表 25-6 中 列出 了 几 种 不 同 的 几 何 命 令 。

pack .mybutton

mydir1 程 序 是 一 个 简 单 的 Tcl/Tk 程 序 , 该 程 序 可 以 在 Tk 列 表 框 饰 件 中 显示 文 件 和 目 录 名 , 程 序 中 还 附 加 了 一 个 滚 动 条 饰 件 。 图 25-1 给 出 了 列 表 框 的 显示 效 果 。 在 列 表 框 中 , 可 以 显 示 一 系 列 项 的 列 表 , 通 过 滚 动 条 可 以 在 列 表 框 中显 示 超 出 列 表 框 设 定 大 小 范 围 的 项 。 滚 动 条 的 建 立 过 程 非 常 简 单 , 首 先 使 用scrollbar 命 令 对 其 进 行 定 义 , 给 定 滚 动 条 的 对 象 名 .scroll 和 绑 定 的 命 令 , ".list yview "。 该 命 令 将 滚 动 条 附 加 到 名 为 .list 的 列 表 框 的 垂 直 方 向 上 。

scrollbar .scroll -command ".list yview"

第 25 章 Tcl, Tk 和 Expect - 图1

图 25-1 列表框和滚动条 mydir1

定 义 滚 动 条 后 , 下 一 步 是 用 listbox 命 令 定 义 一 个 名 为 .list 的 列 表 框 , 该 列表 框 垂 直 方 向 将 附 加 一 个 名 为 .scroll 的 滚 动 条 。

listbox .list -yscroll ".scroll set" -relief sunken -width 15 -height 15 -setgrid

yes

最 后 使 用 pack 命 令 建 立 以 上 定 义 的 两 个 饰 件 , 并 在 窗 口 中 进 行 显 示 。 这 两个 饰 件 将 放 置 在 窗 口 的 左 边 界 并 将 扩 展 到 整 个 窗 口 。 首 先 将 放 置 名 为 .list 的 列表 框 , 然 后 才 是 名 为 .scroll 的 滚 动 条 。

pack .list .sroll -side left -fill both -expand yes -anchor w

在 界 面 显 示 后 , 使 用 一 条 if 语 句 检 查 用 户 在 调 用 该 程 序 时 是 否 输 入 了 参 数 , argv 列 表 中 将 储 存 调 用 程 序 时 的 参 数 。 如 果 没 有 使 用 参 数 进 行 调 用 , 将 使 用 句点 符 号 对 当 前 目 录 进 行 操 作 。

在 将 选 中 的 目 录 赋 值 给 dir 变 量 后 , 使 用 foreach 循 环 填 满 列 表 框 。 循 环 使用 的 列 表 采 用 shell 的 ls 命 令 产 生 , 为 指 定 目 录 下 的 文 件 和 目 录 列 表 。 在 循 环体 中 将 使 用 Tk 的 列 表 框 insert 操 作 将 每 一 个 文 件 名 填 进 列 表 框 .list。 insert 目录 使 用 位 置 和 插 入 所 需 的 值 作 为 参 数 。 这 里 , 插 入 的 值 为 $i 中 储 存 的 文 件 名 , 插 入 的 位 置 则 为 end 指 定 的 列 表 末 尾 。

.list insert end $i

CTRL-C 控 制 字 符 将 绑 定 到 exit 命 令 , 这 样 在 按 下 CTRL-C 组 合 键 后 , 就将 关 闭 本 程 序 窗 口 。

mydir1 #! /bin/sh

# 下 一 行 启 动 wish

exec wish "$0" "$@" # 创 建 滚 动 条 和 列 表 框

scroll bar .scroll -command ".list yview"

yes

操 作

listbox .list -yscroll ".scroll set" -relief sunken -width 15 -height 15 -setgrid

pack .list .sroll -side left -fill both -expand yes -anchor w

# 如 果 用 户 输 入 了 目 录 参 数 , 将 对 该 目 录 进 行 操 作 , 否 则 将 对 当 前 目 录 进 行

if ($argc > 0) then {

set dir [lindex $argv 0]

} else { set dir "."

}

在 列 表 框 中 插 入 从 ls 命 令 获 取 的 文 件 和 目 录 列 表

cd $dir

foreach i [exec ls -a] { if [file isfile $i] {

.list insert end $i

}

}

# 设 定 文 件 管 理 器 的 绑 定 状 况 , CTRL-C 将 关 闭 该 窗 口

bind all <Control-c> {destroy.}

事 件 和 绑 定

Tk 程 序 采 用 事 件 驱 动 方 式 , 在 程 序 运 行 时 , 它 将 等 待 事 件 的 发 生 , 如 鼠 标事 件 或 键 盘 事 件 等 。 鼠 标 事 件 可 能 是 鼠 标 键 的 单 击 或 双 击 , 甚 至 鼠 标 键 按 下 和松 开 也 对 应 有 相 应 的 事 件 。 键 盘 事 件 可 能 是 CONTROL 键 、 meta 键 或 输 入 数据 结 束 的 回 车 键 被 按 下 。 当 程 序 检 测 到 一 个 特 定 的 事 件 时 , 就 会 进 行 相 应 的 动作 。 该 动 作 可 能 是 一 个 图 形 操 作 ( 如 显 示 子 菜 单 ) , 也 可 以 是 另 外 一 个 Tc l、 Perl 或 shell 程 序 。

使 用 bind 命 令 可 以 显 式 绑 定 相 应 的 事 件 和 动 作 。 bind 命 令 使 用 3 个 参 数 : 饰 件 或 类 名 、 需 要 绑 定 的 事 件 和 绑 定 到 该 事 件 的 动 作 。 一 旦 在 指 定 的 饰 件 中 发生 指 定 的 事 件 , 就 会 执 行 相 应 的 动 作 。

bind .myframe <CTRL-H> {.myframe delete insert }

可 以 使 用 bind 命 令 将 Tk 饰 件 绑 定 到 需 要 执 行 的 Tcl 命 令 。 在 这 种 情 况 下 , 整 个 Tcl 程 序 将 分 为 几 段 , 每 一 段 对 应 Tk 饰 件 中 的 一 个 事 件 。 当 饰 件 中 的 事件 发 生 时 , 就 会 去 执 行 与 之 关 联 的 Tcl 命 令 。 Tk 命 令 也 可 以 与 事 件 关 联 , 这 样就 可 以 实 现 饰 件 及 其 事 件 的 嵌 套 。 一 个 Tk 事 件 引 发 的 Tcl 命 令 可 能 会 引 发 其 它的 Tk 事 件 和 Tcl 命 令 ( 请 参 看 表 25-6 Tk 命 令 列 表 )。 图 25-2 中 显 示 的 mydir2 程 序 说 明 了 函 数 和 饰 件 的 绑 定 情 况 。 该 程 序 对 前 面 的 mydir1 程 序 进 行 了 增 强 , 可 以 显 式 两 个 列 表 框 , 分 别 用 来 显 示 目 录 和 文 件 。 每 一 个 列 表 框 都 有 自 己 的 滚动 条 。 目 录 列 表 框 名 为 .listdir , 相 应 的 滚 动 条 为 .scrolldir 。 程 序 首 先 建 立 两 个 对

第 25 章 Tcl, Tk 和 Expect - 图2话 框 和 相 应 的 两 个 滚 动 条 , .listdir 和 .scrolldir 首 先 建 立 , 因 此 它 们 的 位 置 位 于窗 口 的 左 边 。 下 一 步 是 定 义 Tcl 函数 listdirsfuncs , 该 函 数 的 作 用 是 填 满 列 表 框 。该 函 数 的 参 数 为 需 要 显 示 的 目 录 名 。 程 序 将 首 先 使 用 cd 目 录 切 换 到 指 定 的 目录 , 然 后 使 用 isdirectory 函 数 检 查 列 出 的 文 件 是 否 为 目 录 名 , 如 果 是 , 则 将 其放 到 .listdir 列 表 框 中 。 在 该 函 数 定 义 后 是 对 该 函 数 的 调 用 。 在 程 序 运 行 时 应 该首 先 调 用 一 次 listdirfuncs 函 数 , 用 当 前 目 录 中 的 内 容 填 满 列 表 框 。

图 25-2 目录和文件列表框 mydir2

程 序 中 存 在 .listdir 饰 件 的 一 个 绑 定 。 鼠 标 左 键 双 击 事 件 ,Double-Button-1 , 绑 定 到 了 .listdir 列 表 框 的 listdirsfuncs 函 数 。 该 绑 定 使 得 在 .listdir 列 表 框 中 的 任何 鼠 标 左 键 双 击 事 件 都 将 调 用 一 次 listdirsfuncs 函 数 。 由 于 在 .list 列 表 框 中 不 存在 相 应 的 绑 定 , 因 此 在 该 列 表 框 中 的 双 击 事 件 将 没 有 任 何 效 果 。

.listdir 列 表 框 中 的 双 击 事 件 绑 定 了 两 个 动 作 。 这 两 个 动 作 都 放 置 在 事 件 后的 括 号 中 。 第 一 个 动 作 是 从 列 表 框 中 获 取 选 定 的 目 录 名 。 当 用 户 在 列 表 框 中 的某 一 项 上 单 击 时 , 将 同 时 选 定 该 项 。 [selection get] 操 作 将 返 回 选 定 的 项 , 此 时为 选 定 的 文 件 名 。 文 件 名 将 赋 值 给 变 量 i。 然 后 执 行 第 二 个 动 作 , 使 用 该 变 量 作为 参 数 调 用 listdirsfuncs 函 数 。 这 两 个 动 作 说 明 了 如 何 在 绑 定 中 获 取 所 需 的 值 , 如 何 使 用 这 些 参 数 进 行 函 数 调 用 。

绑 定 是 Tk 程 序 中 最 主 要 的 功 能 组 件 。 绑 定 将 检 测 能 够 驱 动 Tk 程 序 的 事 件 。可 以 将 Tk 程 序 想 象 成 一 个 无 限 的 循 环 , 在 循 环 中 程 序 不 断 监 视 特 定 事 件 的 发生 。 一 旦 程 序 检 测 到 这 种 事 件 , 如 鼠 标 单 击 或 控 制 键 按 下 , 程 序 就 会 自 动 去 运行 与 该 事 件 绑 定 的 动 作 。 这 些 动 作 可 以 是 任 何 Tcl/Tk 命 令 或 命 令 序 列 。 通 常 , 事 件 引 发 的 动 作 将 调 用 一 些 函 数 , 可 以 完 成 非 常 复 杂 的 操 作 。 当 动 作 完 成 后 , 程 序 又 会 回 到 无 限 的 循 环 中 , 重 复 监 视 事 件 发 生 的 工 作 。 该 循 环 只 在 使 用 exit 或 destroy 命 令 时 退 出 , 通 常 这 两 个 命 令 将 绑 定 到 CTRL-C 组 合 键 。 从 某 种 意义 上 来 说 , 绑 定 就 是 程 序 的 一 种 多 重 入 口 结 构 , 从 不 同 的 入 口 将 执 行 不 同 的 操作 。 但 绑 定 与 传 统 的 层 次 顺 序 结 构 的 程 序 完 全 不 同 , 每 一 个 绑 定 事 件 都 会 引 发它 自 己 的 命 令 序 列 , 自 己 的 程 序 。

在 对 Tk 程 序 的 控 制 流 程 进 行 跟 踪 时 , 也 是 从 绑 定 开 始 , 每 一 个 绑 定 都 会 有

自 己 的 控 制 流 程 。

mydir2 #! /bin/sh

# 下 一 行 启 动 wish

exec wish "$0" "$@"

# 创 建 目 录 所 用 的 列 表 框 和 滚 动 条

scrollbar .scrolldir -command ".listdir yview"

listbox .listdir -yscroll ".scrolldir set" -relief sunken -width 15 -height 15 - setgrid yes

pack .listdir .scrolldir -side left -fill both -expand yes -anchor w# 创 建 文 件所 用 的 列 表 框 和 滚 动 条

scrollbar .scroll -command ".list yview"

listbox .list -yscroll ".scroll set" -relief sunken -width 15 -height 15 -setgrid yes

pack .list .scroll -side left -fill both -expand yes -anchor w# 检 查 调 用 时 是

否 使 用 了 参 数

if $argc>0 {set dir [lindex $argv 0]} else {set dir "."}--> # 列 出 目 录 和 文 件 的 函 数

# 当 前 项 首 先 被 删 除

proc listdirsfunc dir {

.listdir delete 0 end

.list delete 0 end

cd $dir

foreach i [exec ls -a ] {

if [file isdirectory $i] {

.listdir insert end $i

} else {

.list insert end $i

}}

}

# 初 次 显 示 目 录 和 文 件

listdirsfunc $dir

# 设 定 绑 定 情 况 , 对 列 表 框 中 的 鼠 标 双 击 双 击 进 行 绑 定

bind all <Control-c> {destroy.}

bind .listdir <Double-Button-1> {set i [selection get] listdirsfunc $i}

SpecTcl

在 建 立 GUI 图 形 界 面 时 , 除 了 显 式 使 用 Tk 代 码 进 行 编 程 外 , 还 可 以 使 用SpecTcl GUI builder 来 进 行 编 程 。 SpecTcl 可 以 为 Tcl/Tk 应 用 程 序 简 单 地 建 立图 形 方 式 的 用 户 界 面 。 从 网 址 sunscipt.sun.com 可 以 下 载 SpecTcl 的 Unix 版

本 。 SpecTcl 本 身 也 是 一 个 Tcl/Tk 应 用 程 序 , 至 少 需 要 Tcl 7.6 和 Tk 4.7 的 支持 , 推 荐 使 用 Tcl 和 Tk 的 8.0 版 本 。 OpenLinux 光 盘 中 只 有 Tcl 7.4 和 Tk 4.1 , 因 此 在 运 行 SpecTcl 前 需 要 首 先 下 载 、 编 译 并 安 装 Tcl 和 Tk 的 8.0 版 本 。

在 下 载 SpecTcl 并 将 其 展 开 后 , 更 换 到 SpecTel1.1 目 录 下 的 bin 目 录 ( 当 然也 可 以 将 其 安 装 到 任 何 指 定 的 目 录 ).在 该 目 录 中 可 以 找 到 SpecTcl 和 SpecJava 程 序 。 键 入 SpecTcl 以 运 行 该 程 序 , 程 序 将 询 问 用 户 需 要 将 设 计 的 结 果 输 出 为何 种 格 式 :Tc l 、Java 、http 还 是 Perl 格 式 。Linux 中 的 SpecTcl 是 一 个 X- W indows 程 序 , 它 拥 有 自 己 的 图 形 界 面 , 包 括 窗 口 、 菜 单 和 图 标 等 饰 件 。 使 用 该 程 序 , 可 以 很 方 便 地 使 用 菜 单 选 项 和 鼠 标 操 作 建 立 复 杂 的 图 形 界 面 。

SpecTcl 提 供 了 网 格 状 的 几 何 位 置 管 理 器 , 可 以 方 便 地 建 立 跨 平 台 的 图 形界 面 。 图 25-3 显 示 了 SpecTcl 窗 口 。

Tcl/Tk 网 站 包 含 SpecTcl 的 全 部 详 细 使 用 文 档 。 创 建 一 个 饰 件 时 只 需 要 简单 地 单 击 调 色 板 上 的 图 标 并 将 其 拖 到 网 格 中 即 可 。 调 色 板 即 为 窗 口 左 边 的 两 排图 标 , 将 鼠 标 停 留 在 图 标 上 时 , 在 SpecTcl 窗 口 的 底 部 将 显 示 出 相 应 的 操 作 信息 。

对 饰 件 进 行 属 性 设 置 时 , 只 需 要 选 中 该 饰 件 , 并 从 工 具 条 上 选 中 适 当 的 选项 即 可 。 工 具 条 由 窗 口 上 方 的 图 标 组 成 。 工 具 条 的 下 拉 菜 单 中 包 含 了 一 些 常 用的 选 项 ,如 字 体 或 大 小 等 。选 中 某 个 饰 件 ,然 后 在 Edit 菜 单 中 选 择 饰 件 properties 选 项 , 可 以 对 该 饰 件 的 所 有 属 性 进 行 设 置 。 单 击 Additional Properties 框 可 以列 出 所 有 可 以 进 行 设 置 的 属 性 。

第 25 章 Tcl, Tk 和 Expect - 图3

图 25-3SpectTcl,the Tcl/Tk GUI Builder

选 择 并 拖 动 某 个 饰 件 , 可 以 移 动 该 饰 件 的 位 置 。 选 择 饰 件 后 按 DEL 键 可 以删 除 该 饰 件 , 单 击 右 上 角 的 回 收 站 图 标 也 可 以 完 成 同 样 的 功 能 。 在 界 面 建 立 后 , 可 以 单 击 右 上 角 的 测 试 按 钮 对 其 进 行 测 试 。

Expect

通 过 Expect 提 供 的 命 令 , 程 序 可 以 自 动 地 与 任 何 需 要 交 互 式 操 作 的 Unix 应 用 程 序 提 供 响 应 。 例 如 , 使 用 Expect 命 令 可 以 建 立 能 够 自 动 进 行 ftp 或 telnet 登 录 操 作 的 程 序 。 Expect 是 为 与 任 何 需 要 交 互 式 操 作 的 程 序 相 互 通 讯 而 设 计的 。 它 可 以 等 待 应 用 程 序 返 回 的 消 息 , 然 后 向 应 用 程 序 发 送 脚 本 中 指 定 的 响 应 。这 样 , 用 户 就 可 以 执 行 一 个 简 单 的 命 令 , 来 完 成 复 杂 的 交 互 操 作 功 能 。

Expect 中 存 在 3 个 基 本 的 命 令 : send 、 expect 和 interac t。 expect 命 令 将等 待 从 应 用 程 序 返 回 的 字 符 串 或 值 , send 命 令 则 可 以 向 应 用 程 序 发 送 指 定 的 字符 串 。 interat 命 令 结 束 Expect/Tcl 脚 本 程 序 , 使 用 户 可 以 直 接 与 应 用 程 序 进 行交 互 式 操 作 。 在 下 面 的 脚 本 程 序 中 , Expect 将 用 来 完 成 一 次 ftp 的 自 动 匿 名 登录 。 spawn 命 令 启 动 ftp 程 序 , ftp 站 点 的 地 址 作 为 调 用 参 数 传 递 给 ftp 程 序 , 该 参 数 将 储 存 在 argv 列 表 中 。

myftp

#! /usr/bin/expect spawn ftp

send "open $argv \r"

expect "Name"

send "anonymous \r" expect "word:"

send richlp@turtle.trek.com \r

interact

在 运 行 Expect 命 令 前 , 需 要 首 先 进 入 Expect shell 。 在 前 面 的 脚 本 程 序 中 , 使 用 #! /usr/bin/expect 命 令 调 用 Expect shell 。 注 意 , 在 执 行 myftp 程 序 前 必 须首 先 使 用 chmod 755 myftp 命 令 赋 给 该 脚 本 程 序 可 执 行 权 限 。

$myftp ftp.caldera.com

expect 命 令 可 以 使 用 两 个 参 数 , 一 个 期 待 接 收 到 的 模 式 串 和 收 到 该 模 式 串后 需 要 作 的 动 作 。 expect 也 可 以 使 用 一 个 模 式 /动 作 语 句 块 作 为 相 应 的 参 数 。 在这 种 情 况 下 , expect 命 令 可 以 对 多 个 模 式 串 进 行 匹 配 , 然 后 根 据 接 收 到 的 消 息执 行 相 应 的 动 作 。 例 如 , ftp 命 令 可 能 会 返 回 一 个 "Connection refused" 字 符 串 , 而 不 是 "Name" 字 符 串 。 在 这 种 情 况 下 , 需 要 显 示 该 信 息 并 退 出 Expect 脚 本 程序 。 如 果 针 对 接 收 到 的 消 息 需 要 执 行 多 个 操 作 时 , 可 以 将 这 些 操 作 使 用 分 号 隔开 , 然 后 前 后 加 上 花 括 号 封 装 起 来 。

另 外 一 个 有 用 的 Expect 命 令 是 timeout 命 令 。 可 以 使 用 timeout 命 令 设 定超 时 所 需 的 时 间 , 然 后 用 expect 命 令 检 查 联 接 是 否 超 时 。 设 定 时 间 时 , 应 使 用set 命 令 对 timeout 变 量 进 行 赋 值 ( 单 位 为 秒 , 默 认 值 为 10 秒 )。在 expect 块 中使 用 timeout 作 为 接 收 模 式 , 就 可 以 检 测 联 接 是 否 超 时 。下 面 是 这 样 一 个 expect 脚 本 的 例 子 :

set timeout 20 send "open $argv" expect {

timeout { puts "Connection timed out\n"; exit }

"Connection refused" { puts "Failed to connect\n"; exit } "Unkown Host" { puts "$argv is unknown\n"; exit } "Name"

}

表 25-1Tcl/Tk 软 件 产 品

TclTcl

编 程 语 言 及 解 释 器 (最 新 版 本 8.0)

tcl8.0.tar.gz

Tk

Tk 编 程 语 言 ( 最 新 版 本 8.0)

tk8.0.tar.gz

SpecTcl

Tcl/Tk GUI builder, 建 立 图 形 方 式 的用 户 界 面

SpecTcl1.1.tar.gz

Tcl Plugin

Tcl/Tk 网 页 插 件 , (最 新 版 本 2.0);

Tcl/Tk 应 用 程 序 (Tclets)

查 看 器 tclplugin1.1.386.rpm

TclHttpd

Tcl/Tk 网 络 服 务 器

tclhttpd.tar.Z

sunscript.sun.com

Tcl/Tk 网 址

表 25-2Tcl 列 表 操 作

命 令

操 作

set 列 表 值

建 立 列 表 并 赋 值

lsearch (列 表 , 模 式 )

在 列 表 元 素 中 搜 索 指 定 模 式

lindex( 列 表 , 索 引 )

返 回 列 表 中 指 定 索 引 位 置 的 值

llength( 列 表 )

返 回 列 表 中 元 素 的 个 数

linsert( 列 表 , 索 引 , 值 列 表 )

在 列 表 中 指 定 索 引 位 置 后 插 入 指 定 的

lreplace (列 表 , 索 引 , 值 列 表 )

将 列 表 中 指 定 索 引 的 值 替 换 为 新 值

lappend (列 表 , 值 列 表 )

在 列 表 的 末 尾 添 加 新 值

concat( 列 表 )

将 多 个 列 表 的 值 联 接 到 一 个 列 表 中

list( 列 表 )

将 多 个 列 表 组 合 为 一 个 列 表 , 该 列 表

的 各 个 元 素 的 值 即 为 每 个 列 表

split(字 符 串 , 分 隔 符 )

使 用 指 定 的 分 隔 符 将 字 符 串 进 行 分隔 , 然 后 将 分 隔 后 的 结 果 储 存 在 列 表中

join (列 表 )

将 列 表 中 的 元 素 组 合 为 字 符 串

lsort( 列 表 )

对 列 表 按 字 符 或 数 字 顺 序 进 行 排 序

表 25-3 常 用 的 Tcl 命令

赋 值 和 变 量

说 明

set

对 变 量 进 行 赋 值

global

声 明 全 局 变 量

incr

对 某 个 变 量 增 加 指 定 的 整 数 值

unset

删 除 变 量

upvar

在 变 量 的 声 明 范 围 外 引 用 该 变 量

variable

声 明 变 量 名

array

数 组 引 用

expr

数 学 表 达 式

控 制 结 构 和 子 程 序

if

条 件 命 令 , 可 以 使 用 else 和 elseif 语 句 块

switch

switch 选 择 结 构

while

while 循环

for

for 循环

foreach

为 列 表 操 作 设 计 的 循 环

break

强 行 退 出 循 环

continue

跳 过 循 环 块 中 的 语 句 , 直 接 开 始 下 一 次 迭 代

proc

定 义 Tcl 子 程 序

return

从 子 程 序 中 返 回 值

source

读 入 并 执 行 另 外 一 个 文 件 中 的 Tcl 命 令

续 表

uplevel

执 行 上 一 层 的 命 令

文 件

file

获 取 文 件 信 息

open

打 开 文 件

close

关 闭 文 件

eof

检 查 是 否 到 文 件 末 尾

fcopy

拷 贝 文 件

flush

刷 新 文 件 缓 冲 区

glob

使 用 全 局 匹 配 字 符 匹 配 文 件 名

read

从 文 件 中 读 取 字 符 块

seek

确 定 文 件 指 针 的 位 置

tell

返 回 当 前 文 件 指 针 的 位 置

socket

打 开 一 个 TCP/IP 网 络 联 接

输 入 /输 出

format

使 用 指 定 的 格 式 对 字 符 串 进 行 格 式 处 理 , 与 C 语言 中 的 sprintf 类 似

scan

使 用 指 定 的 格 式 读 入 数 据 并 将 其 转 化 为 字 符 串 元素 , 与 C 语 言 中 的 scanf 类似

gets

读 入 一 行

puts

输 出 一 行

续 表

字 符 串

binary

在 字 符 串 和 二 进 制 数 据 中 进 行 转 换

regexp

使 用 正 则 表 达 式 对 字 符 串 进 行 模 式 匹 配

regsub

使 用 正 则 表 达 式 对 字 符 串 进 行 替 换 操 作

split

将 字 符 串 分 隔 为 列 表 元 素 赋 值 和 变 量 说 明

string 对 字 符 串 进 行 操 作

subst 对 字 符 串 进 行 替 换 操 作

系 统

catch

跟 踪 错 误

cd

更 改 工 作 目 录

clock

返 回 当 前 时 间 和 日 期

error

产 生 错 误

eval

执 行 命 令

exec

执 行 UN IX 命 令

exit

结 束 程 序 并 退 出

pwd

返 回 当 前 工 作 目 录

info

查 看 当 前 Tcl 解 释 器 的 信 息

trace

检 查 变 量 的 值

表 25-4 常 用 的 Tk 命 令 选 项

选 项

描 述

-anchor

饰 件 上 的 信 息 如 何 显 示 , 必 须 为 下 列 值 之 一 :

n,ne,e,se,s,sw,w,nw,center

-background

显 示 饰 件 时 的 背 景 颜 色

-bitmap

饰 件 中 显 示 的 位 图

-borderwidth

饰 件 边 缘 三 维 边 界 的 宽 度

-cursor

饰 件 中 使 用 的 鼠 标 光 标 形 状

-font

在 饰 件 中 显 示 文 本 时 使 用 的 字 体

-foreground

显 示 饰 件 时 的 前 景 颜 色

-geometry

饰 件 窗 口 的 几 何 尺 寸

-highlightbackground

当 饰 件 中 没 有 输 入 焦 点 时 的 背 景 颜 色

-highlightcolor

当 饰 件 中 存 在 输 入 焦 点 时 的 高 亮 度 颜 色

-image

饰 件 中 显 示 的 图 形

-insertbackground

插 入 光 标 覆 盖 处 的 背 景 颜 色

-justify

多 行 文 本 的 对 齐 方 式

-orient

饰 件 放 置 的 位 置

-padx

饰 件 的 X 方 向 上 请 求 分 配 的 多 余 空 间

-pady

饰 件 的 Y 方 向 上 请 求 分 配 的 多 余 空 间

-relief

饰 件 使 用 的 3 维 效 果

-selectbackground

显 示 被 选 择 的 项 时 使 用 的 背 景 颜 色

续 表

-text

饰 件 内 显 示 的 文 本

-textvariable

变 量 名

-troughcolor

饰 件 中 滚 动 条 等 矩 形 对 象 使 用 的 颜 色

-underline

饰 件 中 需 要 使 用 下 划 线 的 字 符 位 置

-xscrollcommand

与 水 平 滚 动 条 进 行 通 讯 的 命 令

-yscrollcommand

与 垂 直 滚 动 条 进 行 通 讯 的 命 令 按 钮 选 项

-command

与 按 钮 绑 定 的 Tcl 命令

-selectimage

复 选 框 被 选 择 时 显 示 的 图 形

-height

按 钮 的 高 度

-selectcolor

按 钮 被 选 择 时 的 背 景 颜 色

-state

指 定 单 选 框 的 状 态 : 一 般 、 选 中 或 无 效

-variable

表 明 按 钮 是 否 被 选 中 的 全 局 变 量

表 25-5 标 准 的 Tk 饰 件

饰 件

描 述

button

按 钮

canvas

窗 口

checkbutton

复 选 框

entry

输 入 框

frame

框 架 , 主 要 任 务 是 在 复 杂 的 窗 口 设 计 中 起 分 隔 美 观 作 用

image

图 形

label

标 签

listbox

列 表 框

menu

菜 单

menubutton

菜 单 按 钮 , 可 以 对 菜 单 进 行 访 问

message

消 息

radiobutton

单 选 框

scrollbar

滚 动 条

text

可 编 辑 的 文 本 框

scale

标 尺

表 25-6Tk 操 作

选 项

描 述

事 件 操 作

描 述

bind

绑 定 X 事 件 与 Tcl 脚 本

bindtags

绑 定 命 令 和 标 记

selection

使 用 鼠 标 选 取 饰 件 或 文 本

几 何 尺 寸 管 理 命 令

pack

将 饰 件 紧 密 放 置

grid

将 饰 件 按 网 格 行 列 放 置

place

将 饰 件 放 置 在 框 架 指 定 位 置 上

窗 口 操 作

destroy

关 闭 Tk 窗 口

toplevel

选 择 最 顶 端 的 窗 口

wm

设 置 窗 口 特 性

uplevel

将 窗 口 上 移 一 个 层 次