天天看點

Tcl/Tk入門(中)

編寫Tcl腳本之前,必須學會兩件事:

1).必須學會Tcl文法,其内容是決定如何解析指令規則;

2).必須掌握在腳本中使用的獨立指令(Tcl提供了近百條内建指令,Tk提供幾十條)。

第一部分 Tcl語言基礎

1.1.腳本、指令和單詞的基本概念

        Tcl腳本包含一條或多條指令。指令通過換行符或分号隔開。每條指令都包含一個或多個單詞,第一個單詞是指令名,其他單詞

是指令的參數。而Tcl處理一個指令分為兩步:解析和執行。在解析時,Tcl解釋器将指令分解為單詞,并執行替換。Tcl解釋器隻是

進行簡單的字元串操作。例如:将字元串$input用input變量中存放的字元串代替。在執行階段,指令中的各個單詞都有了具體的

意義。Tcl把第一個單詞作為指令名稱,檢查這個指令是否已經定義,并且查找完成該指令功能的指令過程。若指令已經定義,Tcl

解釋器就調用該指令過程,把指令中的全部單詞傳遞給該過程。指令過程會根據自己的需要來分辨這些單詞的意義。也就是說Tcl

的指令由兩部分組成,第一部分是指令名,第二部分是指令名後面的若幹單詞,做為指令的參數。

1.2.腳本執行的過程

1.2.1.指令替換

        指令解析時的變量替換(把單詞中的原始字元替換為另外的值)。Tcl提供了三種替換形式:變量替換、指令替換、反斜線

替換。Tcl替換的邏輯:

1).Tcl解析一條指令時,隻從左向右解析一次,進行一輪替換。每個字元隻會被掃描一次。

2).每一個字元隻會發生一次替換,而不會對替換後的結果再進行一次掃描替換。

Tcl替換的分類

1).變量替換:由$符号引發,将Tcl變量的值插入單詞中。

2).指令替換:可把一個單詞的部分或全部替換為一個指令的結果。指令替換通過方括号表示,會調用括号中的指令。

3).反斜線替換:用于向單詞中插入像換行符這樣的特殊字元,以及像[、$這樣的會被Tcl解析器認為是有特殊含義的字元。

        有替換就有不替換的情況。Tcl提供了一些方法,可以阻止解析器對$和分号等字元進行特殊處理,這些方法稱為引用。

Tcl的引用包括以下兩種(反斜線替換也是一種引用):

1).雙引号引用:取消其中的單詞和指令分隔符的特殊解釋。

2).大括号引用:取消其中所有特殊字元的特殊解釋。

總結:完成了指令的替換,也就完成了指令的解析。

1.2.2.指令執行

1.3.變量和表達式

1.3.1.變量

Tcl支援兩種類型的變量:簡單變量(數量變量)和關聯數組。

1).簡單變量:包含一個名字和一個值。名字和值都可以是任意字元串。

      變量名命名規則:以一個字母開頭,由一些字母、數字和下劃線組成。區分大小寫。

      Tcl的内部資料存儲。==》高效的内部表達形式。

2).數組:數組是元素的集合,每一個元素是有自己的名稱和值的變量。

    數組元素的名稱由兩部分組成:數組名和數組中的元素名。數組名和元素名可以是任意字元串。

    數組的文法形式: 數組名(元素名)

    數組是無序的資料結構(在Tcl内部使用一個哈希表存儲數組元素)

    Tcl清單是有序的資料結構。   

1.3.2.表達式

1.4.字元串操作

1.5.清單

1.6.字典

1.7.流程控制

1. if...elseif...else 結構:

    if expr1? then? body1 elseif expr2? then? body2 elseif...? else?bodyN? 

if {$x != 1} {
      puts "$x is !=1"
  } else {
      puts "$x is 1"   
  }
           
if {條件1} then{
     puts "語句1"
  }  elseif {條件2} then{   
     puts "語句2"  
  }  else { puts "不滿足條件1、條件2" }
           

2. switch 結構:

    switch string pattern1 body1 ?pattern2 body2? ... ?patternN bodyN?

    switch string { pattern1 body1 ?pattern2 body2?...?patternN bodyN? }

switch $x "ONE" "puts ONE=1" "TWO" "puts TWO=2" "default" "puts NO_MATCH"
結果:NO_MATCH
           
set a "one"
set b one
switch $a {
       "$b" {puts "MATCH.."}
       one  {puts "MATCH,YEAH! "}
       default {puts " NO MATCH"}
  } 
結果:MATCH,YEAH!
           

3.while循環結構:

   while test body  [test:條件;body:循環體]

set x 1
while {$x < 5} {
   puts "x is $x"
   set x [expr {$x + 1}]
}
puts "exited loop with x equal to $x\n"

輸出結果:
x is 1
x is 2
x is 3
x is 4
exited loop with x equal to 5
           

下面的例子,可以說明在 循環體内 { }  和 “ ” 的差別: 

set x 0
while "$x < 5" {
    set x [expr {$x + 1}]
    if {$x > 7} break
    if "$x > 3" continue
    puts "x is $x"
}

puts "exited this loop with X equal to $x"

輸出結果:
inter loop before x=1
x is 1
inter loop before x=2
x is 2
inter loop before x=3
x is 3
inter loop before x=4
inter loop before x=5
inter loop before x=6
inter loop before x=7
exited this loop with X equal to 8
           

