跳轉至內容

Tcl 程式設計/Tk

來自 Wikibooks,開放世界的開放書籍

Tk(工具包)是用於在 Macintosh、Unix/Linux 或 Windows 作業系統上設計圖形使用者介面 (GUI) 最流行的 Tcl 擴充套件。

只需少量努力,就可以組合出有用的

  • 視窗(表單,有些人稱之為)由
  • 部件組成,這些部件由
  • 幾何管理器管理。此外,您可以輕鬆定義
  • 滑鼠或鍵盤事件的繫結以觸發您想要的動作。

示例:計算器

[編輯 | 編輯原始碼]

這是一個非常簡單、完整的 Tcl/Tk 指令碼,實現了計算器

package require Tk
pack [entry .e -textvar e -width 50]
bind .e <Return> {
   set e  [regsub { *=.*} $e ""] ;# remove evaluation (Chris)
   catch {expr [string map {/ *1./} $e]} res
   append e " = $res"
} 

它建立了一個名為 .e輸入框部件,您可以在其中從鍵盤輸入,並關聯一個變數 e(它將反映輸入框的內容),並使用 pack 管理它。

定義了一個繫結:如果鍵盤焦點在 .e 上,並且按下 <Return> 鍵,則

  • 變數 e 中的所有除法運算子 (/) 都會對映到 "*1./"(這強制進行浮點除法),
  • 將生成的字串提供給 expr 以將其評估為算術/邏輯表示式
  • 由於使用者輸入中可能存在錯誤,因此 expr 呼叫被包裝在 catch 中,該 catchexpr 的結果或發生的錯誤訊息分配給變數 res
  • 最後一次評估的結果透過刪除 = 後面的所有內容來清除
  • 最後,一個等號和 res 變數的值被 appende 中,使輸入和結果立即在輸入框中可見。

示例:一個微型 IRC 客戶端

[編輯 | 編輯原始碼]

與之前 Tcl 部分一樣,這裡再次提供了一個可執行的小指令碼:一個 38 行程式碼的 IRC(網際網路中繼聊天)客戶端,它具有 文字框輸入框部件

package require Tk
set ::server irc.freenode.org
set ::chan   #tcl
set ::me     $tcl_platform(user)
text .t -height 30 -wrap word -font {Arial 9}
.t tag config bold   -font [linsert [.t cget -font] end bold]
.t tag config italic -font [linsert [.t cget -font] end italic]
.t tag config blue   -foreground blue
entry .cmd
pack .cmd -side bottom -fill x
pack .t -fill both -expand 1
bind .cmd <Return> post
proc recv {} {
    gets $::fd line
    if {[regexp {:([^!]*)![^ ].* +PRIVMSG ([^ :]+) +:(.*)} $line -> \
        nick target msg]} {
        set tag ""
        if [regexp {\001ACTION(.+)\001} $msg -> msg] {set tag italic}
        if [in {azbridge ijchain} $nick] {regexp {<([^>]+)>(.+)} $msg -> nick msg}
       .t insert end $nick\t bold $msg\n $tag
    } else {.t insert end $line\n italic}
    .t yview end
}
proc in {list element} {expr {[lsearch -exact $list $element]>=0}}
proc post {} {
    set msg [.cmd get]
    if [regexp {^/me (.+)} $msg -> action] {set msg "\001ACTION $action\001"}
    foreach line [split $msg \n] {send "PRIVMSG $::chan :$line"}
    .cmd delete 0 end
    set tag ""
    if [regexp {\001ACTION(.+)\001} $msg -> msg] {set tag italic}
    .t insert end $::me\t {bold blue} $msg\n [list blue $tag]
    .t yview end
}
proc send str {puts $::fd $str; flush $::fd}
set ::fd [socket $::server 6667]
send "NICK $::me"
send "USER $::me 0 * :PicoIRC user"
send "JOIN $::chan"
fileevent $::fd readable recv
bind . <Escape> {exec wish $argv0 &; exit}

最後一行是一個快速除錯助手:如果您在編輯器中修改了指令碼,儲存到磁碟,然後在應用程式中按下 <Escape> 以重新啟動它。

部件是 GUI 物件,當由幾何管理器對映時,對應於螢幕上的一個矩形區域,具有不同的屬性和功能。

部件使用路徑名稱命名,有點類似於檔案系統路徑名稱,只是部件的分隔符是句點“.”。例如,.foo.barfoo 的子部件,而 foo 是“.”的子部件。父子關係通常發生在容器中,例如 頂級視窗、框架、畫布、文字框。名稱部分(即句點之間的部分)幾乎可以是任何不包含“.”的字串,或者不以大寫字母開頭(這是因為以大寫字母開頭的部件類名稱具有特殊含義,它們表示類範圍的選項)。

