#

這一篇文章主要是想快速的紹介Tcl/Tk,它沒有長篇大論,反而用非常直接的方式切入主題,希望由操作去感受如何使用Tcl/Tk。

1.1 Hello Tcl/Tk

在學習程式語言的時候,習慣上都會以一個「Hello world!!」程式,當做是學習的第一步,比照慣例,接下來我們也要試著寫出這樣的程式。程式的功能很簡單,只是在螢幕上列印出一個「Hello Tcl!!」的字串。

程式1-1 : hello.tcl


完成了,只有一行。是的只有一行,而且不到20個字。它可以正確的做到我們想要的功能。請大家使用任何一種純文字編輯器,輸入這一行程式,並命名為hello.tcl,檔案儲存位置請隨意。

1.1.1 在Windows環境下執行

請開啟命令提示字元並且輸入下面的指令 (我的hello.tcl儲存在C:\下)

C:\> tclsh hello.tcl

執行起來應該像這樣,程式在畫面上輸出一行「Hello Tcl !!」,然後結束

圖 1-1 hello.tcl在windows環境的執行畫面

1.1.2 在Linux環境下執行

請在console下輸入一樣的指令 (我的hello.tcl儲存在家目錄下)

$ tclsh hello.tcl

在Linux下執行的畫面像這樣,當然功能和在windows下是一樣的。

圖 1-2 hello.tcl在Linux環境的執行畫面

1.1.3 在Mac OSX環境下執行

請開啟終端機,然後輸入和Linux平台一樣的指令(我的hello.tcl儲存在家目錄下)

$ tclsh hello.tcl

在Mac OSX下執行的畫面像這樣,當然功能和在上面的兩個平台是一樣的。

圖 1-3 hello.tcl在Mac OSX環境的執行畫面

1.1.4 圖形介面版本的Hello World

完成了文字介面版本的「Hello World」,下一步我們要試試用Tk來製作圖形介面的版本。這個版本的功能稍稍有一點不同,它會畫出一個視窗並在上面顯示一個「Hello Tk」的按扭,當這個按扭被執行後,就會結束程式。

程式1-2 : hello2.tcl


...又是一行。沒錯又只有一行就完成了視窗介面的版本,請把程式儲存成hello2.tcl。如果有圖形介面的,要改用wish來執行程式。來看看Mac OSX下的執行結果吧!!

$ wish hello2.tcl

圖 1-4 有圖形介面版本的Hello World。
哦!! 看來你會在Mac、Linux下開發視窗程式了...雖然只是一小步。

1.2 程式說明

程式1-1及程式1-2都只有一行,接下來仔細說明這兩個程式。

1.2.1 程式1-1說明

請注意 puts 這個部分



Tcl的程式是由許多「命令」所組成,puts就是其中一個命令,puts能夠把跟在其後的字串輸出到螢幕上並自動加上斷行。程式1-1的例子就是把"Hello Tcl !!"輸出,注意puts和字串間一定要用空白隔開。如果要連續輸出3行可以這樣寫。



執行結果是:

Hello Tcl-1
Hello Tcl-2
Hello Tcl-3

每次輸出完字串puts都會自動補上斷行,如果不希望自動補上斷行,可以在puts及輸出字串間補上一個-nonewline的參數。



執行結果:

Hello TclTk

因為第一個puts加上了-nonewline參數不會自動補上斷行,所以下一個puts命令的字串輸出就緊接在後。

§ 什麼是命令參數

前面有提到Tcl的程式是由許多命令所組成的,而參數是附加在命令之後的項目,它可以用來調整命令執行的行為。一般來說給予命令不同的參數,那命令在執行時就會有不一樣的執行效果。當然對於不同的Tcl命令,它們可以接受的參數也會有所差異。例如,puts如果加上 -nonewline參數,就是希望puts在執行後不要自動補上斷行。

1.2.2 程式1-2說明

請先注意到被中括號夾起來的內容



在Tcl程式裡,夾在中括號裡的內容會被當成是子命令優先執行,中括號及其內容會在子命令執行完後被代換成子命令的執行結果。所以程式1-2的一行程式其實執行了2個命令,首先執行子命令button:



button命令用來建立按鈕。.btn是給予這個按鈕獨一無二的ID, -text 是命令的參數後面跟的字串可以用來指定要顯示在按鈕上的文字,-command也是命令的參數其後可以指定按鈕執行時的動作,在這個例子中,按下按鈕會執行exit命令,它的功能是結束程式,所以當你按下按鈕就會結束程式。button命令執行完後, 預設會回傳按鈕的ID,以這個例子來看會回傳.btn。



依子命令的代換原則 .btn 取代了原來中括號的部份,所以程式看起來像上面一行。pack 是Tk的幾合管理命令,用來在視窗上排列視窗元件(widget),.btn是要排放的視窗元件,-expnad及-fill都是命令的參數,用來指定.btn排放時要跟著視窗放大及縮小。

§ 什麼是視窗元件 (widget)

簡單的說視窗元件就是像按鈕、文字方塊、組合式下拉選單、清單方塊、功能表...等,用來組成圖形操作介面的元件。

1.2.3 程式註解

在Tcl裡如果一行的第一個非空白字元是井字號,那麼這一行會被Tcl當作是註解而不會被當做程式的一部份。註解的功能是讓程式設計者可以為程式加註說明,目的是為了可以方便看懂或提醒程式的運作。例如下面井字開頭的一行都是註解:



