組合方塊(combobox)是同時具備單行輸入方塊及清單方塊兩種特性的視窗元件,使用者可以在組合方塊裡直接輸入文字,或是由下拉清單中選取預設的項目。這一個章節介紹ttk組合方塊的使用方法。
30.1 建立組合方塊
如下是組合方塊的外觀,有一個文字輸入區,還有一個下拉清單方塊。使用者可以在文字輸入區輸入文字,也可以在下拉清單方塊中挑選預設提供的項目。圖 30-1
ttk可以使用combobox命令建立組合方塊,如下是一個簡單的範例:
請看到第5行,-values後面必需緊接著一個清單式的資料,這個清單中的項目會被顯示在組合方塊的下拉清單方塊中。-textvariable的使用方法和ttk::entry一樣,它後面可以指定一個變數名稱,用來反映目前組合方塊輸入區的文字內容。
執行結果如下:
圖 30-2
使用者可以直接輸入想吃的水果,或是由下拉清單中挑選預設的項目。這些預設項目可以讓使用者少打一些字。
30.2 存取文字輸入區
文字輸入區的內容除了可以使用-textvariable指定的變數存取之外,也可以用下列的方法:combobox的set命令可以用來設定文字輸入區的內容。上面的例子會把文字輸入區的內容設定為「西瓜」。而下方的程式,則會列印文字輸入區的內容。
30.3 使用範例
下面是一個常見的應用技巧,這個程式會在下拉清單中記住輸入區曾經使用過的內容。這個程式把組合方塊綁定了Return事件,就是使用者按下鍵盤的Enter時,後方大括號裡的程式就會被執行。當事件觸發的時候,程式取出下拉清單中所有的項目,然後查看目前輸入區的內容,是否出現在這些項目中,如果沒有的話,就把目前輸入區的內容插入下拉清單的開頭,如此一來程式就會在下拉清單中自動記錄使用者曾經輸入的內容。
下面是另一個組合方塊的例子,它示範動態建立下拉清單項目的方法:
這個程式的重點在第3行的-postcommand選項,它就類似ttk::button的-command選項,指定給它的程式碼會在下拉清單顯示時被執行,也可以說是使用者在按下組合方塊右方的向下按鈕時就會執行。在這個例子裡,我把目前工作路徑下的檔案及目錄都掃進下拉清單,所以在不同的工作路徑下執行這個程式,下拉清單中的項目就會有不同的內容。
圖 30-3
上圖顯示了我的家目錄下所有的內容,因為我在家目錄下執行了這個程式。
30.4 常用選項
以下是其它常用的選項,有興趣的朋友請自己試看看吧!!-height | 指定組合方塊的高度 |
-justify | 指定文字對齊的方式,它的值可以是left、right或center。 |
-width | 指定組合方塊的寬度。 |
圓鈕方塊也提供了cget及configure等標準的視窗元件命令,它們的用法請參考這一章的說明。
按右上方的「#」號切換側邊欄
17 個意見
米粒 | 2009年12月18日 清晨7:06
簡單易懂
程式碼有項目數字耶~~~
下次再好好問你怎用出來的
dai | 2009年12月18日 上午11:17
其實在網誌的原始文件裡,並沒有為程式碼加入行號。那些行號是我用javascript幫它們自動加上的~也就是說行號是網誌載入時,程式動態產生的。哈~~我太懶了。
翊翾 | 2010年1月12日 下午5:04
Dai你好^^~
因為postcommand是拉下選單馬上被執行
如果我想拉下清單點選裡面的變數之後
再執行另外一個副程式,不知道有無這指令?
還是就只有postcommand可以使用了...?
請Dai给個寶貴的意見^^~
dai | 2010年1月12日 下午6:00
請試試下面的範例:
ttk::combobox .cmb -values "1 2 3"
bind .cmb <> {puts [.cmb get]}
pack .cmb
翊翾 ~~ 你真是有禮冒的好孩子 @@
翊翾 | 2010年1月12日 下午6:33
那個.....我有個疑問
bind 中不用給條件嗎?
^^被Dai稱讚了耶~
dai | 2010年1月12日 晚上7:11
抱歉!! 忘記把角號換成html的語法,所以角號裡的內容顯示不出來
ttk::combobox .cmb -values "1 2 3"
bind .cmb <ComboboxSelected> {puts [.cmb get]}
pack .cmb
這個當然是要大大的稱讚一番~~如果人人都像你一樣的有禮貌,世界一定會更美好~呵呵 值得效法 ~ 值得效法 ~
翊翾 | 2010年1月13日 上午9:39
^^Dai我試出來囉
正是我要的功能呢~
不過用法可能要稍微改變一下
bind .cmb <> {puts [.cmb get]}
中間的<>要多打一次,不然好像會一直說找不到這指令的說
感謝建議啦~又吸收了一點點功力啦(笑)
dai | 2010年1月13日 上午10:47
沒錯 ~~ 是要打兩次,我的html還是打錯了 哈哈。
匿名 | 2010年10月7日 下午4:06
我用了上面的(蘋果,西瓜,蕃茄)範例來練習一下,但是我有一個問題想請教一下,那就是當我在輸入文字區輸入中文後,它就會錯誤訊息"alloc invalid block...",但是如果輸入英文的話就沒有問題出現,我想請問一下為什麼會這樣的呢?
匿名 | 2010年10月8日 上午9:56
我的問題(打中文會有錯誤訊息)已經解決了。如果用8.5版本的話,就會有這個問題存在,我想可能是8.5版本的bug,後來我安裝8.6版本的話,問題就不會發生了。
匿名 | 2011年2月23日 下午3:58
30.3的第一個範例程式中
bind .cmb 應該改為bind .cmb
R要大寫
dai | 2011年2月27日 上午11:11
Hi 匿名的朋友,
已經修正了,謝謝哦!!
匿名 | 2013年12月11日 下午2:18
Hello dai,
我想將翊翾的例子,選了值之後存入變數,到combobox外再運算該怎麼做?
匿名 | 2013年12月12日 晚上7:11
像這樣
:ttk::combobox .cmb -values "1 2 3" -textvariable ::cmbVal
pack .cmb
從此以後你可以在程式的任何位置用 $::cmbVal 來取得combobox選中的值
Mike | 2014年12月23日 下午5:36
不好意思,又來麻煩Dai大大,我這邊又遇到一個問題,想請問一下要如何把舊的 label 給 unset 掉?(不知道可不可以這樣說?)
一個很簡單combobox選擇後顯示的程式,但只要重複選之後,就會說舊得已經存在。
proc test {op1} {
label .text -text $op1
place .text -x 0 -y 30
}
set list "A B C"
set var A
test A
::ttk::combobox .combo -values $list -textvariable var -state readonly
place .combo -x 0 -y 0
bind .combo <> {test [.combo get]}
似乎可以用configure可以來改設定,但若是今天有元件很多怎麼辦?也是要一個一個改嗎?
可不可再proc開頭就把所有設定給unset掉,然後讓我重新再來一次就好?
這好像是一個蠻笨的問題。
匿名 | 2014年12月24日 下午2:18
Hi Hu Mike,
我想你可以開一個LIST儲存已選擇的ELEMENT
匿名 | 2014年12月24日 下午2:48
tk widget 可以 destroy 例如
if {[winfo exists .text]} {destroy .text}
留下您的意見