如果您有一個接受父部件 w 並新增子部件的過程,區分 w 是“.”還是其他部件可能很重要 - 因為您不能將子部件名稱直接連線到“.” - 如果 $w == “.”,則 $w.kid 將生成無效名稱。以下是如何避免這種情況

set w2 [expr {$w eq "."? "": $w}]
button $w2.$kid ...

部件由以其類命名的命令建立,然後獲取路徑名稱(要求父部件在那時必須存在)和任意數量的-key value選項,這些選項構成初始配置,例如

button .b -text "Hello!" -command {do something}

建立後,與部件的通訊透過對應於其名稱的建立命令進行。例如,可以查詢配置選項

set text [.b cget -text]

或更改

.b configure -text Goodbye! -background red

一些“方法”,如 cget、configure 對所有部件類都是通用的,其他方法則特定於一個或幾個部件類。例如,文字框輸入框都接受 insert 方法。有關所有詳細資訊,請參閱手冊頁。

部件僅在被提供給幾何管理器後才會顯示在螢幕上(請參閱下面的更多資訊)。示例

text .t -wrap word
pack .t -fill both -expand 1

由於部件建立命令返回路徑名稱,因此這兩個步驟也可以巢狀,例如

pack [text .t -wrap word] -fill both -expand 1

destroy 命令刪除一個部件及其所有子部件(如果存在)

destroy .b

以下子章節描述了 Tk 中可用的部件。


帶有文字和/或影像,單擊時呼叫可配置的命令。示例

button .b -text Hello! -command {puts "hello, world"}

用於線條、矩形、多邊形、橢圓和文字項以及點陣圖和照片影像以及整個嵌入式視窗的可滾動圖形表面。例如,請參閱下面的“微型繪圖程式”。示例

pack [canvas .c -background white]
.c create line 50 50 100 100 150 50 -fill red -width 3
.c create text 100 50 -text Example

平移畫布(在視窗內使用滑鼠中鍵按住的情況下滾動它)透過繼承文字部件繫結

 bind .c <2> [bind Text <2>]
 bind .c <B2-Motion> [bind Text <B2-Motion>]

輸入框

[編輯 | 編輯原始碼]

單行可編輯文字欄位,水平可滾動(請參閱上面的示例)。您可以指定驗證函式來約束輸入的內容。示例

entry .e -width 20 -textvariable myVar
set myVar "this text appears in the entry"


多個部件的容器,通常與 pack 一起使用,或用於包裝“Megawidgets”

用於文字顯示的一行或多行欄位,可以繫結到文字變數以在該變數更改時更新。換行符由要顯示的文字中的 \n 指定。

標籤框架

[編輯 | 編輯原始碼]

類似於框架的容器,周圍裝飾有細矩形,左上角位置有一個標籤。示例(一個微型無線電波段選擇器)

pack [labelframe .lf -text Band]
pack [radiobutton .lf.am -text AM -variable band -value AM]
pack [radiobutton .lf.fm -text FM -variable band -value FM]
set band AM

列表框

[編輯 | 編輯原始碼]

列表的多行顯示,可滾動。可以使用滑鼠選擇單個或多個專案。

要向GUI應用程式新增選單,需要分三步操作

  • 建立頂層水平選單(只需一次)
. configure -menu [menu .m]
  • 對於頂層選單中的每個專案,建立一個級聯子選單,例如:
.m add cascade -label File -menu [menu .m.mFile]
  • 對於子選單中的每個條目,像這樣新增它:
.m.mFile add command -label Open -command {openFile ...}
.m.mFile add separator

由於這些命令有點冗長,可以將它們包裝到一個小的輔助函式中

proc m+ {head name {cmd ""}} {
   if {![winfo exists .m.m$head]} {
        .m add cascade -label $head -menu [menu .m.m$head -tearoff 0]
   }
   if [regexp ^-+$ $name] {
           .m.m$head add separator
   } else {.m.m$head add command -label $name -comm $cmd}
}

演示示例 - 現在選單項可以用更清晰的方式建立了

. configure -menu [menu .m]
m+ File Open {.t insert end "opened\n"}
m+ File Save {.t insert end "saved\n"}
m+ File -----
m+ File Exit exit
m+ Edit Cut ...
pack [text .t -wrap word] -fill both -expand 1

單選按鈕

[編輯 | 編輯原始碼]

