2023年5月11日 星期四

Python 內建 GUI 模組 tkinter 測試 (十七) : OptionMenu 元件

這幾天因為想要用 Python 改寫之前用 IE/Edge + WSH 寫的工作自動化軟體, 重新把 tkinter 筆記找出來複習, 想說剩下一小部分乾脆就測一測把 tkinter 來個大圓滿, 上一次玩 tkinter 已是兩年前 (2021) 時的事了, 學習跟感冒一樣 ~~~ 最怕拖, 呵呵. 


OptionMenu 元件與網頁的的下拉式選單類似, 其實就是一個含有選項清單的特殊的按鈕, 平常選單是收合起來的, 點擊才會顯示選項清單. 

建立 Menu 元件之語法如下 (注意, 此元件僅在 tk 中提供, ttk 中無此元件) : 

optionmenu=OptionMenu(container, var, default=None, *values, **kwargs)    

參數說明如下 : 

container : 父容器物件
var : 儲存所選項目之 tk.StringVar 物件
default : 預設被選取之項目
*values : 儲存選項清單之序列物件名稱 (tuple/list)
**kwargs : 關鍵字參數

前兩個參數 containner 與 var 是必要參數. 注意, 序列物件名稱 values 前面必須有星號 *, 反則清單內容不會顯示 (雖然不會有 error 出現). 

建立 OptionMenu 物件時清單項目有兩種傳入 OptionMenu() 的方式 : 


1. 項目以字串參數依序傳入 :   

即參數 *values 是以 '項目1', '項目2', '項目3', .... 等字串參數依序傳入, 適合用在項目數量少的場合, 例如 : 

import tkinter as tk

win=tk.Tk()                                                      
win.title("tkinter GUI 測試")                           
win.geometry("500x200")
var=tk.StringVar(win)
optionmenu=tk.OptionMenu(win, var, 'Python', 'Java', 'C++', 'Perl')
optionmenu.pack()
win.mainloop()

此例將清單項目以字串依序放在兩個必要參數後面, 結果如下 :




可見 OptionMenu 剛開始時只是一個沒有預設選項的按鈕 (左側是空白的), 按一下就會彈出清單, 點選後被選取之項目會顯示在按鈕左邊 : 





2. 項目以 tuple 或 list 變數傳入 :   

清單項目也可以改用一個 tuple 或 list 變數傳入, 此變數前面須有星號 * (表示不確定長度之參數), 例如上例可改寫如下 :

import tkinter as tk

win=tk.Tk()                                                      
win.title("tkinter GUI 測試")                           
win.geometry("500x200")
var=tk.StringVar(win)
values=('Python', 'Java', 'C++', 'Perl')       # 用list 亦可
optionmenu=tk.OptionMenu(win, var, *values)
optionmenu.pack()
win.mainloop()

結果與上例相同. 注意, 此處儲存清單項目的變數 values 前面若無 * 號, 執行不會有錯誤, 但點擊按鈕時清單不會出現. 


3. 用 tk.StringVar 的 set() 方法設定預設選項 : 

在上面的範例中, 選項按鈕元件沒有預設選項, 這可以透過 tk.StringVar 物件的 set() 方法加以設定 (此物件會被傳入 tk.OptionMenu() 的第二參數 var), 例如 : 

import tkinter as tk

win=tk.Tk()                                                      
win.title("tkinter GUI 測試")                           
win.geometry("500x200")
var=tk.StringVar(win)
var.set('C++')       # 設定預設選項
optionmenu=tk.OptionMenu(win, var, 'Python', 'Java', 'C++', 'Perl')
optionmenu.pack()
win.mainloop()

此例呼叫 tk.StringVar 物件的 set() 方法設定預設選項為 'C++', 結果如下 :




可見程式一執行, 選項按鈕左側就出現預設選項為 'C++' 了. 


4. 用 tk.StringVar 的 get() 方法取得所選之選項 : 

下面範例測試用 tk.StringVar 物件的 get() 方法取得選項按鈕被選定之項目 :

import tkinter as tk
from tkinter import messagebox

def event_handler():
    messagebox.showinfo('Info', 'You select ' + var.get())
    
win=tk.Tk()                                                      
win.title("tkinter GUI 測試")                           
win.geometry("500x200")
var=tk.StringVar(win)
var.set('C++')
optionmenu=tk.OptionMenu(win, var, 'Python', 'Java', 'C++', 'Perl')
optionmenu.pack()
button=tk.Button(win, text='Get selection', command=event_handler)
button.pack()
win.mainloop()

此例添加了一個 tk.Button 物件, 當按下它時會呼叫 event_handler() 函式, 用 var.get() 取得選項按鈕的選項中被選擇的項目, 然後用 tk.MessageBox 訊息盒顯示, 結果如下 :




5. 用 tk.StringVar 的 trace() 方法監視選項變更事件 : 

除了用按鈕事件去取得被選取項目外, 也可以利用 tk.StringVar 物件的 trace() 方法追蹤選項的變更事件, 此方法要傳入兩個參數 :

var.trace(mode, event_handler)   

參數說明如下 :

mode : 追蹤模式, 'w'=當選單的值被改變或被選擇
event_handler : 當事件發生時要呼叫的函式

例如 :

import tkinter as tk

def show_change(*args):
    label['text']='You select ' + var.get()

win=tk.Tk()                                                      
win.title("tkinter GUI 測試")                           
win.geometry("500x200")
var=tk.StringVar(win)
values=('Python', 'Java', 'C++', 'Perl')
optionmenu=tk.OptionMenu(win, var, *values)
optionmenu.pack()
label=tk.Label(win, text='')
label.pack()
var.trace('w', show_change)    
win.mainloop()

此例改用 tk.Label 元件來顯示被選定之選項, 並使用 'w' 模式來追蹤選項的變更, 當事件發生時呼叫 show_change() 函式在 Label 元件上顯示被選定之選項, 結果如下 :




參考 :


沒有留言 :