Python可以這樣玩(8):選擇類元件應用
如果任何內容都使用文字方塊來輸入,會變得很沒有效率,因為有些東西是可以讓使用者用選的方式來輸入,可以節省很多時間。選擇類元件包含了單選鈕(Radiobutton)、核取方塊(Checkbutton)、下拉式清單(Combobox)、以及清單方塊(Listbox)。
讓我們一步一步示範這些元件的用法,整個程式的構想是,寫一個班級學生的輸入介面,可以讓老師輸入學生的姓名、性別、年級、班級、是否報到等資訊之後,插入到一個多行文字方塊之中,並提供刪除功能。
元件定位
首先我們來設計姓名輸入的文字框,要讓使用者清楚知道輸入姓名的位置,必須用到兩個元件,就是用 Label 以及 Entry,除此之外,之前的
pack()不能再用了,為了精準定位,我們使用 place() 精確的定出元件的位置:
import
tkinter as tk
window =
tk.Tk()
window.title('學生基本資料')
window.geometry('400x320')
labName
= tk.Label(window, text = '學生姓名:',
justify = tk.RIGHT, width = 50)
labName.place(x=10,
y=10, width=100, height=20)
varName
= tk.StringVar()
varName.set('')
entName
= tk.Entry(window, width = 120, textvariable = varName)
entName.place(x=110,
y=10, width=120, height=20)
window.mainloop()
請注意這裡已經把原本的 pack() 改成 place() 了,其中 x, y 是元件左上角對應視窗的座標。
接下來我們要輸入年級和班級,年級為一到三,班級為甲到戊,這兩個值是固定的,所以我們可以使用 combobox 來達成。
Combobox 下拉式選單
要使用 combobox,我們必須匯入
tkinter.ttk,年級的值按照規定要使用元組來儲存,程式碼如下:
import
tkinter as tk
import
tkinter.ttk as tt
window =
tk.Tk()
window.title('學生基本資料')
window.geometry('400x320')
labName
= tk.Label(window, text = '姓名:',
justify=tk.RIGHT, width=50)
labName.place(x=10,
y=10, width=100, height=20)
varName
= tk.StringVar()
varName.set('')
entName
= tk.Entry(window, width = 120, textvariable = varName)
entName.place(x=110,
y=10, width=120, height=20)
labGrade
= tk.Label(window, text = '年級:',
justify=tk.RIGHT, width=50)
labGrade.place(x=10,
y=40, width=100, height=20)
stdGrade
= ('1','2','3')
comGrade
= tt.Combobox(window, width=50, values=stdGrade)
comGrade.place(x=110,
y=40, width=50, height=20)
window.mainloop()
執行結果如下:
用同樣的方式把每一個年級甲到戊班也放入 combobox 裡面,這種方式是兩個 combobox 各自獨立運作,有另外一種連動的 combobox 組,選取第一個之後才決定第二個的值,我們在此先不討論。
Radiobutton 單選鈕
單選鈕的特性就是,只能有一個選擇,性別就是標準的單選鈕,不是男生,就是女生。程式碼如下,紅色部分為相關部分:
import tkinter
as tk
import
tkinter.ttk as tt
window =
tk.Tk()
window.title('學生基本資料')
window.geometry('400x320')
labName
= tk.Label(window, text = '姓名:',
justify=tk.RIGHT, width=50)
labName.place(x=10,
y=10, width=100, height=20)
varName
= tk.StringVar()
varName.set('')
entName
= tk.Entry(window, width = 120, textvariable = varName)
entName.place(x=110,
y=10, width=120, height=20)
labGrade
= tk.Label(window, text = '年級:',
justify=tk.RIGHT, width=50)
labGrade.place(x=10,
y=40, width=100, height=20)
stdGrade
= ('1','2','3')
comGrade
= tt.Combobox(window, width=50, values=stdGrade)
comGrade.place(x=110,
y=40, width=60, height=20)
labGrade
= tk.Label(window, text = '班級:',
justify=tk.RIGHT, width=50)
labGrade.place(x=190,
y=40, width=100, height=20)
stdClass
= ('甲','乙','丙','丁','戊')
comClass
= tt.Combobox(window, width=50, values=stdClass)
comClass.place(x=300,
y=40, width=60, height=20)
labSex =
tk.Label(window, text = '性別:',
justify=tk.RIGHT, width=50)
labSex.place(x=10,
y=70, width=100, height=20)
varSex = tk.IntVar()
varSex.set(1) # 預設值1=男
radBoy =
tk.Radiobutton(window, variable=varSex, value=1,text='男生')
radBoy.place(x=110,
y=70, width=60, height=20)
radGirl =
tk.Radiobutton(window, variable=varSex, value=0,text='女生')
radGirl.place(x=190,
y=70, width=60, height=20)
window.mainloop()
Radiobutton 有“群組”的觀念,同一個群組的 Radiobutton 只能有一個項目被選取,才能表現單選的特性,因此,在這個例子中性別就是一個群組,男生和女生則是群組裡面的兩個項目,那麼我們要如何區分是否是同一個群組呢?就是靠
variable=varSex 來表現,設定成相同變數名稱的,就是同一個群組。
接下來就是 value=1 代表男生,value=0 但表女生。執行結果如下圖 (點女生,男生就跳掉):
Checkbutton 核取方塊
核取方塊的表現與單選鈕完全不同,它是可以多重選擇的,所以可以各自獨立。我們就加一個 “是否報到” 核取方塊,新增的程式碼如下:
signin =
tk.IntVar()
signin.set(0) # 預設值0=未報到
chkSignin
= tk.Checkbutton(window, text='是否報到',
variable=signin,
onvalue=1, offvalue=0)
chkSignin.place(x=100,
y=100, width=100, height=20)
因為可以各自獨立,所以會有各自的 variable,透過 onvalue=1, onvalue=0 給予變數值。
Listbox 清單方塊
最後,我們加入一個新增按鈕、一個刪除按鈕、以及一個清單方塊,此範例我們先談新增功能,其他進階功能後面再補充,程式碼如下:
def
addInfo():
result = '姓名:' + entName.get()
result += ';年級:' + comGrade.get()
result += ';班級:' + comClass.get()
result += ';性別:' + ('男生' if
varSex.get() else '女生')
result += ';報到:' + ('是' if
signin.get() else '否')
lstStudent.insert(0,result)
btnAdd =
tk.Button(window, text='加入',
width=40, command=addInfo)
btnAdd.place(x=150,
y=100, width=100, height=20)
btnDel =
tk.Button(window, text='刪除',
width=40, command=addInfo)
btnDel.place(x=260,
y=100, width=100, height=20)
lstStudent
= tk.Listbox(window, width=380)
lstStudent.place(x=10,
y=130, width=380, height=180)
請注意取值的方,前三個取元件的值,後兩個取變數的值。插入方式則是每次都插入第一行,執行結果如下:
到這裡為止,我們已經學會的大部分會用到的GUI元件,為了讓讀者不會覺得太枯燥,我們接下來來玩一下 tkinter 的繪圖功能。
留言
張貼留言