帶選擇欄位的按鈕,可以處於開啟或關閉狀態,並帶有一個標籤。用滑鼠點選選擇欄位會更改關聯的全域性變數的值。通常,多個單選按鈕會繫結到同一個變數。例如,請參見上面的標籤框架

水平或垂直捲軸(預設情況下為垂直,對於水平,指定:-orientation horizontal,或者如果您喜歡簡短的寫法,則使用 -ori hori)可以繫結到畫布、輸入框、列表框或文字小部件。捲軸與其滾動小部件之間的互動透過回撥函式實現,其中一個通知另一個。

  • 捲軸到小部件:xviewyview 方法
  • 小部件到捲軸:set 方法

當回撥函式被呼叫時,這些方法的引數將被自動新增。

例如,以下是將文字小部件與垂直捲軸連線的方法:

pack [scrollbar .y -command ".t yview"] -side right -fill y
pack [text .t -wrap word -yscrollc ".y set"] \
     -side right -fill both -expand 1

對於大多數小部件,捲軸會自動調整到小部件的內容。對於畫布小部件,您需要在新增新專案後更新滾動區域。最簡單的方法如下:

$canvas configure -scrollregion [$canvas bbox all]

可滾動的可編輯多行文字,具有許多格式選項。還可以包含影像和嵌入式小部件。預設換行設定是“none”,因此您可能需要水平捲軸才能檢視所有長行。在許多情況下,將文字小部件配置為-wrap word 會更友好 - 這樣您最多隻需要一個垂直捲軸。

文字小部件中的位置指定為行.列,其中行從1開始,列從0開始,因此1.0是文字小部件中的第一個字元。如何刪除所有內容的示例:

$t delete 1.0 end

要突出顯示部分內容,可以定義標籤並將它們分配給子序列

$t tag configure ul -underline 1
$t insert end "The next word is " {} underlined ul ", the rest is not."

頂層視窗

[編輯 | 編輯原始碼]

獨立的框架視窗,主要帶有視窗管理器提供的裝飾(標題欄、按鈕)。當您啟動Tk時,會收到一個名為“.”(一個點)的初始空頂層視窗。如果您想要更多頂層視窗,可以像這樣建立它們:

toplevel .mySecondWindow

這些頂層視窗在邏輯上是“.”的子視窗。要為頂層視窗分配一個好的標題,請使用:

wm title $toplevel "This is the title"

您還可以使用以下方法控制頂層視窗的幾何形狀(大小和位置):

wm geometry $toplevel ${width}x$height+$x+$y

幾何管理器

[編輯 | 編輯原始碼]

幾何管理器的目的是計算小部件所需的高度、寬度和位置,並將其對映到螢幕上。除了gridpackplace 之外,canvastext 小部件也可以管理嵌入式小部件。

對幾何管理器的呼叫總是以管理器的名稱開頭,然後(大多)是一個或多個小部件名稱,然後是任意數量的-name value選項

網格佈局

[編輯 | 編輯原始碼]

此幾何管理器最適合用於由行和列組成的表格窗口布局。例如,要將三個小部件放在水平行中:

grid .1 .2 .3 -sticky news

-sticky 選項指示小部件應貼上到其框的哪一邊,以羅盤方向表示;“news”表示北-東-西-南”,即所有四面。

以下是在網格中顯示錶格(列表的列表)的最小解決方案:

package require Tk
proc table {w content args} {
    frame $w -bg black
    set r 0
    foreach row $content {
        set fields {}
        set c 0
        foreach col $row {
            lappend fields [label $w.$r/$c -text $col]
            incr c
        }
        eval grid $fields -sticky news -padx 1 -pady 1
        incr r
    }
    set w
}
#--- Test:
table .t {
   {Row Head1 Head2}
   {1   foo   42}
   {2   bar   1234}
   {3   grill testing}
}
pack .t
#--- Changing the contents, given row and column number:
after 2000 .t.3/2 config -text Coucou

填充佈局

[編輯 | 編輯原始碼]

這曾經是主力管理器,但在最近幾年,它的流行度不如網格佈局。無論如何,它仍然適用於您只需要在一個方向(水平或垂直)上對齊小部件的情況。對於更復雜的佈局,過去常常插入中間框架,但網格佈局使這些工作變得更容易。示例:

pack .x -fill both -expand 1 -side left

定位佈局

[編輯 | 編輯原始碼]

此幾何管理器不常使用,主要用於特殊應用程式,例如當您想要突出顯示選項卡筆記本的當前選項卡時。它允許以畫素為單位精確放置小部件,但在響應頂層視窗或內部小部件的大小調整方面不太動態。