這個程式的第1及5行即是上面提到的註解,另外第6行位置「;#」之後的文字串也是註解,與前兩個註解不同的是,在第6行中只有「;#」之後的內容會被成是註解,而「;#」之前的內容都還是程式碼。

本章回顧

你可以使用tclsh或wish啟動tcl的程式檔,方法是在終端機下執行這樣的命令:

$ tclsh tcl程式檔

或是:

$ wish tcl程式檔

這兩者的差別在於wish預設就載入了Tk的支援,所以有圖形介面的程式請使用wish啟動,否則使用tclsh啟動。

puts可以把跟在後面的文字串列印到終端機顯示,程式要這樣寫:

puts "你要輸出的文字串"

如果文字串沒有包含空白字元,前後的雙引號是可以省略的,但還是建議你加上它們。

tcl提供了單行註解的功能,只要每一行的第一個字用「#」號開頭,這一行就會被tcl當成註解,不會被執行。

18 個意見

匿名 | 2010年10月31日 下午11:07

您好:

謝謝您那麼用心的編輯這麼棒的教學文件,讓我受益良多..

對了,tcl有沒有一次註解多行的方法啊,就像C,

/*
.....
...
...
*/

dai | 2010年11月7日 上午8:55

Hi

Tcl沒有多行的註解,但可以這樣:

if {0} {
...
...
}

這樣也有多行註解的效果

isPeter | 2010年11月8日 下午3:05

寫的真好,清楚明瞭
對我幫助很大,感謝你!

dai | 2010年11月20日 上午9:42

客氣了,謝謝你。

匿名 | 2011年1月11日 下午3:41

好文 受益良多

匿名 | 2011年2月5日 下午6:29

好文 簡單易懂 謝囉

匿名 | 2011年3月8日 下午2:46

寫的真好
簡單 易懂
謝謝囉...^^

匿名 | 2011年11月23日 下午5:34

如果是用Eclipse去編輯程式的話是可以ctrl+/把圈選的範圍一次全部標記

匿名 | 2012年4月14日 下午1:24

一行就能寫出簡單的視窗程式,太棒了 ^^

匿名 | 2012年12月19日 下午10:59

資訊界有您這樣無私付出的好人 真好!!^^

匿名 | 2013年3月27日 上午10:50

想請教下
如果我使用snmp_get 抓到MAC位址
set hf [snmp_get -t 1 -r 3 -Oqv $CMlocal public .1.3.6.1.2.1.2.2.1.6.1]
假設取出$hf變數為"2f 9w 5b fd as fg"
如何變成2f:9w:5b:fd:as:fg
試過用join 但無效果

dai | 2013年3月27日 下午1:42


試試 puts [join "2f 9w 5b fd as fg" :]

再試試 puts [join $hf :]

jimmy | 2013年3月27日 下午1:48

可以先去掉 " 再join
join [string trim $hf \"] :

或是用 eval 去執行
eval join $hf :

匿名 | 2013年3月27日 下午3:07

感謝dai與jimmy回答 不過以下方法都不是我想要的結果
問題
set hf [snmp_get -t 1 -r 3 -Oqv $CMlocal public .1.3.6.1.2.1.2.2.1.6.1]
puts $hf ; #會輸出 "2f 9w 5b fd as fg" 我想直接就輸出2f:9w:5b:fd:as:fg

1.可以成功輸出我想要的結果 但我想要處理$hf
puts [join "2f 9w 5b fd as fg" :]
2f:9w:5b:fd:as:fg

2.這為什麼感覺沒變化
puts [join $hf :]
2f 9w 5b fd as fg

3.有去除" 但無法加入:
join [string trim $hf \"]
2f 9w 5b fd as fg

jimmy | 2013年3月27日 下午10:47

join指令語法是: join list ?joinString?
作用是把list裡的每個元素利用joinString合併起來
joinString沒指定的話就是空白

set hf1 {"2f 9w 5b fd as fg"}
set hf2 {2f 9w 5b fd as fg}
llength $hf1 ;# 輸出為1
llength $hf2 ;# 輸出為6

join $hf1 : ;#輸出為 2f 9w 5b fd as fg
join $hf2 : ;#輸出為 2f:9w:5b:fd:as:fg

hf1 因為被當成只有1個元素,所以不會用 : 合併
hf2 因為被當成有6個元素,所以可以合併

使用 eval
eval join $hf1 : ;#輸出為 2f:9w:5b:fd:as:fg
這行相當於執行
join "2f 9w 5b fd as fg" :

如果是用
join $hf1 :
這邊的 hf1 相當於
[list "2f 9w 5b fd as fg"] ,是只有一個元素的list,要輸出對的值可以連用2次join
join [join $hf1] : ;#同樣可以輸出 2f:9w:5b:fd:as:fg









dai | 2013年3月28日 上午11:00

謝謝 jimmy 熱心的回答 ~

也可以試試 puts [join [lindex $hf] :]

葡萄汁 | 2014年12月15日 上午11:07

請問怎麼在tcl中呼叫minicom ?

mirrownight | 2016年10月16日 下午11:06

您好,感謝您寫出這麼淺顯易懂的教學文章!!

留下您的意見

Theme Design by devolux.org. Converted by Wordpress To Blogger for WP Blogger Themes. Sponsored by iBlogtoBlog
This template is brought to you by : allblogtools.com | Blogger Templates