#

圓鈕方塊是一種讓使用者多選一,而且確保選項間互斥的視窗元件。這一個章節介紹圓鈕方塊的建立及使用方法。另外為了慶祝剛裝好的ubuntu 9.10,所以這次程式範例都改成了Ubuntu下的快照,呵呵。

28.1 建立圓鈕方塊

在建立圓鈕方塊之前,我們要先說明一個「分組」的觀念,其意義就是,如果多個圓鈕方塊被分類在同一組,那麼Tk會確保同一組的圓鈕方塊中永遠只有一個會被選中。下面是一個建立方塊及分組的例子:

001
002
003
ttk::radiobutton .r1 -text "男生" -value 1 -variable ::sex
ttk::radiobutton .r2 -text "女生" -value 0 -variable ::sex
pack .r1 .r2

這個例子總共建立了2個圓鈕方塊,如果使用者點選了男生,那麼::sex變數會被設定為1(男生後面-value指定的值),如果選了女生::sex會被設定為0(女生後面-value指定的值)。這邊的重點在於,如果多個圓鈕方塊的-variable選項指定了相同的變數名稱,這樣的話Tk會自動把這些圓鈕方塊分為一組,然後確保使用者只能在這些圓鈕方塊中選中1個。所以這個例子執行起來就像下面的圖一樣,使用者永遠只能在兩個圓鈕中點選其中之一。

圖 28-1


注意哦!!如果沒有設定::sex的初始值,那麼初始的情況下沒有任何一個圓鈕會被選中的。如果你希望把女生當為預設值的話,可以這樣做:

001
002
003
004
set ::sex 0
ttk::radiobutton .r1 -text "男生" -value 1 -variable ::sex
ttk::radiobutton .r2 -text "女生" -value 0 -variable ::sex
pack .r1 .r2

很簡單只要把::sex設定為0就可以了。想當然的,如果把::sex設定為1,這樣的話預設值就會變為男生。

□ 使用範例

現在我們用一個簡單的例子來說明圓鈕方塊的使用方法,這個例子長得像下面的樣子:

圖 28-2


圖上的「查看狀態」每按一下就會輸出圓鈕方塊選中的項目值。而「回復初值」會把圓鈕方塊還原為原始的選取狀態。程式碼如下:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
ttk::label .lbl1 -text "你的性別是:"
ttk::radiobutton .rdo1 -text "男生" -value 1 -variable ::sex
ttk::radiobutton .rdo2 -text "女生" -value 0 -variable ::sex

ttk::label .lbl2 -text "最愛的程式語言是:"
ttk::radiobutton .rdo3 -text "Tcl" -value 1 -variable ::lang
ttk::radiobutton .rdo4 -text "踢扣" -value 2 -variable ::lang

ttk::button .btn1 -text "查看狀態" -command {
 puts "性別:$::sex"
 puts "語言:$::lang"
}

ttk::button .btn2 -text "回復初值" -command {
 set ::sex 1
 set ::lang 2 
}

set ::sex 1
set ::lang 2 

grid .lbl1 .rdo1 .rdo2 -sticky "news" -padx 2 -pady 2
grid .lbl2 .rdo3 .rdo4 -sticky "news" -padx 2 -pady 2
grid .btn1 .btn2 -sticky "news" -padx 2 -pady 2

正常的情況下你應該看得懂上面的每一行程式,如果你覺得有陌生的地方,請試試複習先前的文章。

□ 其它常用選項

以下是其它常用的選項,有興趣的朋友請自己試看看吧!!

-image 設定圓鈕方塊後面的圖示。
-compound 指定圖示及文字內容的排列方式。
-textvariable 這個選項可以指定一個變數來即時反應圓鈕後面的文字內容。

圓鈕方塊也提供了cget及configure等標準的視窗元件命令,它們的用法請參考這一章的說明。

12 個意見

小燕鷗 | 2009年11月28日 晚上7:04

我是一個在學Tcl/Tk的人,希望能與你聯絡上(一直找不到你的聯絡方式)。
有許多問題想像你求教。
謝謝......

Dai | 2009年11月28日 晚上7:49

嗯~~你可以直接在網誌留下問題,如果我會的話,就會直接回應答案。

shawn.chen | 2010年6月22日 下午3:20