對話方塊

[編輯 | 編輯原始碼]

對話方塊是用於顯示訊息或詢問問題的頂層視窗。您不必為它們分配小部件路徑名稱。只需像呼叫函式一樣呼叫它們並評估結果(如果對話方塊被取消,通常為“”)。

tk_getOpenFile

[編輯 | 編輯原始碼]

檔案選擇器對話方塊(僅限於現有檔案)。返回帶有路徑名稱的選擇檔案,如果取消則返回“” 。

tk_getSaveFile

[編輯 | 編輯原始碼]

檔案選擇器對話方塊,它也允許指定不存在的檔案。返回帶有路徑名稱的選擇檔案,如果取消則返回“” 。

tk_messageBox

[編輯 | 編輯原始碼]

一個簡單的對話方塊,顯示一個字串,可以用“確定”按鈕關閉。示例:

tk_messageBox -message "hello, world!"

tk_chooseColor

[編輯 | 編輯原始碼]

顯示顏色選擇對話方塊。返回值是根據Tcl對這類資訊的理解,以某種表示形式呈現的選擇顏色;在Microsoft Windows系統上,這可能是一個“#RRGGBB”格式的十六進位制字串。在終止該過程時,將傳遞空字串。可以透過“-initialcolor”選項配置對話方塊以預選特定的預設顏色,透過“-parent”配置到父小部件的從屬關係,以及透過“-title”配置標題。

 tk_chooseColor -initialcolor #FF0000 -parent . -title "What tincture do you wish?"

自定義對話方塊

[編輯 | 編輯原始碼]

除了Tk自帶的預製對話方塊外,構建自定義對話方塊也不太難。作為一個非常簡單的例子,這裡有一個“值對話方塊”,提示使用者輸入一個值:

proc value_dialog {string} {
   set w [toplevel .[clock seconds]]
   wm resizable $w 0 0
   wm title $w "Value request"
   label  $w.l -text $string
   entry  $w.e -textvar $w -bg white
   bind $w.e <Return> {set done 1}
   button $w.ok     -text OK     -command {set done 1}
   button $w.c      -text Clear  -command "set $w {}"
   button $w.cancel -text Cancel -command "set $w {}; set done 1"
   grid $w.l  -    -        -sticky news
   grid $w.e  -    -        -sticky news
   grid $w.ok $w.c $w.cancel
   vwait done
   destroy $w
   set ::$w
}

測試

set test [value_dialog "Give me a value please:"]
puts test:$test
pack [ label .l -text "Value: '$test' " ]

對於更復雜的示例,這裡有一個記錄編輯器對話方塊(多個欄位,每個欄位都有一個標籤和輸入框(或用於多行輸入的文字)):

proc editRecord {title headers fields} {
    set oldfocus [focus]
    set w [toplevel .[clock clicks]]
    wm resizable $w 1 0
    wm title $w $title
    set n 0
    foreach h $headers f $fields {
        if ![regexp {(.+)([=+])} $h -> hdr type] {set hdr $h; set type ""}
        label $w.h$n -text $hdr -anchor ne
        switch -- $type {
            = {label $w.e$n -width [string length $f] -text $f -anchor w -bg white}
            + {[text $w.e$n -width 20 -height 6] insert end $f}
            default {[entry $w.e$n -width [string length $f]] insert end $f}
        }
        grid $w.h$n $w.e$n -sticky news
        incr n
    }
    button $w.ok -text OK -width 5 -command [list set $w 1]
    button $w.cancel -text Cancel -command [list set $w 0]
    grid $w.ok $w.cancel -pady 5
    grid columnconfigure $w 1 -weight 1
    vwait ::$w
    if [set ::$w] { #-- collect the current entry contents
        set n 0
        foreach h $headers f $fields {
            regexp {([^=+].+)([=+]?)} $h -> hdr type
            switch -- $type {
                "" {lappend res [$w.e$n get]}
                =  {lappend res [$w.e$n cget -text]}
                +  {lappend res [$w.e$n get 1.0 end]}
            }
            incr n
        }
    } else {set res {}}
    destroy $w
    unset ::$w ;#-- clean up the vwait variable
    focus $oldfocus
    return $res
}

快速測試

editRecord Test {foo= bar grill+} {one two three}

輕鬆建立巨型小部件

[編輯 | 編輯原始碼]

術語“巨型小部件”常用於複合小部件,它們本身包含其他小部件,儘管它們的數量幾乎不會達到一百萬(字首Mega-所暗示的),子小部件的數量通常不會超過十個。

