Tcl-Tk 快速指南



Tcl - 概述

Tcl 是 **工具命令语言** 的缩写形式。加州大学伯克利分校的 John Ousterhout 设计了它。它结合了脚本语言及其自己的解释器,该解释器嵌入到我们用它开发的应用程序中。

Tcl 最初是为 Unix 开发的。然后移植到 Windows、DOS、OS/2 和 Mac OSX。Tcl 与其他 Unix shell 语言非常相似,例如 Bourne Shell (Sh)、C Shell (csh)、Korn Shell (sh) 和 Perl。

它旨在为程序提供与其他程序交互的能力,以及充当可嵌入解释器的能力。即使最初的目标是使程序能够交互,您也可以找到用 Tcl/Tk 编写的完整应用程序。

Tcl 的特性

Tcl 的特性如下:

  • 缩短开发时间。

  • 通过集成 TK,提供强大且简单用户界面工具包。

  • 一次编写,随处运行。它可以在 Windows、Mac OS X 和几乎所有 Unix 平台上运行。

  • 对于有经验的程序员来说,入门非常容易;因为该语言非常简单,他们可以在几个小时或几天内学会 Tcl。

  • 您可以轻松地使用 Tcl 扩展现有应用程序。此外,还可以将 Tcl 包含到 C、C++ 或 Java 中,反之亦然。

  • 拥有强大的网络功能集。

  • 最后,它是一个开源的、免费的,并且可以用于商业应用程序,没有任何限制。

应用

Tcl 是一种通用语言,您可以在任何地方找到 Tcl。它包括:

  • 通常由数据库支持的可扩展网站。
  • 使用 TclHttpd 构建的高性能 Web 服务器。
  • 使用 CGI 的 Tcl 网站。
  • 桌面 GUI 应用程序。
  • 嵌入式应用程序。

Tcl - 环境设置

本地环境设置

如果您希望为 Tcl 设置环境,则需要在您的计算机上安装以下两个软件应用程序:

  • 文本编辑器
  • Tcl 解释器。

文本编辑器

这将用于键入您的程序。一些文本编辑器的示例包括 Windows 记事本、OS Edit 命令、Brief、Epsilon、EMACS 和 vim 或 vi。

文本编辑器的名称和版本在不同的操作系统上可能有所不同。例如,Notepad 将用于 Windows,而 vim 或 vi 既可以用于 Windows,也可以用于 Linux 或 UNIX。

使用文本编辑器创建的文件称为源文件,其中包含程序源代码。Tcl 程序的源文件以扩展名 **".tcl"** 命名。

在开始编程之前,请确保您已准备好一个文本编辑器,并且您有足够的经验来编写计算机程序、将其保存到文件中、构建它,最后执行它。

Tcl 解释器

它只是一个小型程序,使您能够键入 Tcl 命令并逐行执行它们。如果遇到错误,它会停止执行 tcl 文件,这与执行完整的编译器不同。

让我们创建一个名为 helloWorld.tcl 的文件,如下所示。我们将使用它作为第一个程序,在您选择的平台上运行。

#!/usr/bin/tclsh

puts "Hello World!" 

在 Windows 上安装

从提供的 Active Tcl 二进制文件列表中下载适用于 Windows 的最新版本 安装程序。Active Tcl 社区版可免费用于个人使用。

运行下载的可执行文件以安装 Tcl,这可以通过按照屏幕上的说明进行。

现在,我们可以通过使用 'cd' 命令切换到包含该文件的文件夹,然后使用以下步骤执行程序来构建和运行 Tcl 文件,例如 helloWorld.tcl

C:\Tcl> tclsh helloWorld.tcl

我们可以看到以下输出。

C:\Tcl> helloWorld

C:\Tcl 是我用来保存示例的文件夹。您可以将其更改为您保存 Tcl 程序的文件夹。

在 Linux 上安装

大多数 Linux 操作系统都内置了 Tcl,您可以在这些系统上立即开始使用。如果不可用,您可以使用以下命令下载并安装 Tcl-Tk。

$ yum install tcl tk

现在,我们可以通过使用 'cd' 命令切换到包含该文件的文件夹,然后使用以下步骤执行程序来构建和运行 Tcl 文件,例如 helloWorld.tcl:

$ tclsh helloWorld.tcl

我们可以看到以下输出:

$ hello world

在基于 Debian 的系统上安装

如果您的操作系统中没有,您可以使用以下命令下载并安装 Tcl-Tk:

$ sudo apt-get install tcl tk

现在,我们可以通过使用 'cd' 命令切换到包含该文件的文件夹,然后使用以下步骤执行程序来构建和运行 Tcl 文件,例如 helloWorld.tcl:

$ tclsh helloWorld.tcl

我们可以看到以下输出:

$ hello world

在 Mac OS X 上安装

从提供的 Active Tcl 二进制文件列表中下载适用于 Mac OS X 的最新版本 软件包。Active Tcl 社区版可免费用于个人使用。

运行下载的可执行文件以安装 Active Tcl,这可以通过按照屏幕上的说明进行。

现在,我们可以通过使用 'cd' 切换到包含该文件的文件夹,然后使用以下步骤执行程序来构建和运行 Tcl 文件,例如 helloWorld.tcl:

$ tclsh helloWorld.tcl

我们可以看到以下输出:

$ hello world

从源文件安装

当二进制软件包不可用时,您可以选择从源文件安装。通常建议对 Windows 和 Mac OS X 使用 Tcl 二进制文件,因此仅在下面显示了基于 unix 系统上的源代码编译。

  • 下载 源文件。

  • 现在,切换到下载的文件夹后,使用以下命令进行提取、编译和构建。

$ tar zxf tcl8.6.1-src.tar.gz
$ cd tcl8.6.1
$ cd unix
$ ./configure —prefix=/opt —enable-gcc
$ make
$ sudo make install

**注意** - 请确保将文件名更改为您在上面给出的命令 1 和 2 中下载的版本。

Tcl - 特殊变量

在 Tcl 中,我们将某些变量分类为特殊变量,它们具有预定义的用法/功能。特殊变量的列表如下所示。

序号 特殊变量 & 描述
1

argc

指命令行参数的数量。

2

argv

指包含命令行参数的列表。

3

argv0

指正在解释的文件的文件名或我们用来调用脚本的名称。

4

env

用于表示环境变量元素的数组。

5

errorCode

提供上次 Tcl 错误的错误代码。

6

errorInfo

提供上次 Tcl 错误的堆栈跟踪。

7

tcl_interactive

分别通过将其设置为 1 和 0 来在交互模式和非交互模式之间切换。

8

tcl_library

用于设置标准 Tcl 库的位置。

9

tcl_pkgPath

提供通常安装软件包的目录列表。

10

tcl_patchLevel

指 Tcl 解释器的当前补丁级别。

11

tcl_platform

用于表示包含 byteOrder、machine、osVersion、platform 和 os 等对象的元素数组。

12

tcl_precision

指精度,即在将浮点数转换为字符串时要保留的位数。默认值为 12。

13

tcl_prompt1

指主提示符。

14

tcl_prompt2

指带有无效命令的辅助提示符。

15

tcl_rcFileName

提供用户特定的启动文件。

16

tcl_traceCompile

用于控制字节码编译的跟踪。使用 0 表示无输出,1 表示摘要,2 表示详细。

17

tcl_traceExec

用于控制字节码执行的跟踪。使用 0 表示无输出,1 表示摘要,2 表示详细。

18

tcl_version

返回 Tcl 解释器的当前版本。

上述特殊变量对 Tcl 解释器具有特殊含义。

使用 Tcl 特殊变量的示例

让我们看看一些特殊变量的示例。

Tcl 版本

#!/usr/bin/tclsh

puts $tcl_version

运行程序时,您将获得如下所示的类似输出:

8.6

Tcl 环境路径

#!/usr/bin/tclsh

puts $env(PATH)

运行程序时,您将获得如下所示的类似输出:

/home/cg/root/GNUstep/Tools:/usr/GNUstep/Local/Tools:/usr/GNUstep/
System/Tools:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/webmaster/.local/bin:/
home/webmaster/bin:/usr/local/scriba/bin:/usr/local/smlnj/
bin:/usr/local/bin/std:/usr/local/bin/extra:/usr/local/fantom/bin:/usr/
local/dart/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/opt/mono/
bin:/opt/mono/lib/mono/4.5:/usr/local/bin:.:/usr/libexec/sdcc:/usr/local/
icon-v950/bin:/usr/local/mozart/bin:/opt/Pawn/bin:/opt/jdk1.7.0_75/bin:/
opt/jdk1.7.0_75/jre/bin:/opt/pash/Source/PashConsole/bin/Debug/

Tcl 软件包路径

#!/usr/bin/tclsh

puts $tcl_pkgPath

运行程序时,您将获得如下所示的类似输出:

/usr/lib64/tcl8.6 /usr/share/tcl8.6 /usr/lib64/tk8.6 /usr/share/tk8.6

Tcl 库

#!/usr/bin/tclsh

puts $tcl_library

运行程序时,您将获得如下所示的类似输出:

/usr/share/tcl8.6

Tcl 补丁级别

#!/usr/bin/tclsh

puts $tcl_patchLevel

运行程序时,您将获得如下所示的类似输出:

8.6.6

Tcl 精度

#!/usr/bin/tclsh

puts $tcl_precision

运行程序时,您将获得如下所示的类似输出:

0

Tcl 启动文件

#!/usr/bin/tclsh

puts $tcl_rcFileName

运行程序时,您将获得如下所示的类似输出:

~/.tclshrc

Tcl - 基本语法

Tcl 非常容易学习,让我们开始创建我们的第一个 Tcl 程序吧!

第一个 Tcl 程序

让我们编写一个简单的 Tcl 程序。所有 Tcl 文件都将具有扩展名,即 .tcl。因此,将以下源代码放入 test.tcl 文件中。

#!/usr/bin/tclsh

puts "Hello, World!" 

假设 Tcl 环境已正确设置;让我们切换到文件目录,然后使用以下命令执行程序:

$ tclsh test.tcl

我们将获得以下输出:

Hello, World!

现在让我们看看 Tcl 程序的基本结构,以便您更容易理解 Tcl 语言的基本构建块。在 Tcl 中,我们使用换行符或分号来终止上一行代码。但是,如果您为每个命令使用换行符,则分号不是必需的。

注释