你好
不好意思可以請問一下嗎?
我的radio button分兩種類別區隔開
(確定一定要分兩次建立宣告,不能一口氣全部塞完)
x TEXTA ◆ TEXTB (建立A B的radiobutton)
x TEXT1 x TEXT2 (建立 1 2的radiobutton)
我想做到的情況是 "能被選到的是只有一個"

但實際上的卻是被選到的有兩個
如下面所示:
x TEXTA ◆ TEXTB
◆ TEXT1 x TEXT2
我希望做到的是像最上面的那一種四選一
而不是下面這種的四選二的情況
請問這樣你辦法幫我解決我的疑問嗎?
謝謝!!

dai | 2010年6月23日 凌晨12:02

可以的 請看下面的範例:

ttk::radiobutton .rdo1 -text "TEXTA" -value 1 -variable ::var
ttk::radiobutton .rdo2 -text "TEXTB" -value 0 -variable ::var

ttk::radiobutton .rdo3 -text "TEXT1" -value 2 -variable ::var
ttk::radiobutton .rdo4 -text "TEXT2" -value 3 -variable ::var

grid .rdo1 .rdo2
grid .rdo3 .rdo4

shawn.chen | 2010年6月23日 上午9:26

我問完問題 看到你的解答後
又回到文章的最開頭就知道為什麼了囧
我應該要先看完這篇文章
也許我就不會提這個鳥問題了
這題的解答是 -variable 變數設成相同 就分為同一組
總之 謝謝你的回覆
這個blog平台真是太棒了!!

豬事大吉 | 2010年9月23日 下午6:15

如果我的TCL/TK介面提供三種功能(a,b,c)給使用者選取
其中功能b是使用了radio button進行3選1
但是當使用者選了3選1中的1個後,又突然不想使用這個功能b
想改用功能a,請問是否有辦法取消radio button的選擇

sam | 2010年9月24日 下午6:01

Hi大吉:

請問你的意思是想要讓三個radio button都呈現"未選取"的狀態嗎?
如果是的話只要指定一個不存在的數就可以了。
(如圖28-2的例子)
ttk::button .btn2 -text "回復初值" -command {
set ::sex -1
set ::lang -1
}

豬事大吉 | 2010年9月28日 下午1:30

TO: sam

不是~~~不過我已經找到解法
.radiobutton1 deselect

謝謝!

匿名 | 2010年11月16日 晚上9:11

Dai 你好,
我的script如下,

set w .radio
catch {destroy $w}
toplevel $w
label $w.msg -text "Select one "
pack $w.msg -side top

frame $w.button
pack $w.button -side bottom -fill x -pady 2m
button $w.button.ok -text OK -command {
puts stdout "chk=$chk"
destroy $w
exit
}
pack $w.button.ok -side bottom

frame $w.select
pack $w.select -side left -expand yes -pady .5c -padx .5c

set i {{for XX to XX} {For OO to OO}}
foreach k {a b} {
set k1 [lsearch {a b} $k]
set k2 [lindex $i $k1]
set k3 [string toupper $k]
radiobutton $w.select.$k -text "$k3 $k2" -variable chk \
-relief flat -value $k3
pack $w.select.$k -side top -pady 2 -anchor w
}

如果我單獨執行的話,可以得到我要的值($chk=a or b);但我把這段寫進我的程式中,不論是寫成procedure或寫在主程式中似乎都得不到我要的值;應該是有執行但tk的畫面並沒有跑出來,能否幫我
看問題是出在哪嗎?謝謝.(寫在proc時已把exit mark起來了)

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

hi

嗯~這樣該是名稱空間的問題,請你把chk改成::chk,把$chk改成$::chk就可以了。

Unknown | 2014年6月19日 晚上9:42

dai 大你好,

我有一個問題 ,現在我使用了radiobutton ,有兩個選項如下

● None (label)
○ _______ 口 ( 一個 entry + 一個 button)

如果我選了 label 的話,那麼我希望 entry 和 button 是無法使用的
選擇了下面的之後,才可以填入值,以及使用 button
使用 button 是選擇選擇檔案,選擇的檔案路徑會把值填入到 entry 裡面。

這有點小小的複雜,不知道要如何著手,再麻煩您了

匿名 | 2014年6月20日 中午12:39

首先把entry及button放在同一個frame裡面(frameA)

然後在第1個radiobutton的 -command 命令中,設定frameA的狀態為disabled
然後在第2個radiobutton的 -command 命令中,設定frameA的狀態為 !disabled

這樣應該就可以了

留下您的意見

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