要建立巨型小部件,需要一個與Tk小部件建立命令具有相同簽名的過程。當此過程被呼叫時,它將建立一個以小部件命名的另一個過程,並將方法分派到特定的處理程式或Tk建立的通用小部件命令。

一個小筆記本

[編輯 | 編輯原始碼]

普通的 Tk 沒有包含“筆記本”控制元件,它沒有頂部帶標籤的選項卡,可以切換顯示不同的“頁面”,但是很容易自己做一個。這個例子演示瞭如何用框架中的按鈕實現選項卡,以及如何“過載”以框架命名的原始 Tk 命令,使其能夠接收額外的新增切換方法。

proc notebook {w args} {
   frame $w
   pack [frame $w.top] -side top -fill x -anchor w
   rename $w _$w
   proc $w {cmd args} { #-- overloaded frame command
       set w [lindex [info level 0] 0]
       switch -- $cmd {
           add     {notebook'add   $w $args}
           raise   {notebook'raise $w $args}
           default {eval [linsert $args 0 _$w $cmd]}
       }
   }
   return $w
}
proc notebook'add {w title} {
   set btn [button $w.top.b$title -text $title -command [list $w raise $title]]
   pack $btn -side left -ipadx 5
   set f [frame $w.f$title -relief raised -borderwidth 2]
   pack $f -fill both -expand 1
   $btn invoke
   bind $btn <3> "destroy {$btn}; destroy {$f}" ;# (1)
   return $f
}
proc notebook'raise {w title} {
   foreach i [winfo children $w.top] {$i config -borderwidth 0}
   $w.top.b$title config -borderwidth 1
   set frame $w.f$title
   foreach i [winfo children $w] {
       if {![string match *top $i] && $i ne $frame} {pack forget $i}
   }
   pack $frame -fill both -expand 1
}

測試和演示程式碼

package require Tk
pack [notebook .n] -fill both -expand 1
set p1 [.n add Text]
pack   [text $p1.t -wrap word] -fill both -expand 1
set p2 [.n add Canvas]
pack   [canvas $p2.c -bg yellow] -fill both -expand 1
set p3 [.n add Options]
pack   [button $p3.1 -text Console -command {console show}]
.n raise Text
wm geometry . 400x300

繫結事件

[編輯 | 編輯原始碼]