注释就像 Tcl 程序中的帮助文本,解释器会忽略它们。可以使用开头处的哈希 (#) 符号编写注释。

#!/usr/bin/tclsh

# my first program in Tcl
puts "Hello World!" 

执行上述代码时,会产生以下结果:

Hello World!

多行或块注释使用带有条件 '0' 的 'if' 编写。下面显示了一个示例。

#!/usr/bin/tclsh

if 0 {
   my first program in Tcl program
   Its very simple
}
puts "Hello World!" 

执行上述代码时,会产生以下结果:

Hello World!

内联注释使用 ;#。下面给出了一个示例。

#!/usr/bin/tclsh

puts "Hello World!" ;# my first print in Tcl program

执行上述代码时,会产生以下结果:

Hello World!

标识符

Tcl 标识符是用于标识变量、函数或任何其他用户定义项目的名称。标识符以字母 A 到 Z 或 a 到 z 或下划线 (_) 开头,后跟零个或多个字母、下划线、美元符号 ($) 和数字 (0 到 9)。

Tcl 不允许在标识符中使用诸如 @、% 等标点符号。Tcl 是一种区分大小写的语言。因此,Manpowermanpower 在 Tcl 中是两个不同的标识符。以下是可接受的标识符的一些示例:

mohd       zara    abc   move_name  a_123
myname50   _temp   j     a23b9      retVal

Tcl 中的空格

仅包含空格(可能还有注释)的行被称为空行,Tcl 解释器会完全忽略它。

空格是 Tcl 中用来描述空格、制表符、换行符和注释的术语。空格将语句的一部分与另一部分分隔开来,并使解释器能够识别语句中一个元素(例如 puts)的结束位置和下一个元素的开始位置。因此,在以下语句中:

#!/usr/bin/tclsh

puts "Hello World!" 

“puts” 和 "Hello World!" 之间必须至少有一个空格字符(通常是空格),以便解释器能够区分它们。另一方面,在以下语句中:

#!/usr/bin/tclsh

puts [expr 3 + 2] ;# print sum of the 3 and 2

执行上述代码时,会产生以下结果:

5

3 和 + 之间,或者 + 和 2 之间不需要空格字符;尽管如此,为了可读性,您可以随意添加一些空格。

Tcl - 命令

如您所知,Tcl 是一种工具命令语言,命令是该语言最核心的部分。Tcl 命令内置于语言中,每个命令都有其自身预定义的功能。这些命令构成了语言的保留字,不能用于其他变量命名。使用这些 Tcl 命令的优势在于,您可以为任何这些命令定义自己的实现,以替换原始的内置功能。

每个 Tcl 命令都会验证输入,从而减少了解释器的负担。

Tcl 命令实际上是一个单词列表,第一个单词表示要执行的命令。接下来的单词表示参数。为了将单词组合成单个参数,我们将多个单词用 "" 或 {} 括起来。

Tcl 命令的语法如下:

commandName argument1 argument2 ... argumentN

让我们看一个简单的 Tcl 命令示例:

#!/usr/bin/tclsh

puts "Hello, world!"

执行上述代码时,会产生以下结果:

Hello, world!

在上面的代码中,‘puts’ 是 Tcl 命令,"Hello World" 是参数 1。如前所述,我们使用了 "" 来组合两个单词。

让我们再看一个包含两个参数的 Tcl 命令示例:

#!/usr/bin/tclsh

puts stdout "Hello, world!"

执行上述代码时,会产生以下结果:

Hello, world!

在上面的代码中,‘puts’ 是 Tcl 命令,‘stdout’ 是参数 1,"Hello World" 是参数 2。在这里,stdout 使程序能够在标准输出设备上打印。

命令替换

在命令替换中,使用方括号来评估方括号内的脚本。下面显示了一个简单的加两个数字的示例:

#!/usr/bin/tclsh

puts [expr 1 + 6 + 9]

执行上述代码后,将产生以下结果:

16

变量替换

在变量替换中,在变量名前使用 $,这将返回变量的内容。下面显示了一个将值赋给变量并打印它的简单示例。

#!/usr/bin/tclsh

set a 3
puts $a

执行上述代码时,会产生以下结果:

3

反斜杠替换

这些通常称为转义序列;每个反斜杠后跟一个字母,每个字母都有其自身的含义。下面显示了一个换行符替换的简单示例:

#!/usr/bin/tclsh

puts "Hello\nWorld"

执行上述代码时,会产生以下结果:

Hello
World

Tcl - 数据类型

Tcl 的基本数据类型是字符串,并且我们经常可以在 Tcl 中将字符串视为唯一的语言。这些基本数据类型依次创建列表和关联数组的复合数据类型。在 Tcl 中,数据类型不仅可以表示简单的 Tcl 对象,还可以表示复杂的对象,例如句柄、图形对象(主要是小部件)和 I/O 通道。让我们详细了解上述每个方面。

简单的 Tcl 对象

在 Tcl 中,无论是整数、布尔值、浮点数还是字符串。当您想要使用变量时,可以直接为其赋值,在 Tcl 中没有声明步骤。这些不同类型的对象可以有内部表示形式。它可以在需要时将一种数据类型转换为另一种数据类型。为变量赋值的语法如下:

#!/usr/bin/tclsh

set myVariable 18
puts $myVariable

执行上述代码时,会产生以下结果:

18

上述语句将创建一个名为 myVariable 的变量,并将其存储为字符串,即使我们没有使用双引号。现在,如果我们尝试对变量进行算术运算,它会自动转换为整数。下面显示了一个简单的示例:

#!/usr/bin/tclsh

set myVariable 18
puts [expr $myVariable + 6 + 9]

执行上述代码时,会产生以下结果:

33

需要注意的一点是,这些变量没有任何默认值,并且必须在使用之前为其赋值。

如果我们尝试使用 puts 打印,则该数字将转换为正确的字符串。拥有内部和外部两种表示形式,有助于 Tcl 比其他语言更容易地创建复杂的数据结构。此外,由于其动态对象特性,Tcl 更有效率。

字符串表示

与其他语言不同,在 Tcl 中,如果只有一个单词,则无需包含双引号。例如:

#!/usr/bin/tclsh

set myVariable hello
puts $myVariable

执行上述代码时,会产生以下结果:

hello

当我们想要表示多个字符串时,可以使用双引号或花括号。如下所示:

#!/usr/bin/tclsh

set myVariable "hello world"
puts $myVariable
set myVariable {hello world}
puts $myVariable

执行上述代码时,会产生以下结果:

hello world
hello world

列表

列表只不过是一组元素。可以使用双引号或花括号括起来的一组单词来表示一个简单的列表。下面显示了一个简单的列表:

#!/usr/bin/tclsh

set myVariable {red green blue}
puts [lindex $myVariable 2]
set myVariable "red green blue"
puts [lindex $myVariable 1]

执行上述代码时,会产生以下结果:

blue
green

关联数组

关联数组的索引(键)不一定是整数。它通常是一个充当键值对的字符串。下面显示了一个简单的示例:

#!/usr/bin/tclsh

set  marks(english) 80
puts $marks(english)
set  marks(mathematics) 90
puts $marks(mathematics)

执行上述代码时,会产生以下结果:

80
90

句柄

Tcl 句柄通常用于表示文件和图形对象。这些可以包括网络请求的句柄,以及其他通道,例如串行端口通信、套接字或 I/O 设备。以下是一个创建文件句柄的示例。

set myfile [open "filename" r]

您将在Tcl 文件 I/O章节中看到有关文件的更多详细信息。

Tcl - 变量

在 Tcl 中,没有变量声明的概念。一旦遇到新的变量名,Tcl 就会定义一个新的变量。

变量命名

变量名可以包含任何字符和长度。您甚至可以通过将变量用花括号括起来包含空格,但这并不推荐。

set 命令用于为变量赋值。set 命令的语法为:

set variableName value

下面显示了一些变量示例:

#!/usr/bin/tclsh

set variableA 10
set {variable B} test
puts $variableA
puts ${variable B}

执行上述代码时,会产生以下结果:

10
test

如您在上述程序中看到的,$variableName 用于获取变量的值。

动态类型

Tcl 是一种动态类型语言。变量的值可以在需要时动态转换为所需类型。例如,存储为字符串的数字 5 在进行算术运算时将转换为数字。如下所示:

#!/usr/bin/tclsh

set variableA "10"
puts $variableA
set sum [expr $variableA +20];
puts $sum

执行上述代码时,会产生以下结果:

10
30

数学表达式

如您在上述示例中看到的,expr 用于表示数学表达式。Tcl 的默认精度为 12 位数字。为了获得浮点数结果,我们应该至少添加一位小数。一个简单的示例解释了上述内容。

#!/usr/bin/tclsh

set variableA "10"
set result [expr $variableA / 9];
puts $result
set result [expr $variableA / 9.0];
puts $result
set variableA "10.0"
set result [expr $variableA / 9];
puts $result

执行上述代码时,会产生以下结果:

1
1.1111111111111112
1.1111111111111112

在上面的示例中,您可以看到三种情况。在第一种情况下,被除数和除数都是整数,我们得到一个整数作为结果。在第二种情况下,只有除数是小数,在第三种情况下,被除数是小数。在第二种和第三种情况下,我们都得到一个小数作为结果。

在上面的代码中,您可以使用 tcl_precision 特殊变量更改精度。如下所示:

#!/usr/bin/tclsh

set variableA "10"
set tcl_precision 5
set result [expr $variableA / 9.0];
puts $result

执行上述代码时,会产生以下结果:

1.1111

Tcl - 运算符

运算符是一个符号,它告诉编译器执行特定的数学或逻辑操作。Tcl 语言富含内置运算符,并提供以下类型的运算符:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 三元运算符
Types of Operators

本章将逐一解释算术、关系、逻辑、位和三元运算符。

算术运算符

下表显示了 Tcl 语言支持的所有算术运算符。假设变量‘A’保存 10,变量‘B’保存 20,则:

显示示例

运算符 描述 示例
+ 将两个操作数相加 A + B 将得到 30
- 从第一个操作数中减去第二个操作数 A - B 将得到 -10
* 将两个操作数相乘 A * B 将得到 200
/ 将分子除以分母 B / A 将得到 2
% 模运算符和整数除法后的余数 B % A 将得到 0

关系运算符

下表显示了 Tcl 语言支持的所有关系运算符。假设变量A保存 10,变量B保存 20,则:

显示示例

运算符 描述 示例
== 检查两个操作数的值是否相等,如果相等则条件为真。 (A == B) 为假。
!= 检查两个操作数的值是否不相等,如果不相等则条件为真。 (A != B) 为真。
> 检查左侧操作数的值是否大于右侧操作数的值,如果是则条件为真。 (A > B) 为假。
< 检查左侧操作数的值是否小于右侧操作数的值,如果是则条件为真。 (A < B) 为真。
>= 检查左侧操作数的值是否大于或等于右侧操作数的值,如果是则条件为真。 (A >= B) 为假。
<= 检查左侧操作数的值是否小于或等于右侧操作数的值,如果是则条件为真。 (A <= B) 为真。

逻辑运算符

下表显示了 Tcl 语言支持的所有逻辑运算符。假设变量A保存 1,变量B保存 0,则:

显示示例

运算符 描述 示例
&& 称为逻辑 AND 运算符。如果两个操作数均非零,则条件为真。 (A && B) 为假。
|| 称为逻辑 OR 运算符。如果两个操作数中的任何一个非零,则条件为真。 (A || B) 为真。
! 称为逻辑 NOT 运算符。用于反转其操作数的逻辑状态。如果条件为真,则逻辑 NOT 运算符将使其为假。 !(A && B) 为真。

位运算符

位运算符对位进行操作,并执行逐位运算。&、| 和 ^ 的真值表如下:

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

假设 A = 60;B = 13;现在以二进制格式,它们将如下所示:

A = 0011 1100

B = 0000 1101

----------------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

Tcl 语言支持的位运算符列在下表中。假设变量A保存 60,变量B保存 13,则:

显示示例

运算符 描述 示例
& 二进制 AND 运算符将位复制到结果中,如果它存在于两个操作数中。 (A & B) 将得到 12,即 0000 1100
| 二进制 OR 运算符将位复制到结果中,如果它存在于任何一个操作数中。 (A | B) 将得到 61,即 0011 1101
^ 二进制 XOR 运算符将位复制到结果中,如果它在一个操作数中设置,但在另一个操作数中未设置。 (A ^ B) 将得到 49,即 0011 0001
<< 二进制左移运算符。左侧操作数的值向左移动右侧操作数指定的位数。 A << 2 将得到 240,即 1111 0000
>> 二进制右移运算符。左侧操作数的值向右移动右侧操作数指定的位数。 A >> 2 将得到 15,即 0000 1111

三元运算符

显示示例

运算符 描述 示例
? : 三元运算符 如果条件为真?则值为 X:否则值为 Y

Tcl 中的运算符优先级

运算符优先级决定了表达式中项的组合方式。这会影响表达式的计算方式。某些运算符的优先级高于其他运算符;例如,乘法运算符的优先级高于加法运算符。

例如:x = 7 + 3 * 2;这里,x 被赋值为 13,而不是 20,因为运算符 * 的优先级高于 +,所以它首先与 3 * 2 相乘,然后加到 7 中。

这里,优先级最高的运算符出现在表格的顶部,优先级最低的出现在底部。在一个表达式中,优先级较高的运算符将首先被计算。

显示示例

类别 运算符 结合性
一元运算符 + - 从右到左
乘法运算符 * / % 从左到右
加法运算符 + - 从左到右
移位运算符 << >> 从左到右
关系运算符 < <= > >= 从左到右
按位与运算符 & 从左到右
按位异或运算符 ^ 从左到右
按位或运算符 | 从左到右
逻辑与运算符 && 从左到右
逻辑或运算符 || 从左到右
三元运算符 ?: 从右到左

Tcl - 决策

决策结构要求程序员指定一个或多个条件,由程序进行评估或测试,以及在确定条件为真时要执行的语句或语句,以及可选地,在确定条件为假时要执行的其他语句。

以下是大多数编程语言中常见的决策结构的一般形式:

Decision Making

Tcl 语言在内部使用 expr 命令,因此我们不需要显式地使用 expr 语句。

Tcl 语言提供了以下类型的决策语句:

序号 语句 & 描述
1 if 语句

一个 'if' 语句由一个布尔表达式后跟一个或多个语句组成。

2 if...else 语句

一个 'if' 语句后面可以跟一个可选的 'else' 语句,当布尔表达式为假时执行。

3 嵌套 if 语句

您可以在另一个 'if' 或 'else if' 语句中使用一个 'if' 或 'else if' 语句。

4 switch 语句

一个 switch 语句允许将一个变量与一个值的列表进行相等性测试。

5 嵌套 switch 语句

您可以在另一个 switch 语句中使用一个 switch 语句。

? : 运算符

我们在上一章中介绍了 条件运算符 ? :,它可以用来替换 if...else 语句。它具有以下一般形式:

Exp1 ? Exp2 : Exp3;

其中 Exp1、Exp2 和 Exp3 是表达式。注意冒号的使用和位置。

“?表达式”的值如下确定:Exp1 被计算。如果为真,则计算 Exp2 并将其作为整个“?表达式”的值。如果 Exp1 为假,则计算 Exp3 并将其值作为表达式的值。下面显示了一个示例。

#!/usr/bin/tclsh

set a 10;
set b [expr $a == 1 ? 20: 30]
puts "Value of b is $b\n"
set b [expr $a == 10 ? 20: 30]
puts "Value of b is $b\n" 

当您编译并执行上述程序时,它会产生以下结果:

Value of b is 30
Value of b is 20

Tcl - 循环

可能存在这样一种情况,您需要多次执行一段代码。通常,语句按顺序执行:函数中的第一个语句首先执行,然后是第二个语句,依此类推。

编程语言提供了各种控制结构,允许更复杂的执行路径。

循环语句允许我们多次执行一个语句或一组语句,以下是大多数编程语言中循环语句的一般形式:

Loop Architecture

Tcl 语言提供了以下类型的循环来处理循环需求。

序号 循环类型 & 描述
1 while 循环

在给定条件为真的情况下重复一个语句或一组语句。它在执行循环体之前测试条件。

2 for 循环

多次执行一系列语句,并缩写管理循环变量的代码。

3 嵌套循环

您可以在任何其他 while、for 或 do..while 循环中使用一个或多个循环。

循环控制语句

循环控制语句更改执行的正常顺序。当执行离开作用域时,在该作用域中创建的所有自动对象都会被销毁。

Tcl 支持以下控制语句。

序号 控制语句 & 描述
1 break 语句

终止循环或 switch 语句,并将执行转移到循环或 switch 后面的语句。

2 continue 语句

导致循环跳过其主体剩余部分,并在重复之前立即重新测试其条件。

无限循环

如果条件永远不变成假,则循环变成无限循环。while 循环传统上用于此目的。您可以通过将条件表达式保留为 1 来创建一个无限循环。

while {1} {
   puts "This loop will run forever."
}

当条件表达式不存在时,它被假定为真。Tcl 程序员更常使用 while {1} 结构来表示无限循环。

注意 - 您可以通过按 Ctrl + C 键来终止无限循环。

Tcl - 数组

数组是使用索引对一组元素进行系统排列。传统数组的语法如下所示。

set ArrayName(Index) value

创建简单数组的示例如下所示。

#!/usr/bin/tclsh

set languages(0) Tcl
set languages(1) "C Language"
puts $languages(0)
puts $languages(1)

执行上述代码时,会产生以下结果:

Tcl
C Language

数组的大小

计算数组大小的语法如下所示。

[array size variablename]

打印大小的示例如下所示。

#!/usr/bin/tclsh

set languages(0) Tcl
set languages(1) "C Language"
puts  [array size languages]

执行上述代码时,会产生以下结果:

2

数组迭代

尽管数组索引可以是非连续的,例如为索引 1 指定的值,然后是索引 10,依此类推。但是,如果它们是连续的,我们可以使用数组迭代来访问数组的元素。下面显示了一个用于打印数组元素的简单数组迭代。

#!/usr/bin/tclsh

set languages(0) Tcl
set languages(1) "C Language"
for { set index 0 }  { $index < [array size languages] }  { incr index } {
   puts "languages($index) : $languages($index)"
}

执行上述代码时,会产生以下结果:

languages(0) : Tcl
languages(1) : C Language

关联数组

在 Tcl 中,所有数组本质上都是关联数组。数组的存储和检索没有特定的顺序。关联数组的索引不一定是数字,并且可以是稀疏填充的。下面显示了一个带有非数字索引的关联数组的简单示例。

#!/usr/bin/tclsh

set personA(Name) "Dave"
set personA(Age) 14
puts  $personA(Name)
puts  $personA(Age)

执行上述代码时,会产生以下结果:

Dave
14

数组的索引

检索数组索引的语法如下所示。

[array names variablename]

打印大小的示例如下所示。

#!/usr/bin/tclsh

set personA(Name) "Dave"
set personA(Age) 14
puts [array names personA]

执行上述代码时,会产生以下结果:

Age Name

关联数组的迭代

您可以使用数组的索引遍历关联数组。下面显示了一个示例。

#!/usr/bin/tclsh

set personA(Name) "Dave"
set personA(Age) 14
foreach index [array names personA] {
   puts "personA($index): $personA($index)"
}

执行上述代码时,会产生以下结果:

personA(Age): 14
personA(Name): Dave

Tcl - 字符串

Tcl 的基本数据类型是字符串,我们经常可以在 Tcl 中发现引号作为字符串语言。这些字符串可以包含字母数字字符、仅数字、布尔值或甚至二进制数据。Tcl 使用 16 位 Unicode 字符,字母数字字符可以包含字母(包括非拉丁字符)、数字或标点符号。

布尔值可以表示为 1、yes 或 true 表示真,0、no 或 false 表示假。

字符串表示

与其他语言不同,在 Tcl 中,如果只有一个单词,则无需包含双引号。例如:

#!/usr/bin/tclsh

set myVariable hello
puts $myVariable

执行上述代码时,会产生以下结果:

hello

当我们想要表示多个字符串时,可以使用双引号或花括号。如下所示:

#!/usr/bin/tclsh

set myVariable "hello world"
puts $myVariable
set myVariable {hello world}
puts $myVariable

执行上述代码时,会产生以下结果:

hello world
hello world

字符串转义序列

字符字面量可以是普通字符(例如,'x')、转义序列(例如,'\t')或通用字符(例如,'\u02C0')。

Tcl 中某些字符在前面加上反斜杠时具有特殊含义,它们用于表示换行符(\n)或制表符(\t)。这里,您有一个此类转义序列代码的列表:

转义序列 含义
\\ \ 字符
\' ' 字符
\" " 字符
\? ? 字符
\a 警报或铃声
\b 退格键
\f 换页符
\n 换行符
\r 回车符
\t 水平制表符
\v 垂直制表符

以下是显示一些转义序列字符的示例:

#!/usr/bin/tclsh

puts "Hello\tWorld\n\nTutorialspoint";

当上述代码被编译并执行时,它会产生以下结果:

Hello   World

Tutorialspoint

String 命令

String 命令的子命令列表在以下表格中列出:

序号 方法 & 描述
1

compare string1 string2

按字典顺序比较 string1 和 string2。如果相等则返回 0,如果 string1 在 string2 之前则返回 -1,否则返回 1。

2

first string1 string2

返回 string1 在 string2 中第一次出现的索引。如果未找到,则返回 -1。

3

index string index

返回索引处的字符。

4

last string1 string2

返回 string1 在 string2 中最后一次出现的索引。如果未找到,则返回 -1。

5

length string

返回字符串的长度。

6

match pattern string

如果字符串与模式匹配,则返回 1。

7

range string index1 index2

返回字符串中从 index1 到 index2 的字符范围。

8

tolower string

返回小写字符串。

9

toupper string

返回大写字符串。

10

trim string ?trimcharacters?

删除字符串两端的 trimcharacters。默认的 trimcharacters 是空格。

11

trimleft string ?trimcharacters?

删除字符串开头左侧的 trimcharacters。默认的 trimcharacters 是空格。

12

trimright string ?trimcharacters?

删除字符串末尾右侧的 trimcharacters。默认的 trimcharacters 是空格。

13

wordend findstring index

返回 findstring 中包含索引处字符的单词之后字符的索引。

14

wordstart findstring index

返回 findstring 中包含索引处字符的单词的第一个字符的索引。

下面给出了一些常用 Tcl 字符串子命令的示例。

字符串比较

#!/usr/bin/tclsh

set s1 "Hello"
set s2 "World"
set s3 "World"
puts [string compare $s1 $s2]
if {[string compare $s2 $s3] == 0} {
   puts "String \'s1\' and \'s2\' are same.";
}

if {[string compare $s1 $s2] == -1} {
   puts "String \'s1\' comes before \'s2\'.";
}

if {[string compare $s2 $s1] == 1} {
   puts "String \'s2\' comes after \'s1\'.";
}

当上述代码被编译并执行时,它会产生以下结果:

-1
String 's1' and 's2' are same.
String 's1' comes before 's2'.
String 's2' comes after 's1'.

字符串的索引

#!/usr/bin/tclsh

set s1 "Hello World"
set s2 "o"
puts "First occurrence of $s2 in s1"
puts [string first $s2 $s1]
puts "Character at index 0 in s1"
puts [string index $s1 0]
puts "Last occurrence of $s2 in s1"
puts [string last $s2 $s1]
puts "Word end index in s1"
puts [string wordend $s1 20]
puts "Word start index in s1"
puts [string wordstart $s1 20]

当上述代码被编译并执行时,它会产生以下结果:

First occurrence of o in s1
4
Character at index 0 in s1
H
Last occurrence of o in s1
7
Word end index in s1
11
Word start index in s1
6

字符串的长度

#!/usr/bin/tclsh

set s1 "Hello World"
puts "Length of string s1"
puts [string length $s1]

当上述代码被编译并执行时,它会产生以下结果:

Length of string s1
11

处理大小写

#!/usr/bin/tclsh

set s1 "Hello World"
puts "Uppercase string of s1"
puts [string toupper $s1]
puts "Lowercase string of s1"
puts [string tolower $s1]

当上述代码被编译并执行时,它会产生以下结果:

Uppercase string of s1
HELLO WORLD
Lowercase string of s1
hello world

修剪字符

#!/usr/bin/tclsh

set s1 "Hello World"
set s2 "World"
puts "Trim right $s2 in $s1"
puts [string trimright $s1 $s2]

set s2 "Hello"
puts "Trim left $s2 in $s1"
puts [string trimleft $s1 $s2]

set s1 " Hello World "
set s2 " "
puts "Trim characters s1 on both sides of s2"
puts [string trim $s1 $s2]

当上述代码被编译并执行时,它会产生以下结果:

Trim right World in Hello World
Hello 
Trim left Hello in Hello World
 World
Trim characters s1 on both sides of s2
Hello World

匹配字符串

#!/usr/bin/tclsh

set s1 "[email protected]" 
set s2 "*@*.com"
puts "Matching pattern s2 in s1"
puts [string match "*@*.com" $s1 ]
puts "Matching pattern tcl in s1"
puts [string match {tcl} $s1]

当上述代码被编译并执行时,它会产生以下结果:

Matching pattern s2 in s1
1
Matching pattern tcl in s1
0

Append 命令

#!/usr/bin/tclsh

set s1 "Hello" 
append s1 " World"
puts $s1

当上述代码被编译并执行时,它会产生以下结果:

Hello World

Format 命令

下表显示了 Tcl 中可用的格式说明符列表:

说明符 用途
%s 字符串表示形式
%d 整数表示形式
%f 浮点数表示形式
%e 带尾数-指数形式的浮点数表示形式
%x 十六进制表示形式

下面给出了一些简单的示例:

#!/usr/bin/tclsh

puts [format "%f" 43.5]
puts [format "%e" 43.5]
puts [format "%d %s" 4 tuts]
puts [format "%s" "Tcl Language"]
puts [format "%x" 40]

当上述代码被编译并执行时,它会产生以下结果:

43.500000
4.350000e+01
4 tuts
Tcl Language
28

Scan 命令

Scan 命令用于根据格式说明符解析字符串。下面给出了一些示例。

#!/usr/bin/tclsh

puts [scan "90" {%[0-9]} m]
puts [scan "abc" {%[a-z]} m]
puts [scan "abc" {%[A-Z]} m]
puts [scan "ABC" {%[A-Z]} m]

当上述代码被编译并执行时,它会产生以下结果:

1
1
0
1

Tcl - 列表

列表是 Tcl 中可用的基本数据类型之一。它用于表示项目的排序集合。它可以在同一列表中包含不同类型的项目。此外,列表可以包含另一个列表。

需要注意的一件重要事情是,这些列表完全以字符串形式表示,并在需要时处理以形成各个项目。因此,避免使用大型列表,在这种情况下;使用数组。

创建列表

列表的一般语法如下所示:

set listName { item1 item2 item3 .. itemn }
# or
set listName [list item1 item2 item3]
# or 
set listName [split "items separated by a character" split_character]

下面给出了一些示例:

#!/usr/bin/tclsh

set colorList1 {red green blue}
set colorList2 [list red green blue]
set colorList3 [split "red_green_blue" _]
puts $colorList1
puts $colorList2
puts $colorList3

执行上述代码时,会产生以下结果:

red green blue
red green blue
red green blue

将项目追加到列表中

将项目追加到列表中的语法如下所示:

append listName split_character value
# or
lappend listName value

下面给出了一些示例:

#!/usr/bin/tclsh

set var orange
append var " " "blue"
lappend var "red" 
lappend var "green" 
puts $var

执行上述代码时,会产生以下结果:

orange blue red green

列表的长度

列表长度的语法如下所示:

llength listName

列表长度的示例如下所示:

#!/usr/bin/tclsh

set var {orange blue red green}
puts [llength $var] 

执行上述代码时,会产生以下结果:

4

索引处的列表项

选择特定索引处的列表项的语法如下所示:

lindex listname index

索引处列表项的示例如下所示:

#!/usr/bin/tclsh

set var {orange blue red green}
puts [lindex $var  1]

执行上述代码时,会产生以下结果:

blue

在索引处插入项目

在特定索引处插入列表项的语法如下所示。

linsert listname index value1 value2..valuen

在特定索引处插入列表项的示例如下所示。

#!/usr/bin/tclsh

set var {orange blue red green}
set var [linsert  $var 3 black white]
puts $var

执行上述代码时,会产生以下结果:

orange blue red black white green

替换索引处的项目

替换特定索引处的列表项的语法如下所示:

lreplace listname firstindex lastindex value1 value2..valuen

替换特定索引处的列表项的示例如下所示。

#!/usr/bin/tclsh

set var {orange blue red green}
set var [lreplace $var 2 3 black white]
puts $var

执行上述代码时,会产生以下结果:

orange blue black white

设置索引处的项目

下面给出设置指定索引处列表项的语法:

lset listname index value 

下面给出设置指定索引处列表项的示例:

#!/usr/bin/tclsh

set var {orange blue red green}
lset var 0 black 
puts $var

执行上述代码时,会产生以下结果:

black blue red green

将列表转换为变量

下面给出将值复制到变量的语法:

lassign listname variable1 variable2.. variablen

下面给出将列表转换为变量的示例:

#!/usr/bin/tclsh

set var {orange blue red green}
lassign $var colour1 colour2
puts $colour1
puts $colour2

执行上述代码时,会产生以下结果:

orange
blue

排序列表

下面给出排序列表的语法:

lsort listname

下面给出排序列表的示例:

#!/usr/bin/tclsh

set var {orange blue red green}
set var [lsort $var]
puts $var

执行上述代码时,会产生以下结果:

blue green orange red

Tcl - 字典

字典是用于将值映射到键的结构。下面显示了常规字典的语法:

dict set dictname key value
# or 
dict create dictname key1 value1 key2 value2 .. keyn valuen

下面显示了一些创建字典的示例:

#!/usr/bin/tclsh

dict set colours  colour1 red 
puts $colours
dict set colours  colour2 green
puts $colours

set colours [dict create colour1 "black" colour2 "white"]
puts $colours

执行上述代码时,会产生以下结果:

colour1 red
colour1 red colour2 green
colour1 black colour2 white

字典的大小

下面给出获取字典大小的语法:

[dict size dictname]

下面给出打印大小的示例:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
puts [dict size $colours]

执行上述代码时,会产生以下结果:

2

字典迭代

下面显示了一个简单的字典迭代,用于打印字典的键和值:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
foreach item [dict keys $colours] {
   set value [dict get $colours $item]
   puts $value
}

执行上述代码时,会产生以下结果:

black
white

字典中键的值

下面给出在字典中检索键的值的语法:

[dict get $dictname $keyname]

下面给出检索键值的示例:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set value [dict get $colours colour1]
puts $value

执行上述代码时,会产生以下结果:

black

字典中的所有键

下面给出检索字典中所有键的语法:

[dict keys $dictname]

下面给出打印所有键的示例:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set keys [dict keys $colours]
puts $keys

执行上述代码时,会产生以下结果:

colour1 colour2

字典中的所有值

下面给出检索字典中所有值的语法:

[dict values $dictname]

下面给出打印所有值的示例:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set values [dict values $colours]
puts $values

执行上述代码时,会产生以下结果:

black white

键是否存在于字典中

下面给出检查键是否存在于字典中的语法:

[dict exists $dictname $key]

下面给出检查键是否存在于字典中的示例:

#!/usr/bin/tclsh

set colours [dict create colour1 "black" colour2 "white"]
set result [dict exists $colours colour1]
puts $result

执行上述代码时,会产生以下结果:

1

Tcl - 过程

过程只不过是一系列命令的代码块,提供特定的可重用功能。它用于避免在多个位置重复相同的代码。过程等效于许多编程语言中使用的函数,并且在 Tcl 中借助 **proc** 命令提供。

下面显示了创建简单过程的语法:

proc procedureName {arguments} {
   body
}

下面给出了过程的一个简单示例:

#!/usr/bin/tclsh

proc helloWorld {} {
   puts "Hello, World!"
}
helloWorld

执行上述代码时,会产生以下结果:

Hello, World!

带多个参数的过程

下面显示了带参数过程的示例:

#!/usr/bin/tclsh

proc add {a b} {
   return [expr $a+$b]
}
puts [add 10 30]

执行上述代码时,会产生以下结果:

40

带可变参数的过程

下面显示了带参数过程的示例:

#!/usr/bin/tclsh

proc avg {numbers} {
   set sum 0
   foreach number $numbers {
      set sum  [expr $sum + $number]
   }
   set average [expr $sum/[llength $numbers]]
   return $average
}
puts [avg {70 80 50 60}]
puts [avg {70 80 50 }]

执行上述代码时,会产生以下结果:

65
66

带默认参数的过程

默认参数用于提供默认值,如果未提供值,则可以使用这些默认值。下面显示了一个带默认参数的过程示例,有时也称为隐式参数:

#!/usr/bin/tclsh

proc add {a {b 100} } {
   return [expr $a+$b]
}
puts [add 10 30]
puts [add 10]

执行上述代码时,会产生以下结果:

40
110

递归过程

下面给出了递归过程的示例:

#!/usr/bin/tclsh

proc factorial {number} {
   if {$number <= 1} {
      return 1
   } 
   return [expr $number * [factorial [expr $number - 1]]]

}
puts [factorial 3]
puts [factorial 5]

执行上述代码时,会产生以下结果:

6
120

Tcl - 包

包用于创建可重用的代码单元。一个包包含一系列提供特定功能的文件。此文件集合由包名称标识,并且可以具有相同文件的多个版本。该包可以是 Tcl 脚本、二进制库或两者的组合。

包使用命名空间的概念来避免变量名和过程名的冲突。在我们的下一个“命名空间”教程中查看更多信息。

创建包

可以使用至少两个文件创建包。一个文件包含包代码。另一个文件包含用于声明包的索引包文件。

下面给出创建和使用包的步骤列表。

步骤 1:创建代码

在文件夹(例如 HelloWorld)中创建包的代码。让文件名为 HelloWorld.tcl,代码如下所示:

# /Users/rajkumar/Desktop/helloworld/HelloWorld.tcl 
# Create the namespace
namespace eval ::HelloWorld {
 
  # Export MyProcedure
  namespace export MyProcedure
 
  # My Variables
   set version 1.0
   set MyDescription "HelloWorld"
 
  # Variable for the path of the script
   variable home [file join [pwd] [file dirname [info script]]]
 
}
 
# Definition of the procedure MyProcedure
proc ::HelloWorld::MyProcedure {} {
   puts $HelloWorld::MyDescription
}

package provide HelloWorld $HelloWorld::version
package require Tcl 8.0

步骤 2:创建包索引

打开 tclsh。切换到 HelloWorld 目录,并使用 pkg_mkIndex 命令创建索引文件,如下所示:

% cd /Users/rajkumar/Desktop/helloworld 
% pkg_mkIndex . *.tcl

步骤 3:将目录添加到 autopath

使用 lappend 命令将包添加到全局列表中,如下所示:

% lappend auto_path "/Users/rajkumar/Desktop/helloworld"

步骤 4:添加包

接下来,使用 package require 语句将包添加到程序中,如下所示:

% package require HelloWorld 1.0

步骤 5:调用过程

现在,一切设置就绪,我们可以调用我们的过程,如下所示:

% puts [HelloWorld::MyProcedure]

您将获得以下结果:

HelloWorld

前两个步骤创建了包。创建包后,您可以通过添加最后三个语句(如下所示)在任何 Tcl 文件中使用它:

lappend auto_path "/Users/rajkumar/Desktop/helloworld"
package require HelloWorld 1.0
puts [HelloWorld::MyProcedure]

您将获得以下结果:

HelloWorld

Tcl - 命名空间

命名空间是标识符集的容器,用于对变量和过程进行分组。命名空间从 Tcl 版本 8.0 开始可用。在引入命名空间之前,只有一个全局作用域。现在有了命名空间,我们有了全局作用域的其他分区。

创建命名空间

命名空间是使用 **namespace** 命令创建的。下面显示了一个创建命名空间的简单示例:

#!/usr/bin/tclsh

namespace eval MyMath {
  # Create a variable inside the namespace
  variable myResult
}

# Create procedures inside the namespace
proc MyMath::Add {a b } {  
  set ::MyMath::myResult [expr $a + $b]
}
MyMath::Add 10 23

puts $::MyMath::myResult

执行上述代码时,会产生以下结果:

33

在上面的程序中,您可以看到有一个命名空间,其中包含一个变量 **myResult** 和一个过程 **Add**。这使得可以在不同的命名空间下创建同名的变量和过程成为可能。

嵌套命名空间

Tcl 允许嵌套命名空间。下面给出了嵌套命名空间的一个简单示例:

#!/usr/bin/tclsh

namespace eval MyMath {
   # Create a variable inside the namespace
   variable myResult
}

namespace eval extendedMath {
   # Create a variable inside the namespace
   namespace eval MyMath {
      # Create a variable inside the namespace
      variable myResult
   }
}
set ::MyMath::myResult "test1"
puts $::MyMath::myResult
set ::extendedMath::MyMath::myResult "test2"
puts $::extendedMath::MyMath::myResult

执行上述代码时,会产生以下结果:

test1
test2

导入和导出命名空间

您可以在前面的命名空间示例中看到,我们使用了大量的范围解析运算符,使用起来比较复杂。我们可以通过导入和导出命名空间来避免这种情况。下面给出了一个示例:

#!/usr/bin/tclsh

namespace eval MyMath {
   # Create a variable inside the namespace
   variable myResult
   namespace export Add
}

# Create procedures inside the namespace
proc MyMath::Add {a b } {  
   return [expr $a + $b]
}

namespace import MyMath::*
puts [Add 10 30]

执行上述代码时,会产生以下结果:

40

忘记命名空间

您可以使用 **forget** 子命令删除导入的命名空间。下面给出了一个简单的示例:

#!/usr/bin/tclsh

namespace eval MyMath {
   # Create a variable inside the namespace
   variable myResult
   namespace export Add
}

# Create procedures inside the namespace
proc MyMath::Add {a b } {  
   return [expr $a + $b]
}
namespace import MyMath::*
puts [Add 10 30]
namespace forget MyMath::*

执行上述代码时,会产生以下结果:

40

Tcl - 文件 I/O

Tcl 在内置命令 open、read、puts、gets 和 close 的帮助下支持文件处理。

文件表示一系列字节,无论它是文本文件还是二进制文件。

打开文件

Tcl 使用 open 命令在 Tcl 中打开文件。打开文件的语法如下:

open fileName accessMode

这里,**filename** 是字符串文字,您将使用它来命名您的文件,而 **accessMode** 可以具有以下值之一:

序号 模式和描述
1

r

以读取目的打开现有的文本文件,并且文件必须存在。这是未指定 accessMode 时使用的默认模式。

2

w

打开文本文件以写入,如果它不存在,则创建一个新文件,否则截断现有文件。

3

a

以追加模式打开文本文件以写入,并且文件必须存在。在这里,您的程序将开始将内容追加到现有文件内容中。

4

r+

打开文本文件以进行读取和写入。文件必须已经存在。

5

w+

打开文本文件以进行读取和写入。如果文件存在,则首先将其截断为零长度,否则如果文件不存在,则创建文件。

6

a+

打开文本文件以进行读取和写入。如果文件不存在,则创建文件。读取将从开头开始,但只能追加写入。

关闭文件

要关闭文件,请使用 close 命令。close 的语法如下:

close fileName 

程序打开的任何文件都必须在程序完成使用该文件时关闭。在大多数情况下,无需显式关闭文件;当文件对象自动终止时,它们会自动关闭。

写入文件

Puts 命令用于写入打开的文件。

puts $filename "text to write"

下面显示了一个写入文件的简单示例。

#!/usr/bin/tclsh

set fp [open "input.txt" w+]
puts $fp "test"
close $fp

当编译并执行上述代码时,它会在其启动的目录(在程序的工作目录中)中创建一个名为 **input.txt** 的新文件。

读取文件

以下是从文件读取的简单命令:

set file_data [read $fp]

下面显示了一个完整的读写示例:

#!/usr/bin/tclsh

set fp [open "input.txt" w+]
puts $fp "test"
close $fp
set fp [open "input.txt" r]
set file_data [read $fp]
puts $file_data
close $fp

当编译并执行上述代码时,它会读取上一节中创建的文件并产生以下结果:

test

以下是另一个逐行读取文件直至文件结尾的示例:

#!/usr/bin/tclsh

set fp [open "input.txt" w+]
puts $fp "test\ntest"
close $fp
set fp [open "input.txt" r]

while { [gets $fp data] >= 0 } {
   puts $data
}
close $fp

当编译并执行上述代码时,它会读取上一节中创建的文件并产生以下结果:

test
test

Tcl - 错误处理

Tcl 中的错误处理在 **error** 和 **catch** 命令的帮助下提供。下面显示了每个命令的语法。

错误语法

error message info code

在上面的错误命令语法中,message 是错误消息,info 设置在全局变量 errorInfo 中,code 设置在全局变量 errorCode 中。

Catch 语法

catch script resultVarName

在上面的 catch 命令语法中,script 是要执行的代码,resultVarName 是保存错误或结果的变量。如果没有任何错误,则 catch 命令返回 0,如果有错误,则返回 1。

下面给出了一个简单的错误处理示例:

#!/usr/bin/tclsh

proc Div {a b} {
   if {$b == 0} {
      error "Error generated by error" "Info String for error" 401
   } else {
      return [expr $a/$b]
   }
}

if {[catch {puts "Result = [Div 10 0]"} errmsg]} {
   puts "ErrorMsg: $errmsg"
   puts "ErrorCode: $errorCode"
   puts "ErrorInfo:\n$errorInfo\n"
}

if {[catch {puts "Result = [Div 10 2]"} errmsg]} {
   puts "ErrorMsg: $errmsg"
   puts "ErrorCode: $errorCode"
   puts "ErrorInfo:\n$errorInfo\n"
}

执行上述代码时,会产生以下结果:

ErrorMsg: Error generated by error
ErrorCode: 401
ErrorInfo:
Info String for error
   (procedure "Div" line 1)
   invoked from within
"Div 10 0"

Result = 5

如您在上面的示例中看到的,我们可以创建自己的自定义错误消息。类似地,可以捕获 Tcl 生成的错误。下面给出了一个示例:

#!/usr/bin/tclsh

catch {set file [open myNonexistingfile.txt]} result
puts "ErrorMsg: $result"
puts "ErrorCode: $errorCode"
puts "ErrorInfo:\n$errorInfo\n"

执行上述代码时,会产生以下结果:

ErrorMsg: couldn't open "myNonexistingfile.txt": no such file or directory
ErrorCode: POSIX ENOENT {no such file or directory}
ErrorInfo:
couldn't open "myNonexistingfile.txt": no such file or directory
   while executing
"open myNonexistingfile.txt"

Tcl - 内置函数

Tcl 提供了许多用于各种操作的内置函数(过程)。这包括:

  • 用于 列表 处理的函数。

  • 用于 字符串 处理的函数。

  • 用于 数组 处理的函数。

  • 用于 字典 处理的函数。

  • 用于 文件 I/O 处理的函数。

  • 用于创建 命名空间包。 的函数。

  • 用于数学运算的函数。

  • 用于系统操作的函数。

除了数学和系统函数之外,上述每个函数都在前面的章节中进行了介绍。数学和系统内置函数将在下面解释。

数学函数

Tcl 中可用的数学函数列在下表中:

序号 方法和描述
1

abs arg

计算 arg 的绝对值。

2

acos arg

计算 arg 的反余弦。

3

asin arg

计算 arg 的反正弦。

4

atan arg

计算 arg 的反正切。

5

atan2 y x

计算其参数 (y/x) 的商的反正切。

6

ceil arg

计算大于或等于数字的最小整数。

7

cos arg

计算 arg 的余弦。

8

cosh arg

计算 arg 的双曲余弦。

9

double arg

计算 arg 是否为浮点值,返回 arg,否则将 arg 转换为浮点并返回转换后的值。

10

exp arg

计算指数函数(e 的 arg 次幂)。

11

floor arg

计算小于或等于 arg 的最大整数。

12

fmod x y

计算 x 除以 y 的浮点余数。如果 y 为 0,则返回错误。

13

hypot x y

计算直角三角形斜边的长度 sqrt(x*x+y*y)。

14

int arg

计算 arg 是否为与机器字宽度相同的整数值,返回 arg,否则将 arg 转换为整数。

15

log arg

计算 arg 的自然对数。

16

log10 arg

计算 arg 的以 10 为底的对数。

17

pow x y

计算 x 的 y 次幂的值。如果 x 为负数,则 y 必须为整数值。

18

rand

计算 0 到 1 之间的伪随机数。

19

round arg

计算 arg 四舍五入到最接近整数的值。

20

sin arg

计算 arg 的正弦。

21

sinh arg

计算 arg 的双曲正弦。

22

sqrt arg

计算 arg 的平方根。arg 必须为正数。

23

srand arg

计算 0 到 1 之间的伪随机数。arg(必须为整数)用于重置 rand 的随机数生成器的种子。

24

tan arg

计算 arg 的正切。

25

tanh arg

计算 arg 的双曲正切。

26

wide arg

如果参数不是 64 位整数,则计算至少 64 位宽的整数(如果参数是 32 位数字,则通过符号扩展)。

下面给出了一些使用数学函数的示例:

#!/usr/bin/tclsh

namespace import ::tcl::mathfunc::*
puts [tan 10]
puts [pow 10 2]
puts [ceil 10.34]
puts [hypot 10 20]
puts [srand 45]
puts [log 10]
puts [srand 45]

执行上述代码时,会产生以下结果:

0.6483608274590866
100.0
11.0
22.360679774997898
0.0003521866166741525
2.302585092994046
0.0003521866166741525

系统函数

Tcl 中重要的系统函数包括:

  • clock - 秒函数,返回以秒为单位的当前时间。

  • clock - 格式函数,将秒格式化为日期和时间。

  • clock - 扫描函数,扫描输入字符串并将其转换为秒。

  • open - 函数,用于打开文件。

  • exec - 函数,用于执行系统命令。

  • close - 函数,用于关闭文件。

上面这些函数的一些示例如下所示:

#!/usr/bin/tclsh

#get seconds
set currentTime [clock seconds]
puts $currentTime
#get format 
puts "The time is: [clock format $currentTime -format %H:%M:%S]"
puts "The date is: [clock format $currentTime -format %D]"

set date "Jun 15, 2014"
puts [clock scan $date -format {%b %d, %Y}]

puts [exec ls]
puts [exec dir]

set a  [open input.txt]
puts [read $a];
puts $a
close $a

执行上述代码时,会产生以下结果:

1402819756
The time is: 03:09:16
The date is: 06/15/2014
1402808400
input.txt
main.tcl
input.txt  main.tcl
This is the file you can use to provide input to your program and later on open
   it inside your program to process the input.

file3

下表提供了可用于格式化日期和时间的字符串列表。

序号 格式和描述
1

%a

简写形式的日期,例如:Sun。

2

%A

完整形式的日期,例如:Sunday。

3

%b

简写形式的月份。

4

%B

完整形式的月份。

5

%d

月份中的日期。

6

%j

一年中的儒略日。

7

%m

月份的数字表示。

8

%y

两位数的年份。

9

%Y

四位数的年份。

10

%H

24 小时制的小时。

11

%I

12 小时制的小时。

12

%M

分钟。

13

%S

秒。

14

%p

AM 或 PM。

15

%D

数字表示的日期,mm/dd/yy。

16

%r

12 小时制的时间。

17

%R

24 小时制的时间,不含秒。

18

%T

24 小时制的时间,含秒。

19

%Z

时区名称,例如 GMT、IST、EST 等。

Tcl - 正则表达式

"regexp" 命令用于匹配 Tcl 中的正则表达式。正则表达式是一系列包含搜索模式的字符。它包含多个规则,下表解释了这些规则及其对应的用法。

序号 规则和描述
1

x

精确匹配。

2

[a-z]

a 到 z 之间的任何小写字母。

3

.

任何字符。

4

^

字符串开头应该匹配。

5

$

字符串结尾应该匹配。

6

\^

反斜杠序列,用于匹配特殊字符 ^。类似地,您可以将其用于其他字符。

7

()

将上述序列添加到括号内以构成正则表达式。

8

x*

应该匹配前面 x 的 0 次或多次出现。

9

x+

应该匹配前面 x 的 1 次或多次出现。

10

[a-z]?

应该匹配前面 x 的 0 次或 1 次出现。

11

{digit}

匹配前面正则表达式出现的 digit 次。digit 包含 0-9。

12

{digit,}

匹配前面正则表达式出现的 3 次或更多 digit 次。digit 包含 0-9。

13

{digit1,digit2}

匹配前面正则表达式出现的 digit1 到 digit2 次之间的次数。

语法

正则表达式的语法如下所示:

regexp optionalSwitches patterns searchString fullMatch subMatch1 ... subMatchn

这里,regex 是命令。我们稍后将了解可选开关。Patterns 是前面提到的规则。Search string 是执行正则表达式的实际字符串。Full match 是任何用于保存匹配的正则表达式结果的变量。Submatch1 到 SubMatchn 是可选的子匹配变量,用于保存子匹配模式的结果。

在深入研究复杂的示例之前,让我们先看一些简单的示例。一个简单的字符串示例,其中包含任何字母。当遇到任何其他字符时,正则表达式搜索将停止并返回。

#!/usr/bin/tclsh

regexp {([A-Za-z]*)} "Tcl Tutorial" a b 
puts "Full Match: $a"
puts "Sub Match1: $b"

执行上述代码时,会产生以下结果:

Full Match: Tcl
Sub Match1: Tcl

多个模式

以下示例演示了如何搜索多个模式。这是一个示例模式,用于匹配任何字母后跟任何字符再后跟任何字母。

#!/usr/bin/tclsh

regexp {([A-Za-z]*).([A-Za-z]*)} "Tcl Tutorial" a b c  
puts "Full Match: $a"
puts "Sub Match1: $b"
puts "Sub Match2: $c"

执行上述代码时,会产生以下结果:

Full Match: Tcl Tutorial
Sub Match1: Tcl
Sub Match2: Tutorial

下面显示了上面代码的修改版本,用于说明子模式可以包含多个模式:

#!/usr/bin/tclsh

regexp {([A-Za-z]*.([A-Za-z]*))} "Tcl Tutorial" a b c  
puts "Full Match: $a"
puts "Sub Match1: $b"
puts "Sub Match2: $c"

执行上述代码时,会产生以下结果:

Full Match: Tcl Tutorial
Sub Match1: Tcl Tutorial
Sub Match2: Tutorial

Regex 命令的开关

Tcl 中可用的开关列表如下:

  • nocase - 用于忽略大小写。

  • indices - 存储匹配的子模式的位置,而不是匹配的字符。

  • line - 对换行符敏感的匹配。忽略换行符后的字符。

  • start index - 设置搜索模式开始的偏移量。

  • 标记开关的结束

在上面的示例中,我故意对所有字母都使用了 [A-Z, a-z],您可以轻松地使用 -nocase 代替,如下所示:

#!/usr/bin/tclsh

regexp -nocase {([A-Z]*.([A-Z]*))} "Tcl Tutorial" a b c  
puts "Full Match: $a"
puts "Sub Match1: $b"
puts "Sub Match2: $c"

执行上述代码时,会产生以下结果:

Full Match: Tcl Tutorial
Sub Match1: Tcl Tutorial
Sub Match2: Tutorial

另一个使用开关的示例如下所示:

#!/usr/bin/tclsh

regexp -nocase -line -- {([A-Z]*.([A-Z]*))} "Tcl \nTutorial" a b 
puts "Full Match: $a"
puts "Sub Match1: $b"
regexp -nocase -start 4 -line -- {([A-Z]*.([A-Z]*))} "Tcl \nTutorial" a b  
puts "Full Match: $a"
puts "Sub Match1: $b"

执行上述代码时,会产生以下结果:

Full Match: Tcl 
Sub Match1: Tcl 
Full Match: Tutorial
Sub Match1: Tutorial

Tk - 概述

Tk 代表工具包,它提供跨平台的 GUI 组件,帮助您构建图形用户界面。它是由 John Ousterhout 开发的,作为 Tcl 脚本语言的扩展。在与 Tcl 同步到 v8.0 之前,Tk 与 Tcl 的开发是独立进行的,版本彼此不同。

Tk 的特点

它是一个跨平台的工具包,支持 Linux、Mac OS、Unix 和 Microsoft Windows 操作系统。

  • 它是开源的。
  • 它提供了高度的可扩展性。
  • 它是可定制的。
  • 它是可配置的。
  • 它提供了大量的组件。
  • 它可以与其他动态语言一起使用,而不仅仅是 Tcl。
  • GUI 在各个平台上看起来相同。

使用 Tk 构建的应用程序

许多成功的应用程序都是使用 Tcl/Tk 构建的。

  • 仪表板软件用户界面
  • 关系数据库的表单 GUI
  • 关系数据库的 Ad Hoc GUI
  • 软件/硬件系统设计
  • Xtask - 任务管理
  • 使用 Tcl 和 Tk 进行音乐学研究
  • 日历应用程序
  • Tk 邮件
  • Tk 调试器

Tk - 环境

通常,所有 Mac 和 Linux 系统都预装了 Tk。如果它不可用或您需要最新版本,则可能需要安装它。Windows 没有自带 Tcl/Tk,您可能需要使用其特定的二进制文件来安装它。

Tk 解释器

它只是一个小的程序,允许您键入 Tk 命令并逐行执行它们。与编译器(编译器会完全执行)不同,它会在遇到错误时停止执行 tcl 文件。

让我们创建一个名为 helloWorld.tcl 的文件,如下所示。我们将使用它作为第一个程序,在您选择的平台上运行。

#!/usr/bin/wish

grid [ttk::button .mybutton -text "Hello World"] 

以下部分仅解释如何在每个可用的平台上安装 Tcl/Tk。

在 Windows 上安装

从提供的 Active Tcl/Tk 二进制文件列表中下载适用于 Windows 的最新版本安装程序。Active Tcl/Tk 社区版可供个人免费使用。

运行下载的可执行文件以安装 Tcl 和 Tk,这可以通过按照屏幕上的说明进行操作。

现在,我们可以通过使用 cd 切换到包含文件的文件夹,然后使用以下步骤构建并运行 Tcl 文件(例如 helloWorld.tcl):

C:\Tcl> wish helloWorld.tcl

按 Enter 键,我们将看到如下所示的输出:

Hello World Windows

在 Linux 上安装

大多数 Linux 操作系统都内置了 Tk,您可以在这些系统上立即开始使用。如果它不可用,您可以使用以下命令下载并安装 Tcl-Tk。

$ yum install tcl tk

现在,我们可以通过使用cd 命令切换到包含文件的文件夹,然后使用以下步骤构建并运行 Tcl 文件(例如 helloWorld.tcl):

$ wish helloWorld.tcl

按 Enter 键,我们将看到类似于以下内容的输出:

Hello World

在基于 Debian 的系统上安装

如果它在您的操作系统中没有预构建版本,您可以使用以下命令下载并安装 Tcl-Tk:

$ sudo apt-get install tcl tk

现在,我们可以通过使用cd 命令切换到包含文件的文件夹,然后使用以下步骤构建并运行 Tcl 文件(例如 helloWorld.tcl):

$ wish helloWorld.tcl

按 Enter 键,我们将看到类似于以下内容的输出:

Hello World

在 Mac OS X 上安装

从提供的 Active Tcl/Tk 二进制文件列表中下载适用于 Mac OS X 的最新版本软件包。Active Tcl 社区版可供个人免费使用。

运行下载的可执行文件以安装 Active Tcl,这可以通过按照屏幕上的说明进行。

现在,我们可以通过使用cd 命令切换到包含文件的文件夹,然后使用以下步骤构建并运行 Tcl 文件(例如 helloWorld.tcl):

$ wish helloWorld.tcl

按 Enter 键,我们将看到如下所示的输出:

Hello World

从源文件安装

当没有可用的二进制软件包时,您可以选择从源文件安装。通常建议对 Windows 和 Mac OS X 使用 Tk 二进制文件,因此下面仅显示在基于 Unix 的系统上编译源代码的过程:

  • 下载 源文件。

  • 现在,切换到下载的文件夹后,使用以下命令进行解压缩、编译和构建。

$ tar zxf tk8.6.1-src.tar.gz
$ cd tcl8.6.1
$ cd unix
$ ./configure —with-tcl=../../tcl8.6.1/unix —prefix=/opt —enable-gcc
$ make
$ sudo make install

注意 - 确保将文件名更改为在上面命令 1 和 2 中下载的版本。

Tk - 特殊变量

在 Tk 中,我们将某些变量分类为特殊变量,它们具有预定义的用法/功能。下面列出了特殊变量的列表。

序号 特殊变量 & 描述
1

tk_library

用于设置标准 Tk 库的位置。

2

tk_patchLevel

指的是 Tk 解释器的当前补丁级别。

3

tk_strictMotif

当非零时,Tk 会尽可能地遵循 Motif 的外观和风格。

4

tk_version

显示 Tk 版本。

上述特殊变量对 Tk 解释器具有特殊的含义。

使用 Tk 特殊变量的示例

让我们看看特殊变量的示例。

TK 版本

#!/usr/bin/wish

puts $tk_version

运行程序时,您将获得类似于以下内容的输出。

8.5

TK 库路径

#!/usr/bin/wish

puts $tk_library

运行程序时,您将获得类似于以下内容的输出。

/Library/Frameworks/Tk.framework/Versions/8.6/Resources/Scripts

TK 补丁级别

#!/usr/bin/wish

puts $tk_patchLevel

运行程序时,您将获得类似于以下内容的输出。

8.6.1

TK STRICTMOTIF

#!/usr/bin/wish

puts $tk_strictMotif

运行程序时,您将获得类似于以下内容的输出。

0

Tk - 小部件概述

基于 Tk 的应用程序的基本组件称为组件。组件有时也称为窗口,因为在 Tk 中,“窗口”和“组件”通常可以互换使用。Tk 是一个提供丰富的图形组件的包,用于使用 Tcl 创建图形应用程序。

Tk 提供了一系列组件,从基本的 GUI 组件(如按钮和菜单)到数据显示组件。这些组件非常易于配置,因为它们具有默认配置,使用起来非常方便。

Tk 应用程序遵循组件层次结构,其中任意数量的组件可以放置在另一个组件中,而这些组件又可以放置在另一个组件中。Tk 程序中的主组件称为根组件,可以通过创建 TkRoot 类的新实例来创建。

创建组件

创建组件的语法如下所示。

type variableName arguments options

这里的 type 指的是组件类型,例如按钮、标签等。根据每个组件的语法,参数可以是可选的或必需的。选项范围从每个组件的大小到格式。

组件命名约定

组件使用类似于命名包的结构。在 Tk 中,根窗口的名称为句点(.)和窗口中的元素,例如按钮命名为 .myButton1。变量名应以小写字母、数字或标点符号(句点除外)开头。第一个字符之后,其他字符可以是大写或小写字母、数字或标点符号(句点除外)。建议使用小写字母作为标签的开头。

颜色命名约定

可以使用名称(如红色、绿色等)声明颜色。它还可以使用十六进制表示,以 # 开头。十六进制数字的个数可以是 3、6、9 或 12。

尺寸约定

默认单位是像素,当我们没有指定任何尺寸时使用。其他尺寸包括:i 表示英寸,m 表示毫米,c 表示厘米,p 表示磅。

常用选项

所有部件都提供许多常用选项,如下表所示:

序号 语法和描述
1

-background color

用于设置部件的背景颜色。

2

-borderwidth width

用于以 3D 效果绘制边框。

3

-font fontDescriptor

用于设置部件的字体。

4

-foreground color

用于设置部件的前景色。

5

-height number

用于设置部件的高度。

6

-highlightbackground color

用于设置部件失去焦点时周围绘制的颜色矩形。

7

-highlightcolor color

用于设置部件获得焦点时周围绘制的颜色矩形。

8

-padx number

设置部件的水平内边距。

9

-pady number

设置部件的垂直内边距。

10

-relief condition

设置部件的 3D 浮雕效果。condition 可以是 raised、sunken、flat、ridge、solid 或 groove。

11

-text text

设置部件的文本。

12

-textvariable varName

与部件关联的变量。当部件的文本发生变化时,变量将设置为部件的文本。

13

-width number

设置部件的宽度。

下面显示了一个选项的简单示例。

#!/usr/bin/wish

grid [label .myLabel -background red -text "Hello World" -relief ridge -borderwidth 3]
   -padx 100 -pady 100

运行上述程序后,将得到以下输出。

Hello World Options

可用的部件分类如下:

基本部件

序号 部件和描述
1

Label

用于显示单行文本的部件。

2

Button

可点击的部件,用于触发操作。

3

Entry

用于接受单行文本输入的部件。

4

Message

用于显示多行文本的部件。

5

Text

用于显示和可选编辑多行文本的部件。

6

Toplevel

带有窗口管理器提供的全部边框和装饰的窗口。

布局部件

序号 部件和描述
1

Frame

容器部件,用于容纳其他部件。

2

Place

用于在特定位置容纳其他部件,使用其原点坐标和精确尺寸。

3

Pack

简单的部件,用于在将部件放置到父部件之前将其组织成块。

4

Grid

用于嵌套部件,以不同方向打包。

选择部件

序号 部件和描述
1

Radiobutton

具有一组开/关按钮和标签的部件,其中只能选择一个。

2

Checkbutton

具有一组开/关按钮和标签的部件,可以选中多个。

3

Menu

充当菜单项容器的部件。

4

Listbox

显示单元格列表的部件,可以选中一个或多个单元格。

大型部件

序号 部件和描述
1

Dialog

用于显示对话框的部件。

2

Spinbox

允许用户选择数字的部件。

3

Combobox

将输入框与一组可供用户选择的选项相结合的部件。

4

Notebook

选项卡式部件,使用索引选项卡在多个页面之间切换。

5

Progressbar

用于提供文件上传等长时间操作的进度可视化反馈的部件。

6

Treeview

用于显示和允许浏览树状结构的项目的部件。

7

Scrollbar

没有文本或画布部件的滚动部件。

8

Scale

比例尺部件,用于通过滑块选择数值。

其他部件

序号 部件和描述
1

Canvas

用于显示图形和图像的绘图部件。

我们将在接下来的章节中介绍每个部件。

Tk - 基本小部件

基本部件是几乎所有 Tk 应用程序中都提供的常用部件。可用的基本部件列表如下:

序号 部件和描述
1 Label

用于显示单行文本的部件。

2 Button

可点击的部件,用于触发操作。

3 Entry

用于接受单行文本输入的部件。

4 Message

用于显示多行文本的部件。

5 Text

用于显示和可选编辑多行文本的部件。

6 Toplevel

用于创建作为新顶级窗口的框架的部件。

下面显示了一个使用基本部件的简单 Tk 示例:

#!/usr/bin/wish

grid [label .myLabel -text "Label Widget" -textvariable labelText] 
grid [text .myText -width 20 -height 5]
.myText insert 1.0 "Text\nWidget\n"
grid [entry .myEntry -text "Entry Widget"]
grid [message .myMessage -background red -foreground white -text "Message\nWidget"]
grid [button .myButton1  -text "Button" -command "set labelText clicked"]

运行上述程序后,将得到以下输出:

Basic Widgets Example

Tk - 布局小部件

布局部件用于处理 Tk 应用程序的布局。Frame 部件用于对其他部件进行分组,place、pack 和 grid 是布局管理器,使您可以完全控制添加到窗口中的内容。可用的布局部件列表如下所示:

序号 部件和描述
1 Frame

容器部件,用于容纳其他部件。

2 Place

用于在特定位置容纳其他部件,使用其原点坐标和精确尺寸。

3 Pack

简单的部件,用于在将部件放置到父部件之前将其组织成块。

4 Grid

用于嵌套部件,以不同方向打包。

下面显示了一个布局部件的简单 Tk 示例:

#!/usr/bin/wish

frame .myFrame1 -background red  -relief ridge -borderwidth 8 -padx 10 -pady 10
   -height 100 -width 100
frame .myFrame2 -background blue  -relief ridge -borderwidth 8 -padx 10 -pady 10
   -height 100 -width 50
pack .myFrame1 
pack .myFrame2

运行上述程序后,将得到以下输出:

Frame Widget Example

Tk - 选择小部件

选择部件用于在 Tk 应用程序中选择不同的选项。可用的选择部件列表如下所示。

序号 部件和描述
1 Radiobutton

具有一组开/关按钮和标签的部件,其中只能选择一个。

2 Checkbutton

具有一组开/关按钮和标签的部件,可以选中多个。

3 Menu

充当菜单项容器的部件。

4 Listbox

显示单元格列表的部件,可以选中一个或多个单元格。

下面显示了一个使用选择部件的简单 Tk 示例:

#!/usr/bin/wish

grid [frame .gender ]
grid [label .label1  -text "Male" -textvariable myLabel1 ] 
grid [radiobutton .gender.maleBtn -text "Male"   -variable gender -value "Male"
   -command "set  myLabel1 Male"] -row 1 -column 2
grid [radiobutton .gender.femaleBtn -text "Female" -variable gender -value "Female"
   -command "set  myLabel1 Female"] -row 1 -column 3
.gender.maleBtn select
grid [label .myLabel2  -text "Range 1 not selected" -textvariable myLabelValue2 ] 
grid [checkbutton .chk1 -text "Range 1" -variable occupied1 -command {if {$occupied1 } {
   set myLabelValue2 {Range 1 selected}
} else {
   set myLabelValue2 {Range 1 not selected}
} }]
proc setLabel {text} {
   .label configure -text $text 
}

运行上述程序后,将得到以下输出:

Selection Widget Example

Tk - 画布小部件

Canvas 用于提供绘图区域。Canvas 部件的语法如下所示:

canvas canvasName options

选项

Canvas 部件可用的选项如下表所示:

序号 语法和描述
1

-background color

用于设置部件的背景颜色。

2

-closeenough distance

设置鼠标光标与可显示项目的接近程度。默认值为 1.0 像素。此值可以是分数,并且必须为正数。

3

-scrollregion boundingBox

此画布总区域的边界框。

4

-height number

用于设置部件的高度。

5

-width number

设置部件的宽度。

6

-xscrollincrement size

请求滚动时水平滚动的量。

7

-yscrollincrement size

请求滚动时垂直滚动的量。

下面显示了一个 Canvas 部件的简单示例:

#!/usr/bin/wish

canvas .myCanvas -background red -width 100 -height 100 
pack .myCanvas

运行上述程序后,将得到以下输出:

Canvas Widget Example

用于在 Canvas 中绘图的部件

用于在 Canvas 中绘图的可用部件列表如下所示:

序号 部件和描述
1 Line

绘制一条线。

2 Arc

绘制一个弧形。

3 Rectangle

绘制一个矩形。

4 Oval

绘制一个椭圆。

5 Polygon

绘制一个多边形。

6 Text

绘制文本。

7 Bitmap

绘制一个位图。

8 Image

绘制一个图像。

下面显示了一个使用不同 Canvas 部件的示例:

#!/usr/bin/wish

canvas .myCanvas -background red -width 200 -height 200 
pack .myCanvas
.myCanvas create arc 10 10 50 50 -fill yellow
.myCanvas create line 10 30 50 50 100 10 -arrow both -fill yellow -smooth true
   -splinesteps 2
.myCanvas create oval 50 50 100 80 -fill yellow
.myCanvas create polygon 50 150 100 80 120 120 100 190 -fill yellow -outline green
.myCanvas create rectangle 150 150 170 170  -fill yellow
.myCanvas create text 170 20 -fill yellow -text "Hello" -font {Helvetica -18 bold}
.myCanvas create bitmap 180 50 -bitmap info

运行上述程序后,将得到以下输出:

Canvas Widget Example2

Tk - 超级小部件

大型部件包括许多复杂的部件,这些部件通常在某些大型 Tk 应用程序中需要。可用的大型部件列表如下所示:

序号 部件和描述
1 Dialog

用于显示对话框的部件。

2 Spinbox

允许用户选择数字的部件。

3 Combobox

将输入框与一组可供用户选择的选项相结合的部件。

4 Notebook

选项卡式部件,使用索引选项卡在多个页面之间切换。

5 Progressbar

用于提供文件上传等长时间操作的进度可视化反馈的部件。

6 Treeview

用于显示和允许浏览树状结构的项目的部件。

7 Scrollbar

没有文本或画布部件的滚动部件。

8 Scale

比例尺部件,用于通过滑块选择数值。

下面显示了一个使用一些大型部件的简单 Tk 示例。

#!/usr/bin/wish

ttk::treeview .tree -columns "Creator Year" -displaycolumns "Year Creator" 
.tree heading Creator -text "Creator" -anchor center
.tree heading Year -text "Year" -anchor center
pack .tree
.tree insert {} end -id Languages -text "Languages"
.tree insert Languages end -text C -values [list "Dennis Ritchie" "1990"]
proc scaleMe {mywidget scaleValue} {
	$mywidget configure -length $scaleValue
} 
pack [scale .s2  -from 100.0 -to 200.0 -length 100 -background yellow -borderwidth 5
   -font{Helvetica -18 bold} -foreground red -width 40 -relief ridge -orien horizontal
   -variable a -command "scaleMe .s2" ]
pack [ttk::progressbar .p1 -orient horizontal -length 200 -mode indeterminate -value 90]
pack [ttk::progressbar .p2 -orient horizontal -length 200 -mode determinate -variable a
   -maximum 75 -value 20]

运行上述程序后,将得到以下输出:

Mega Widget Example

Tk - 字体

有一些部件支持显示文本。大多数部件都提供字体属性选项。创建字体的语法如下所示:

font create fontName options

选项

字体创建可用的选项如下表所示:

序号 语法和描述
1

-family familyName

字体系列的名称。

2

-size number

字体的尺寸。

3

-weight level

字体的粗细。

下面显示了一个字体创建的简单示例:

#!/usr/bin/wish

font create myFont -family Helvetica -size 18 -weight bold 
pack [label .myLabel -font myFont -text "Hello World"]

运行上述程序后,将得到以下输出:

Fonts Example

要获取所有可用的字体,可以使用以下命令:

#!/usr/bin/wish

puts [font families]

运行上述命令后,将得到以下输出:

{Abadi MT Condensed Extra Bold} {Abadi MT Condensed Light} {Al Bayan} {Al Nile}
{Al Tarikh} {American Typewriter} {Andale Mono} Arial {Arial Black}
{Arial Hebrew} {Arial Narrow} {Arial Rounded MT Bold} {Arial Unicode MS}
Athelas Avenir {Avenir Next} {Avenir Next Condensed} Ayuthaya Baghdad {Bangla MN}
{Bangla Sangam MN} {Baoli SC} Baskerville {Baskerville Old Face} Batang {Bauhaus 93}
Beirut {Bell MT} {Bernard MT Condensed} BiauKai {Big Caslon} {Book Antiqua}
{Bookman Old Style} {Bookshelf Symbol 7} Braggadocio {Britannic Bold} {Brush Script MT}
Calibri {Calisto MT} Cambria {Cambria Math} Candara Century {Century Gothic}
{Century Schoolbook} Chalkboard {Chalkboard SE} Chalkduster {Charcoal CY} Charter
Cochin {Colonna MT} {Comic Sans MS} Consolas Constantia {Cooper Black} Copperplate
{Copperplate Gothic Bold} {Copperplate Gothic Light} Corbel {Corsiva Hebrew} Courier
{Courier New} {Curlz MT} Damascus {DecoType Naskh} Desdemona {Devanagari MT}
{Devanagari Sangam MN} Didot {DIN Alternate} {DIN Condensed} {Diwan Kufi} {Diwan Thuluth}
{Edwardian Script ITC} {Engravers MT} {Euphemia UCAS} Eurostile Farah Farisi
{Footlight MT Light} {Franklin Gothic Book} {Franklin Gothic Medium}
Futura Gabriola Garamond {GB18030 Bitmap} {Geeza Pro} Geneva {Geneva CY}
Georgia {Gill Sans} {Gill Sans MT} {Gloucester MT Extra Condensed}
{Goudy Old Style} {Gujarati MT} {Gujarati Sangam MN} Gulim GungSeo {Gurmukhi MN}
{Gurmukhi MT} {Gurmukhi Sangam MN} Haettenschweiler {Hannotate SC} {Hannotate TC}
{HanziPen SC} {HanziPen TC} Harrington HeadLineA Hei {Heiti SC} {Heiti TC}
Helvetica {Helvetica CY} {Helvetica Neue} Herculanum {Hiragino Kaku Gothic Pro}
{Hiragino Kaku Gothic ProN} {Hiragino Kaku Gothic Std} {Hiragino Kaku Gothic StdN}
{Hiragino Maru Gothic Pro} {Hiragino Maru Gothic ProN}
{Hiragino Mincho Pro} {Hiragino Mincho ProN} {Hiragino Sans GB}
{Hoefler Text} Impact {Imprint MT Shadow} InaiMathi {Iowan Old Style} Kai Kailasa
{Kaiti SC} {Kaiti TC} {Kannada MN} {Kannada Sangam MN} Kefa {Khmer MN} {Khmer Sangam MN}
{Kino MT} Kokonor Krungthep KufiStandardGK {Lantinghei SC} {Lantinghei TC} {Lao MN}
{Lao Sangam MN} {Libian SC} {LiHei Pro} {LiSong Pro} {Lucida Blackletter} {Lucida Bright}
{Lucida Calligraphy} {Lucida Console} {Lucida Fax} {Lucida Grande} {Lucida Handwriting}
{Lucida Sans} {Lucida Sans Typewriter} {Lucida Sans Unicode} {Malayalam MN}
{Malayalam Sangam MN} Marion {Marker Felt} Marlett {Matura MT Script Capitals}
Meiryo Menlo {Microsoft Sans Serif} Mishafi Mistral {Modern No. 20} Monaco {MS Gothic}
{MS Mincho} {MS PGothic} {MS PMincho} {MS Reference Sans Serif} {MS Reference Specialty}
Mshtakan {MT Extra} Muna {Myanmar MN} {Myanmar Sangam MN} Nadeem {Nanum Brush Script}
{Nanum Gothic} {Nanum Myeongjo} {Nanum Pen Script} {New Peninim MT} {News Gothic MT}
Noteworthy Onyx Optima {Oriya MN} {Oriya Sangam MN} Osaka Palatino {Palatino Linotype}
Papyrus PCMyungjo Perpetua {Perpetua Titling MT} PilGi {Plantagenet Cherokee}
Playbill PMingLiU {PT Mono} {PT Sans} {PT Sans Caption} {PT Sans Narrow} {PT Serif}
{PT Serif Caption} Raanana Rockwell {Rockwell Extra Bold} Sana Sathu {Savoye LET}
Seravek Silom SimSun {Sinhala MN} {Sinhala Sangam MN} Skia {Snell Roundhand} {Songti SC}
{Songti TC} Stencil STFangsong STHeiti STIXGeneral STIXIntegralsD STIXIntegralsSm
STIXIntegralsUp STIXIntegralsUpD STIXIntegralsUpSm STIXNonUnicode STIXSizeFiveSym
STIXSizeFourSym STIXSizeOneSym STIXSizeThreeSym STIXSizeTwoSym STIXVariants STKaiti
STSong Superclarendon Symbol Tahoma {Tamil MN} {Tamil Sangam MN} TeamViewer8 {Telugu MN}
{Telugu Sangam MN} Thonburi Times {Times New Roman} {Trebuchet MS} {Tw Cen MT} Verdana
Waseem {Wawati SC} {Wawati TC} Webdings {Weibei SC} {Weibei TC} {Wide Latin} Wingdings
{Wingdings 2} {Wingdings 3} {Xingkai SC} {Yuanti SC} YuGothic YuMincho {Yuppy SC}
{Yuppy TC} {Zapf Dingbats} Zapfino {Apple Braille} {Apple Chancery} {Apple Color Emoji}
{Apple LiGothic} {Apple LiSung} {Apple SD Gothic Neo} {Apple Symbols}
AppleGothic AppleMyungjo {Monotype Corsiva} {Monotype Sorts}

Tk - 图像

Image 部件用于创建和操作图像。创建图像的语法如下:

image create type name options

在上述语法中,type 是 photo 或 bitmap,name 是图像标识符。

选项

Image 创建可用的选项如下表所示:

序号 语法和描述
1

-file fileName

图像文件的名称。

2

-height number

用于设置部件的高度。

3

-width number

设置部件的宽度。

4

-data string

以 base 64 编码的字符串表示的图像。

下面显示了一个 Image 部件的简单示例:

#!/usr/bin/wish

image create photo imgobj -file "/Users/rajkumar/Desktop/F Drive/pictur/vb/Forests/
   680049.png" -width 400 -height 400 
pack [label .myLabel]
.myLabel configure -image imgobj 

运行上述程序后,将得到以下输出:

Image Example

Image 可用的函数如下表所示:

序号 语法和描述
1

image delete imageName

从内存中删除图像,并视觉上删除相关的部件。

2

image height imageName

返回图像的高度。

3

image width imageName

返回图像的宽度。

4

image type imageName

返回图像的类型。

5

image names

返回内存中存在的图像列表。

下面显示了一个使用上述 Image 部件命令的简单示例:

#!/usr/bin/wish

image create photo imgobj -file "/Users/rajkumar/images/680049.png"
   -width 400 -height 400 
pack [label .myLabel]
.myLabel configure -image imgobj
puts [image height imgobj]
puts [image width imgobj]
puts [image type imgobj]
puts [image names]
image delete imgobj

一旦执行“image delete imgobj”命令,图像将从视觉上和内存中删除。在控制台中,输出将类似于以下内容:

400
400
photo
imgobj ::tk::icons::information ::tk::icons::error ::tk::icons::
warning ::tk::icons::question

Tk - 事件

事件在其最简单的形式中,可以通过命令来处理。事件处理的一个简单示例是使用按钮进行事件处理,如下所示:

#!/usr/bin/wish

proc myEvent { } {
   puts "Event triggered"
}
pack [button .myButton1  -text "Button 1"   -command myEvent]

运行上述程序后,将得到以下输出:

Event Example

下面显示了一个用于显示延迟文本动画事件的简单程序:

#!/usr/bin/wish

proc delay {} {
   for {set j 0} {$j < 100000} {incr j} {} 
}

label .myLabel -text "Hello................" -width 25
pack .myLabel
set str "Hello................"
for {set i [string length $str]} {$i > -2} {set i [expr $i-1]} {
   .myLabel configure -text [string range $str 0 $i]
   update
   delay
}

运行程序后,将以动画方式获得以下输出:

Event Example3

延迟后的事件

延迟后事件的语法如下所示:

after milliseconds number command

下面显示了一个用于显示延迟后事件的简单程序:

#!/usr/bin/wish

proc addText {} {
   label .myLabel -text "Hello................" -width 25
   pack .myLabel
}
after 1000 addText

运行程序后,将在 1 秒后获得以下输出:

Event Example2

您可以使用 after cancel 命令取消事件,如下所示:

#!/usr/bin/wish

proc addText {} {
   label .myLabel -text "Hello................" -width 25
   pack .myLabel
}
after 1000 addText
after cancel addText

事件绑定

事件绑定的语法如下所示:

bind arguments 

键盘事件示例

#!/usr/bin/wish

bind .  {puts "Key Pressed: %K "}

运行程序并按下字母 X 后,将获得以下输出:

Key Pressed: X 

鼠标事件示例

#!/usr/bin/wish

bind .  {puts "Button %b Pressed : %x %y "}

运行程序并按下鼠标左键后,将获得类似于以下内容的输出:

Button 1 Pressed : 89 90 

将事件与按钮链接的示例

#!/usr/bin/wish

proc myEvent { } {
   puts "Event triggered"
}
pack [button .myButton1  -text "Button 1"   -command myEvent]
bind .  ".myButton1 invoke"

运行程序并按下 Enter 键后,将获得以下输出:

Event triggered

Tk - 窗口管理器

窗口管理器用于处理顶级窗口。它有助于控制窗口的大小、位置和其他属性。在 Tk 中,. 用于引用主窗口。窗口命令的语法如下所示:

wm option window arguments

Tk wm 命令可用的选项列表如下表所示:

序号 语法和描述
1

aspect windowName a b c d

尝试将宽度/高度的比率保持在 a/b 和 c/d 之间。

2

geometry windowName geometryParams

用于设置窗口的几何形状。

3

grid windowName w h dx dy

设置网格尺寸。

4

group windowName leaderName

leaderName 指定一组相关窗口的领导者。

5

deiconify windowName

如果窗口最小化,则将其恢复到正常状态。

6

iconify windowName

最小化窗口。

7

state windowName

返回窗口的当前状态。

8

withdraw windowName

取消映射窗口,并将其详细信息从内存中移除。

9

iconbitmap windowName image

设置或返回图标位图。

10

iconPhoto 窗口名称 图片

设置或返回图标图片。

11

command 窗口名称 命令字符串

在 WM_COMMAND 属性中记录启动命令。

12

protocol 窗口名称 参数

注册一个命令来处理协议请求名称,可以是 WM_DELETE_WINDOW,

WM_SAVE_YOURSELF,

WM_TAKE_FOCUS。例如:wm protocol。

WM_DELETE_WINDOW 退出。

13

minsize 窗口名称 尺寸

确定窗口的最小尺寸。

14

maxsize 窗口名称 尺寸

确定窗口的最大尺寸。

15

title 窗口名称 标题文本

确定窗口的标题。

16

attributes 子选项

有很多属性可用,例如 alpha、全屏等。

以上一些命令在以下示例中使用 -

#!/usr/bin/wish

wm maxsize . 800 800
wm minsize . 300 300
wm title . "Hello"
wm attributes . -alpha ".90" 
wm geometry . 300x200+100+100

运行上述程序后,将得到以下输出:

Window Manager

如您所见,alpha 是可用属性之一。常用子命令列表如下 -

序号 语法和描述
1

-alpha 数字

设置窗口的 alpha 值。

2

-fullscreen 数字

数字可以是 0 表示普通屏幕,1 表示全屏。

3

-topmost 数字

设置或返回窗口是否置顶。值可以是 0 或 1。

创建窗口

我们可以使用 toplevel 命令创建窗口,以下是一个示例 -

#!/usr/bin/wish

toplevel .t

运行上述程序后,将得到以下输出:

Window Manager2

销毁窗口

我们可以使用 destroy 命令销毁窗口,以下是一个示例 -

#!/usr/bin/wish

destroy .t

以上命令将销毁名为 .t 的窗口。

Tk - 几何管理器

几何管理器用于管理窗口和其他框架的几何形状。我们可以用它来处理窗口和框架的位置和大小。 布局部件 用于此目的。

定位和调整大小

窗口定位和调整大小的语法如下所示 -

wm geometry . wxh+/-x+/-y

这里,w 指的是宽度,h 指的是高度。后面跟着一个 '+' 或 '-' 符号,以及表示屏幕上 x 位置的数字。类似地,后面的 '+' 或 '-' 符号以及数字表示屏幕上的 y 位置

以下是一个关于以上语句的简单示例 -。

#!/usr/bin/wish

wm geometry . 300x200+100+100

运行上述程序后,将得到以下输出:

GeometryManager1 Example

网格几何

网格几何的语法如下所示 -

grid gridName -column number -row number -columnspan number -rowspan number

列、行、列跨度或行跨度有助于提供网格几何。

以下是一个关于以上语句的简单示例 -

#!/usr/bin/wish

frame .myFrame1 -background red  -height 100 -width 100
frame .myFrame2 -background blue -height 100 -width 50
grid .myFrame1 -columnspan 10 -rowspan 10 -sticky w
grid .myFrame2 -column 10 -row 2

运行上述程序后,将得到以下输出:

Grid Geometry
广告