4.for循環結構:

     for start test next body [start:進入循環前必須執行的語句,test:進入循環的判斷,next:循環計數自增加(也可以是其他語句),body:循環體 ]

for {set i 0} {$i < 10} {incr i} {
    puts "I inside first loop:$i"
}

for {set i 3} {$i < 2} {incr i} {
    puts "I inside second loop: $i"
}

結果:
I inside first loop:0
I inside first loop:1
I inside first loop:2
I inside first loop:3
I inside first loop:4
I inside first loop:5
I inside first loop:6
I inside first loop:7
I inside first loop:8
I inside first loop:9
           

5.自定義指令:

proc name args body

proc sum {arg1 arg2} {
    set x [expr {$arg1 + $arg2}];
    return $x
}

puts " The sum of 2 + 3 is: [sum 2 3]\n\n"

proc for {a b c} {
    puts "The for command has been replaced by a puts";
    puts "The arguments were: $a\n$b\n$c\n"
}

for {set i 1} {$i < 10} {incr i}

輸出結果:
The sum of 2 + 3 is: 5

The for command has been replaced by a puts
The arguments were: set i 1

$i < 10
incr i
           

1.8.過程

1.9.命名空間

1.10.通路檔案

1.11.程序間通信

1.12.錯誤與異常

1.13.其他

1.13.1.建立與使用Tcl腳本庫

1.13.2.Tcl内部管理

1.13.3.其他

執行個體:

1.13.3.1.字元串輸出:puts

puts "hello,world"
puts {hello,world}
           

1.13.3.2.變量指派:set

注:Tcl是面向字元串的語言。是以,Tcl中的所有變量都可以認為是字元串變量。這個在下面的例子中還會有涉及。

set  b  5
set  fruit  apple
           

1.13.3.3.變量使用:$

注:expr 是求解表達式的值,[ ] 将expr 的結果做為一個變量給puts輸出。

set a 5
set b 6
puts  [expr {$a + $b}]
           

1.13.3.4.Tcl中的運算符:

  -  減号;  +  加号;    ~  逐位非;! 非;

  ** 幂;     *  乘号;     /  除号;      %   取餘;

  << >>  左、右移位(必須是整數);   <  小于;  >  大于;  <=  小于等于;   >=  大于等于;

  eq  比較兩個字元串是否相等;      ne  比較兩個字元串不等;

  in  check一個字元串是否包含在list中;       ni  check一個字元串是否不包含在list中; 

  &  與;      ^  異或;        |  或;       &&  邏輯與;          ||  邏輯或;

  x?y:z    if-then-else(與java中的該運算形式是一緻的)

set a 128 
expr {$a >> 1}   結果:64        
expr {$a << 2}   結果:512

set p 1
expr {$p>0? ($p+1) : ($p-1)}   結果:2
           

1.13.3.5.Tcl支援的數學函數表達式:

  abs         acos         asin        atan

  atan2     bool          ceil         cos

  cosh       double     entier      exp

  floor        fmod        hypot       int

  isqrt        log           log10       max

  min         pow          rand        round

  sin          sinh          sqrt          srand

  tan          tanh          wide

1.13.3.6.Tcl的類型轉換函數:

double( )      将一個數字 轉換為一個浮點數

int( )              将一個數字 轉換為整數,截取掉小數部分

wide( )          将數字轉換為寬整數

entier( )         實在不明白這個是幹啥用的。(-_-~)

注:作為初學者,實在是不明白 wide( ) 、entier( ) 函數是在什麼情況下使用。

puts [expr {double(1)}]   結果:1.0
puts [expr {int(2.2)}]    結果:2
puts [expr {wide(3.4)}]   結果:3
puts [expr {entier(10.00)}]  結果:10
           

1.13.3.7.字元串操作:string length

注:參看以下例子,Tcl是将數字、字元串都看做字元串來處理的。不知道是否應該這樣了解,若了解的不正确,盼指教!

set b "abcdef"
set x 2
expr {[string length $b]-2*$x}       結果:2

set b 12.45  
set x 2
expr {[string length $b]-2*$x}       結果:1   
           

數字 12.45 被string length 當做字元串處理,得到結果5。當然 string length 可能本來就要将所有變量當做字元串來處理吧。

第二部分  Tk腳本編寫

2.1.Tk概述

2.2.Tk的元件

2.3.主題元件

2.4.字型、位圖和圖像

2.5.幾何管理器

2.6.事件和綁定

2.7.畫布元件

2.8.文本元件

2.9.選擇與剪貼闆

2.10.視窗管理器

2.11.其他

2.11.1.焦點、模态互動與自定義對話框

2.11.2.其他

第三部分  Tcl應用程式的編寫

3.1.Tcl與C語言的內建原理

3.2.解釋器

3.3.Tcl對象

3.4.處理Tcl代碼

3.5.通路Tcl變量

3.6.建立新的Tcl指令

3.7.擴充包

3.8.嵌入Tcl

3.9.異常

3.10.字元串工具

3.11.哈希表

3.12.清單和字典對象

3.13.通道

3.14.事件處理

3.15.檔案系統的互動

3.16.作業系統工具

3.17.線程

3.18.建構Tcl及其擴充

修訂:

1.修訂于2014年11月22日,修改了文章結構,内容組織。糾正了錯誤的了解。

參考:

        《TCL/TK入門經典(第二版)》

注:

        根據 官網的Tutorial教程寫的,例子用來熟悉文法。Tcl/Tk入門(下)會做一個東西出來,以檢驗學習效果。