Tkinter 的 Radiobutton 元件是用來讓使用者單選 (多選一) 的選項元件.
本系列之前的文章參考 :
# Python 內建 GUI 模組 tkinter 測試 (一) : 建立視窗
# Python 內建 GUI 模組 tkinter 測試 (二) : 對話框
# Python 內建 GUI 模組 tkinter 測試 (三) : 版面管理員
Radiobutton 元件為一種選項元件, 用來從多個選項中選擇一個項目, 只能單選. 其語法如下 :
Radiobutton(父容器, **參數列)
此元件有 tk 與 ttk 版本.
參考 :
RadioButton 元件常用參數如下表 :
Radiobutton 常用參數 | 說明 |
value | 選項圓鈕之值, 用來區分不同之項目 |
variable | 與選項圓鈕綁定之變數類別物件名稱, 用來動態存取選項圓鈕之值 |
text | 選項圓鈕的項目顯示文字 (與 value 對應, 可與 value 不同) |
textvariable | 綁定選項顯示文字的類別變數名稱 |
command | 當按鈕狀態改變時要執行的函式名稱 |
width | 元件寬度 (字元數) |
height | 元件高度 (字元數, ttk 不支援) |
indicatoron | 用按鈕形式顯示選項 (ttk 不支援) |
其中要特別注意的是 variable 這參數, 其功能是用來將 Radiobutton 群組綁定到一個類別變數, 以便能動態存取 Radiobutoon 之值. 單選元件是由一群 Radiobutton 物件組成, 但要讓它們具有單選效果, 必須將各項目的 Radiobutton 之 variable 參數都設為相同名稱之類別變數, 然後用 value 參數區別不同的選項值, 整體結構如下 :
var=StringVar()
var.set(初始值)
rbtn1=tl.Radiobutton(win, variable=var, value=v1, text=t1)
rbtn2=tl.Radiobutton(win, variable=var, value=v2, text=t2)
rbtn3=tl.Radiobutton(win, variable=var, value=v3, text=t3)
.....
類別變數 var 視需要也可以是 IntVar(), DoubleVar() 或 BooleanVar(). 傳入類別變數 set() 方法的初始值可設為 value 參數的值 v1, v2, v3,... 看要用哪一個當作預設被選取之項目, 如果預設都不選取, 則只要傳入 v1, v2, v3... 以外的任何值即可.
例如 :
測試 1 : 單選圓鈕 tk 版 [看原始碼]
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as msgbox
def show_selection():
msgbox.showinfo("info", "性別: " + gender.get())
win=tk.Tk()
win.title("tkinter GUI 測試")
gender=tk.StringVar() # 與單選圓鈕綁定的類別變數
gender.set("M") # 設定初始值
tk.Label(text="性別 : ", width=30, bg="cyan").pack()
tk.Radiobutton(win, text="男",
variable=gender,
value="M",
command=show_selection).pack() # 選項 1
tk.Radiobutton(win, text="女",
variable=gender,
value="F",
command=show_selection).pack() # 選項 2
win.mainloop()
此例為二選一的單選圓鈕, 利用相同的 variable 參數值 (=gender) 將這兩個圓鈕組成一個群組, 其值與名為 gender 的類別變數綁定在一起, 亦即可用 gender.set() 設定哪一個圓鈕被選取, 或呼叫 gender.get() 取得目前被選取的圓鈕之值. 另外 command 則可指定點選選項時要執行的函式名稱. 注意, 建立單選圓鈕群組後必須呼叫與其綁定的類別變數之 set() 方法設定初始值, 否則預設每個選項會被選取, 若要預設都不選取, 則可在呼叫 set() 時傳入一個所有選項的 value 以外之值即可, 結果如下 :
可見 Radiobutton 的 text 參數負責顯示, 而 value 設定每個項目之值, 呼叫類別變數的 get() 方法傳回的是選項的 value, 不是 text.
下面範例是上例的 ttk 版 :
測試 2 : 單選圓鈕 ttk 版 [看原始碼]
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as msgbox
def show_selection():
msgbox.showinfo("info", "性別: " + gender.get())
win=tk.Tk()
win.title("tkinter GUI 測試")
gender=tk.StringVar()
gender.set("M")
ttk.Label(text="性別 : ", width=30, background="cyan").pack()
ttk.Radiobutton(win, text="男",
variable=gender,
value="M",
command=show_selection).pack()
ttk.Radiobutton(win, text="女",
variable=gender,
value="F",
command=show_selection).pack()
win.mainloop()
結果如下 :
上面的範例的選項數目較少, 所以一個一個建立 Radiobutton 物件還 OK, 但如果選項較多時, 程式碼就會變得很冗長, 這時可將選項的值 (value 參數值) 與顯示文字 (text 參數值) 放在字典中, 然後使用 for 迴圈來建立 Radiobutton 元件, 例如 :
測試 3 : 用字典搭配迴圈建立 Radiobutton 物件 [看原始碼]
import tkinter as tk
from tkinter import ttk
def show_selection():
label_result["text"]="選擇結果: " + fruit.get()
win=tk.Tk()
win.title("tkinter GUI 測試")
fruit=tk.StringVar() # 綁定 Radiobutton 群組的類別變數
fruit.set("none") # 設定初始值 (預設都不選)
tk.Label(text="請選擇最喜歡的水果 : ", width=30, bg="cyan").pack()
fruits={"apple": "蘋果", "grape": "葡萄", "peach": "桃子", "mango": "芒果"}
for value, text in fruits.items(): # 用迴圈建立 Radiobutton 物件
tk.Radiobutton(win, text=text,
variable=fruit,
value=value,
command=show_selection).pack()
label_result=tk.Label(text="", width=30, bg="ivory") #顯示結果的 Label
label_result.pack()
win.mainloop()
此例定義了一個用來綁定 Radiobutton 群組的類別變數 fruit, 並且將其初始值任意設為各選項 value 參數值都沒有的 "none" 以便這些選項預設都沒有被選取. 然後以選項的值作為 key, 顯示文字作為 value 組成一個字典 fruits, 呼叫其 items() 方法便可傳回字典鍵值 tuple 組成之串列, 接著以 for 迴圈走訪此串列時建立 Radiobutton 元件, 結果如下 :
可見 fruit.get() 傳回的是被選取的 Radiobutton 元件之 value 參數值, 此例的 fruits 字典將鍵與值設為不同值, 如果要讓傳回值與顯示值相同, 則可以將 text 與 value 參數設為相同, 這樣就不需要使用字典, 只要使用 tuple 或串列就可以了, 例如 :
測試 4 : 用串列搭配迴圈建立 Radiobutton 物件 [看原始碼]
import tkinter as tk
from tkinter import ttk
def show_selection():
label_result["text"]="選擇結果: " + fruit.get()
win=tk.Tk()
win.title("tkinter GUI 測試")
fruit=tk.StringVar()
fruit.set("none")
tk.Label(text="請選擇最喜歡的水果 : ", width=30, bg="cyan").pack()
fruits=["蘋果", "葡萄", "桃子", "芒果"] # 兼做 text 與 value 參數值
for e in fruits:
tk.Radiobutton(win, text=e,
variable=fruit,
value=e,
command=show_selection).pack()
label_result=tk.Label(text="", width=30, bg="ivory")
label_result.pack()
win.mainloop()
此例 text 與 value 參數都使用串列元素, 結果如下 :
可見顯示的選取結果與選項的顯示文字是一樣的.
下面範例測試 Radiobutton 元件的 indicatoron 參數, 此參數若設為 0 就會將選項以按鈕形式表示, 否則就以預設的圓鈕顯示, 不過此參數僅 tk 版有, ttk 不支援 :
測試 5 : 用串列搭配迴圈建立 Radiobutton 物件 [看原始碼]
import tkinter as tk
from tkinter import ttk
def show_selection():
label_result["text"]="選擇結果: " + fruit.get()
win=tk.Tk()
win.title("tkinter GUI 測試")
fruit=tk.StringVar()
fruit.set("none")
tk.Label(text="請選擇最喜歡的水果 : ", width=30, bg="cyan").pack()
fruits=["蘋果", "葡萄", "桃子", "芒果"]
for e in fruits:
tk.Radiobutton(win, text=e,
variable=fruit,
value=e,
indicatoron=0,
command=show_selection).pack()
label_result=tk.Label(text="", width=30, bg="ivory")
label_result.pack()
win.mainloop()
結果如下 :
下面範例測試 Radiobutton 元件的 width, height, 以及 background/bg 參數 :
測試 6 : 測試 Radiobutton 元件的 width, height 與 bg 參數 [看原始碼]
import tkinter as tk
from tkinter import ttk
def show_selection():
label_result["text"]="選擇結果: " + fruit.get()
win=tk.Tk()
win.title("tkinter GUI 測試")
fruit=tk.StringVar()
fruit.set("none")
tk.Label(text="請選擇最喜歡的水果 : ", width=30, bg="cyan").pack()
fruits={"蘋果": "pink", "葡萄": "yellow", "桃子": "#654321", "芒果": "lime"}
for value, bg in fruits.items():
tk.Radiobutton(win, text=value,
variable=fruit,
value=value,
width=20,
height=2,
bg=bg,
command=show_selection).pack()
label_result=tk.Label(text="", width=30, bg="ivory")
label_result.pack()
win.mainloop()
此例使用字典來儲存水果選項名稱與其背景色之鍵值對, 然後以 for 迴圈走訪字典的 items() 方法傳回之 tuple 串列時設定各選項之背景色, 結果如下 :
要注意的是 width 與 height 單位都是字元數, 不是 px.
下面範例測試 textvariable 參數, 此參數透過所綁定的類別變數 (通常是 StringVar) 用來控制選項圓鈕旁的顯示文字, 注意, 設定了 textvariable 參數後, text 參數就無效了, 例如 :
測試 7 : 測試 Radiobutton 元件的 textvariable 參數 [看原始碼]
import tkinter as tk
from tkinter import ttk
def show_selection():
result_label.config(text="性別: " + gender.get())
def english():
option1.set("Male")
option2.set("Female")
def chinese():
option1.set("男")
option2.set("女")
win=tk.Tk()
win.title("tkinter GUI 測試")
gender=tk.StringVar()
gender.set("none")
option1=tk.StringVar() # 用來綁定到選項的 textvariable 參數
option1.set("男")
option2=tk.StringVar() # 用來綁定到選項的 textvariable 參數
option2.set("女")
ttk.Label(text="性別 : ", width=30, background="cyan").pack()
ttk.Radiobutton(win,
variable=gender,
textvariable=option1,
value="M",
command=show_selection).pack()
ttk.Radiobutton(win,
variable=gender,
textvariable=option2,
value="F",
command=show_selection).pack()
result_label=ttk.Label(text="性別 : ", width=30, background="ivory")
result_label.pack()
ttk.Button(win, text="英文", command=english).pack(side="left")
ttk.Button(win, text="中文", command=chinese).pack(side="right")
win.mainloop()
此例的兩個選項設定了 textvariable 參數, 分別綁定到 option1 與 option2 這兩個 StringVar 類別變數, 因此就不需要設定 text 參數了. 選項顯示文字預設為中文, 當按下 "英文" 鈕時呼叫 english() 函式將 option1 與 option2 改為英文顯示, 結果如下 :
參考 :
沒有留言:
張貼留言