Tcl/Tk 中的事件包括使用者執行的操作,例如按下按鍵或單擊滑鼠。要對滑鼠和鍵盤活動做出反應,可以使用 bind 命令。如計算器示例所示。

 pack [entry .e -textvar e -width 50]
 bind .e <Return> {

bind 關鍵字作用於 .e 並將事件與 <return> 事件相關聯。下面的括號表示一組過程的開始,當事件發生時執行這些過程。

BWidget 是一個用純 Tcl 編寫的 Tk 擴充套件(因此它甚至可以在 Windows Mobile 驅動的手機上執行)。它提供了巨型控制元件(所有類名都以大寫字母開頭),例如

  • 組合框
  • 筆記本
  • 樹形控制元件

在 Windows/CE 下的 PocketPC 上,筆記本和樹形控制元件的螢幕截圖

樹形控制元件示例

[編輯 | 編輯原始碼]

這是一個樹形控制元件的“Hello World”示例(這是一個完整的指令碼)。根節點始終稱為root,對於其他節點,您需要自己命名。

package require BWidget
pack [Tree .t]
.t insert end root n1  -text hello
.t insert end root n2  -text world
.t insert end n2   n21 -text (fr:monde)
.t insert end n2   n22 -text (de:Welt)

著名的打字測試句子表示為語法樹

package require BWidget
pack [Tree .t -height 16] -fill both -expand 1
foreach {from to text} {
   root S S
   S   np1  NP
   S   vp   VP
   np1 det1 Det:The
   np1 ap1  AP
   ap1 adj1 Adj:quick
   ap1 adj2 Adj:brown
   ap1 n1   N:fox
   vp  v    V:jumps
   vp  pp   PP
   pp  prep Prep:over
   pp  np2  NP
   np2 det2 Det:the
   np2 ap2  AP
   ap2 adj3 Adj:lazy
   ap2 n2   N:dog
   
} {.t insert end $from $to -text $text}
.t opentree S

Tk 資源

[編輯 | 編輯原始碼]

Tk 中的顏色可以透過三種方式指定

  • 符號名稱,例如:紅色 綠色 藍色 黃色 品紅 青色
  • 以 # 開頭的十六進位制字串:#RGB、#RRGGBB、#RRRRGGGGBBBB
  • 三個非負整數的列表

最後一種形式僅由命令返回。要為命令指定顏色,您需要將其格式化為十六進位制。例如,白色可以描述為 #FFFFFF。

將符號名稱轉換為其 RGB 分量

winfo rgb . $colorname

以下是定義的顏色名稱列表(來自 X11 的 rgb.txt)

set COLORS { snow {ghost white} {white smoke} gainsboro {floral white}
   {old lace} linen {antique white} {papaya whip} {blanched almond}
   bisque {peach puff} {navajo white} moccasin cornsilk ivory {lemon
   chiffon} seashell honeydew {mint cream} azure {alice blue}
   lavender {lavender blush} {misty rose} white black {dark slate
   gray} {dim gray} {slate gray} {light slate gray} gray {light grey}
   {midnight blue} navy {cornflower blue} {dark slate blue} {slate
   blue} {medium slate blue} {light slate blue} {medium blue} {royal
   blue} blue {dodger blue} {deep sky blue} {sky blue} {light sky
   blue} {steel blue} {light steel blue} {light blue} {powder blue}
   {pale turquoise} {dark turquoise} {medium turquoise} turquoise
   cyan {light cyan} {cadet blue} {medium aquamarine} aquamarine
   {dark green} {dark olive green} {dark sea green} {sea green}
   {medium sea green} {light sea green} {pale green} {spring green}
   {lawn green} green chartreuse {medium spring green} {green yellow}
   {lime green} {yellow green} {forest green} {olive drab} {dark
   khaki} khaki {pale goldenrod} {light goldenrod yellow} {light
   yellow} yellow gold {light goldenrod} goldenrod {dark goldenrod}
   {rosy brown} {indian red} {saddle brown} sienna peru burlywood
   beige wheat {sandy brown} tan chocolate firebrick brown {dark
   salmon} salmon {light salmon} orange {dark orange} coral {light
   coral} tomato {orange red} red {hot pink} {deep pink} pink {light
   pink} {pale violet red} maroon {medium violet red} {violet red}
   magenta violet plum orchid {medium orchid} {dark orchid} {dark
   violet} {blue violet} purple {medium purple} thistle snow2 snow3
   snow4 seashell2 seashell3 seashell4 AntiqueWhite1 AntiqueWhite2
   AntiqueWhite3 AntiqueWhite4 bisque2 bisque3 bisque4 PeachPuff2
   PeachPuff3 PeachPuff4 NavajoWhite2 NavajoWhite3 NavajoWhite4
   LemonChiffon2 LemonChiffon3 LemonChiffon4 cornsilk2 cornsilk3
   cornsilk4 ivory2 ivory3 ivory4 honeydew2 honeydew3 honeydew4
   LavenderBlush2 LavenderBlush3 LavenderBlush4 MistyRose2 MistyRose3
   MistyRose4 azure2 azure3 azure4 SlateBlue1 SlateBlue2 SlateBlue3
   SlateBlue4 RoyalBlue1 RoyalBlue2 RoyalBlue3 RoyalBlue4 blue2 blue4
   DodgerBlue2 DodgerBlue3 DodgerBlue4 SteelBlue1 SteelBlue2
   SteelBlue3 SteelBlue4 DeepSkyBlue2 DeepSkyBlue3 DeepSkyBlue4
   SkyBlue1 SkyBlue2 SkyBlue3 SkyBlue4 LightSkyBlue1 LightSkyBlue2
   LightSkyBlue3 LightSkyBlue4 SlateGray1 SlateGray2 SlateGray3
   SlateGray4 LightSteelBlue1 LightSteelBlue2 LightSteelBlue3
   LightSteelBlue4 LightBlue1 LightBlue2 LightBlue3 LightBlue4
   LightCyan2 LightCyan3 LightCyan4 PaleTurquoise1 PaleTurquoise2
   PaleTurquoise3 PaleTurquoise4 CadetBlue1 CadetBlue2 CadetBlue3
   CadetBlue4 turquoise1 turquoise2 turquoise3 turquoise4 cyan2 cyan3
   cyan4 DarkSlateGray1 DarkSlateGray2 DarkSlateGray3 DarkSlateGray4
   aquamarine2 aquamarine4 DarkSeaGreen1 DarkSeaGreen2 DarkSeaGreen3
   DarkSeaGreen4 SeaGreen1 SeaGreen2 SeaGreen3 PaleGreen1 PaleGreen2
   PaleGreen3 PaleGreen4 SpringGreen2 SpringGreen3 SpringGreen4
   green2 green3 green4 chartreuse2 chartreuse3 chartreuse4
   OliveDrab1 OliveDrab2 OliveDrab4 DarkOliveGreen1 DarkOliveGreen2
   DarkOliveGreen3 DarkOliveGreen4 khaki1 khaki2 khaki3 khaki4
   LightGoldenrod1 LightGoldenrod2 LightGoldenrod3 LightGoldenrod4
   LightYellow2 LightYellow3 LightYellow4 yellow2 yellow3 yellow4
   gold2 gold3 gold4 goldenrod1 goldenrod2 goldenrod3 goldenrod4
   DarkGoldenrod1 DarkGoldenrod2 DarkGoldenrod3 DarkGoldenrod4
   RosyBrown1 RosyBrown2 RosyBrown3 RosyBrown4 IndianRed1 IndianRed2
   IndianRed3 IndianRed4 sienna1 sienna2 sienna3 sienna4 burlywood1
   burlywood2 burlywood3 burlywood4 wheat1 wheat2 wheat3 wheat4 tan1
   tan2 tan4 chocolate1 chocolate2 chocolate3 firebrick1 firebrick2
   firebrick3 firebrick4 brown1 brown2 brown3 brown4 salmon1 salmon2
   salmon3 salmon4 LightSalmon2 LightSalmon3 LightSalmon4 orange2
   orange3 orange4 DarkOrange1 DarkOrange2 DarkOrange3 DarkOrange4
   coral1 coral2 coral3 coral4 tomato2 tomato3 tomato4 OrangeRed2
   OrangeRed3 OrangeRed4 red2 red3 red4 DeepPink2 DeepPink3 DeepPink4
   HotPink1 HotPink2 HotPink3 HotPink4 pink1 pink2 pink3 pink4
   LightPink1 LightPink2 LightPink3 LightPink4 PaleVioletRed1
   PaleVioletRed2 PaleVioletRed3 PaleVioletRed4 maroon1 maroon2
   maroon3 maroon4 VioletRed1 VioletRed2 VioletRed3 VioletRed4
   magenta2 magenta3 magenta4 orchid1 orchid2 orchid3 orchid4 plum1
   plum2 plum3 plum4 MediumOrchid1 MediumOrchid2 MediumOrchid3
   MediumOrchid4 DarkOrchid1 DarkOrchid2 DarkOrchid3 DarkOrchid4
   purple1 purple2 purple3 purple4 MediumPurple1 MediumPurple2
   MediumPurple3 MediumPurple4 thistle1 thistle2 thistle3 thistle4
   gray1 gray2 gray3 gray4 gray5 gray6 gray7 gray8 gray9 gray10
   gray11 gray12 gray13 gray14 gray15 gray16 gray17 gray18 gray19
   gray20 gray21 gray22 gray23 gray24 gray25 gray26 gray27 gray28
   gray29 gray30 gray31 gray32 gray33 gray34 gray35 gray36 gray37
   gray38 gray39 gray40 gray42 gray43 gray44 gray45 gray46 gray47
   gray48 gray49 gray50 gray51 gray52 gray53 gray54 gray55 gray56
   gray57 gray58 gray59 gray60 gray61 gray62 gray63 gray64 gray65
   gray66 gray67 gray68 gray69 gray70 gray71 gray72 gray73 gray74
   gray75 gray76 gray77 gray78 gray79 gray80 gray81 gray82 gray83
   gray84 gray85 gray86 gray87 gray88 gray89 gray90 gray91 gray92
   gray93 gray94 gray95 gray97 gray98 gray99
}

此外,以下在 Windows 上定義

set WINDOWSCOLORS {
   SystemButtonFace SystemButtonText SystemDisabledText SystemHighlight
   SystemHightlightText SystemMenu SystemMenuText SystemScrollbar
   SystemWindow SystemWindowFrame SystemWindowText
}

對於每個控制元件,您可以指定滑鼠懸停在其上時游標的外觀。以下是定義的游標名稱列表

set cursors {
   X_cursor arrow based_arrow_down based_arrow_up boat bogosity
   bottom_left_corner bottom_right_corner bottom_side bottom_tee
   box_spiral center_ptr circle clock coffee_mug cross cross_reverse
   crosshair diamond_cross dot dotbox double_arrow draft_large draft_small
   draped_box exchange fleur gobbler gumby hand1 hand2 heart icon
   iron_cross left_ptr left_side left_tee leftbutton ll_angle lr_angle
   man middlebutton mouse pencil pirate plus question_arrow right_ptr
   right_side right_tee rightbutton rtl_logo sailboat sb_down_arrow
   sb_h_double_arrow sb_left_arrow sb_right_arrow sb_up_arrow
   sb_v_double_arrow shuttle sizing spider spraycan star target tcross
   top_left_arrow top_left_corner top_right_corner top_side top_tee 
   trek ul_angle umbrella ur_angle watch xterm
}

一個小工具,它顯示游標名稱,並在滑鼠懸停時顯示每個游標的形狀。

set ncols 4
for {set i 0} {$i<$ncols} {incr i} {
   lappend cols col$i
}
set nmax [expr {int([llength $cursors]*1./$ncols)}]
foreach col $cols {
   set $col [lrange $cursors 0 $nmax]
   set cursors [lrange $cursors [expr $nmax+1] end]
}
label .top -text "Move the cursor over a name to see how it looks" \
   -relief ridge
grid .top -columnspan $ncols -sticky news -ipady 2
for {set i 0} {$i<[llength $col0]} {incr i} {
   set row {}
   foreach col $cols {
       set name [lindex [set $col] $i]
       if {$name eq ""} break
       lappend row .l$name
       label .l$name -text $name -anchor w
       bind .l$name <Enter> [list %W config -cursor $name]
   }
   eval grid $row -sticky we
}

字型由視窗系統提供。哪些字型可用取決於本地安裝。使用以下命令查詢可用的字型:

font families

字型的典型描述最多包含三個元素的列表

family size ?style?

示例

set f {{Bitstream Cyberbit} 10 bold}

字體系列是一個名稱,例如 Courier、Helvetica、Times 等。最好選擇字體系列提供的名稱之一,儘管可能存在一些對映,例如“Helvetica” -> “Arial”。

大小是以磅為單位(印刷工的磅是 1/72 英寸)如果為正數,或以畫素為單位如果為負數。普通顯示字型的大小通常為 9 或 10。

樣式可以是零個或多個粗體、斜體、下劃線等列表。

影像:照片和點陣圖

Tk 允許對影像進行簡單但功能強大的操作。這些影像分為兩種:點陣圖和照片。點陣圖的功能相當有限,它們可以用 XBM 格式指定,並以可配置的顏色呈現。

照片的可能性要多得多 - 您可以使用不同的檔案格式載入和儲存它們(Tk 本身支援 PPM 和 GIF - 對於其他格式,請使用 Img 擴充套件),使用許多選項複製它們,例如縮放/二次取樣或映象,以及獲取或設定單個畫素的顏色。

設定還可以一次性處理矩形區域,以下示例演示瞭如何建立一個三色旗的照片影像(三個等間距的垂直條帶 - 如法國、義大利、比利時、愛爾蘭和許多其他國家)。預設值為法國。您可以指定寬度,高度將是寬度的 2/3。該過程返回影像名稱 - 只要儲存為 -format GIF 格式即可。

proc tricolore {w {colors {blue white red}}} {
   set im [image create photo]
   set fromx 0
   set dx [expr $w/3]
   set tox $dx
   set toy [expr $w*2/3]
   foreach color $colors {
       $im put $color -to $fromx 0 $tox $toy
       incr fromx $dx; incr tox $dx
   }
   set im
}
# Test - display flag on canvas:
pack [canvas .c -width 200 -height 200 -background grey]
.c create image 100 100 -image [tricolore 150]
# Test - save image of flag to file:
[tricolore 300] write tric.gif -format gif

除錯 Tk 程式

[編輯 | 編輯原始碼]

正在開發的 Tk 程式可以透過新增此類繫結來快速除錯

bind . <F1> {console show}

這僅適用於 Windows 和 Macintosh(OS-X 之前版本),並在其中您可以與 Tcl 直譯器互動,檢查或修改全域性變數,配置控制元件等的控制檯中彈出一個控制檯。

bind . <Escape> {eval [list exec wish $argv0] $argv &; exit}

這將啟動當前程式的新例項(假設您編輯了原始檔並將其儲存到磁碟),然後終止當前例項。

對於簡短的除錯輸出,還可以使用視窗的標題欄。例如,要顯示滑鼠移動時的當前滑鼠座標

bind . <Motion> {wm title . %X/%Y}

其他語言

[編輯 | 編輯原始碼]

其他程式語言有與 Tcl/Tk 介面並使用它的模組

  • 在 R(程式語言)中,有一個 tcltk 庫,使用命令library(tcltk)呼叫。
  • 在 Python 中,有一個 tkinter 模組,使用import tkinterfrom tkinter import *呼叫。
  • Common Lisp 可以通過幾個外部可用的庫與 Tcl/Tk 通訊,包括CL-TKLTK
華夏公益教科書