2021年7月14日 星期三

Python 內建 GUI 模組 tkinter 測試 (四) : 基本用法複習整理

我在 2016 年中開始學習 Python 內建的 GUI 模組 tkinter, 才整理了一篇入門筆記就停擺了. 到了2018 年想改寫語音處理程式再次拾起, 但也只再寫了兩篇筆記又停下來了. 最近因為工作方便, 計畫要寫個 GUI 介面搭配網路爬蟲來使工作自動化, tkinter 的學習經過了五年還停滯不前實在說不過去, 所以想趁此機會把 tkinter 一口氣學完, 以下先複習之前的筆記並做個摘要整理. 

本系列之前的文章參考 :

Python 內建 GUI 模組 tkinter 測試 (一) : 建立視窗
Python 內建 GUI 模組 tkinter 測試 (二) : 對話框
Python 內建 GUI 模組 tkinter 測試 (三) : 版面管理員

tkinter 的說明文件參考 :

https://pythonspot.com/en/tkinter/
Graphical User Interfaces with Tk

茲將前三篇筆記摘要整理如下 : 


1. 匯入模組 :

這幾年因為機器學習的推波助瀾, Python 3 現在已是主流, 所以學習 GUI 套件應該改用 Python 3 的 tkinter 模組 (注意是小寫的 t), 而非 Python 2 的 Tkinter 模組 (注意是大寫的 T). 使用 tkinter 模組通常即可開發一般的 GUI 程式, 但若要使用更進階的元件也可以同時匯入其子模組 ttk : 

>>> import tkinter as tk                     # 匯入 tkinter 並取簡名 tk
>>> from tkinter import ttk               # 匯入 tkinter 的子模組 ttk
>>> tk  
<module 'tkinter' from 'C:\\Python37\\lib\\tkinter\\__init__.py'>
>>> ttk   
<module 'tkinter.ttk' from 'C:\\Python37\\lib\\tkinter\\ttk.py'>

原始版的 tkinter 提供了 19 種視窗元件 (widget, 或稱控制項), 其外觀依賴於作業系統, 為了美化視窗元件外觀與提供更多好用元件, tkinter 另外發展了主題版 (Themed tkinter) 的子模組 ttk, 它提供了 18 種外觀美化的主題元件 (其中 12 種與 tkinter 相同), 合計有 25 種元件可用 :  


 tkinter 元件 ttk 元件 說明
 1. Label 1. Label 標籤文字
 2. Button 2. Button 按鈕
 3. Radiobutton 3. Radiobutton 單選圓鈕
 4. Checkbutton 4. Checkbutton 核取方塊 (多選)
 5. Entry 5. Entry 文字欄位 (單行)
 6. Text  文字區域 (多行)
 7. Scrollbar 6. Scrollbar 捲軸
 8. Listbox  清單方塊
 9. Spinbox 7. Spinbox 數值微調器
 10. Scale 8. Scale 尺規
 11. Frame 9. Frame 框架
 12. LabelFrame 10. LabelFrame 標籤框架
 13. Toplevel  頂層視窗
 14. PanedWindow 11.PanedWindow 視窗面板
 15. Menu  選單
 16. OptionMenu  功能表
 17. Menubutton 12. MenuButton 選單按鈕
 18. Canvas  畫布
 19. Message  訊息 (可多行)
  13. Combobox 下拉式選單
  14. Notebook 頁籤面板
  15. Progressbar 進度條
  16. Separator 分隔線
  17. Sizegrip 尺寸調整器
  18. Treeview 樹狀表格


2. 視窗程式基本架構 :    

tkinter 模組基本視窗程式結構如下 : 

import tkinter as tk                                  # 匯入 tkinter 模組並取簡名為 tk
root=tk.Tk()                                             # 建立根視窗 Tk 物件 
root.title("Hello")                                     # 設定標題
label=tk.Lable(root, "Hello!")                 # 建立標籤元件
label.pack()                                              # 將標籤元件加入視窗
root.mainloop()                                        # 將根視窗加入事件監視迴圈並持續描繪視窗

使用 ttk 的基本架構如下 :

import tkinter as tk                                   # 匯入 tkinter 模組並取簡名為 tk
from tkinter import ttk                             # 匯入 ttk 子模組
root=tk.Tk()                                             # 建立根視窗 Tk 物件 (仍用 tk)
root.title("Hello")                                     # 設定標題
label=ttk.Lable(root, "Hello!")               # 建立標籤元件
label.pack()                                              # 將標籤元件加入視窗
root.mainloop()                                        # 將根視窗加入事件監視迴圈並持續描繪視窗

注意, 建立根視窗物件仍然要用 tk.Tk(), 建立元件才用 ttk.

如果視窗元件物件後續不會再用到就不須建立物件參考, 可以直接用鏈式呼叫 :

ttk.Label(root, "Hello").pack()   

視窗預設是可拖曳調整大小, 放到最大或縮小, 也可以呼叫根視窗 Tk 物件的 geometry() 方法設定視窗大小 :

root.geometry("400x300")

呼叫根視窗物件的 resizable() 方法傳入 (0,0) 或 (False, False) 可限制視窗不可調整大小 : 

root.resizable(0,0)                         # 設定視窗不可變更大小
root.resizable(False, False)           # 設定視窗不可變更大小


3. 建立元件 : 

原始版 tkinter 使用模組簡名 tk 呼叫方法, 主題版則用子模組名稱 ttk. 


(1). 標籤元件 : 

label=tk.Label(root, text="Hello World!")

更改標籤內容 :

label.configure("你是在說哈囉嗎?")


(2). 按鈕元件 : 

button=tk.Button(root, text="OK", command=clickOK)    

按鈕須用 command 參數綁定一個事件處理函式 (此處為 clickOK). 

(3). 元件排版 : 

tkinter 元件提供 pack(流水式), grid(網格式), 以及 place(絕對與相對位置) 三種排版方法, 其中 pack 與 grid 兩種方式互斥, 一個視窗容器中不可同時使用 pack 與 grid, 但 place 排版中則可以同時用 pack 與 grid. 

流水式排版 : 呼叫元件的 pack() 方法可將元件如流水般順序放入視窗容器, 預設是由下而上堆疊, 但可以利用可選參數 side (tk.TOP/tk.BOTTOM/tk.LEFT, tk.RIGHT/tk.CENTER) 與 anchor (tk.E/tk.W/tk.S/tk.N/tk.NW/tk.SW/tk.NE/tk.SE/tk.CENTER) 指定元件的放置方位與錨定位置, 預設是 tk.TOP 與 tk.CENTER, 故元件預設會由上而下置中放置 :   

label.pack()
button.pack()
button.pack(side=tk.LEFT, anchor=tk.S)

網格式排版 : 呼叫元件的 grid() 方法 

label.grid(row=0, column=0)     
button.grid()    # 多列單行
button.grid(row=0, column=1)


4. 對話框 : 

tkinter 透過三個子模組提供完整的對話框功能 :


 tkinter 對話框類別 說明
 messagebox 提供訊息輸出與確定, 取消, 是, 否等按鈕回應功能 (輸出)
 simpledialog 提供輸入框與確定, 取消等按鈕回應功能 (輸入)
 filedialog 提供檔案開啟與儲存對話框功能


其中訊息盒 messagebox 透過方法呼叫提供 8 種訊息盒類型, 語法如下 : 

messagebox.functionName(title, message [, detail])

參數 message 是主訊息, 而可選的 detail 則是說明訊息. 


 messagebox 方法 說明 按鈕 圖示 回傳值
 showinfo(title, massage [, detail]) 通知對話框 確定 i "ok"
 showwarning(title, massage [, detail]) 警告對話框 確定 ! "ok"
 showerror(title, massage [, detail]) 錯誤對話框 確定 x "ok"
 askyesno(title, massage [, detail]) 詢問對話框 是/否 ? True/False
 askokcancel(title, massage [, detail]) 詢問對話框 是/取消 ?  True/None
 askyesnocancel(title, massage[, detail]) 詢問對話框 是/否/取消 ? True/False/None
 askquestion(title, massage[, detail]) 詢問對話框 是/否 ? "yes"/"no"
 askretrycancel(title, massage[, detail]) 詢問對話框 重試/取消 ? True/False


使用 messagebox 要先從 tkinter 匯入此子模組並取個方便的簡名例如 mb :

from tkinter import messagebox as mb

例如 :

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as mb

def hello():
    mb.showinfo("Info", "Hello World!")

root=tk.Tk()
root.title("Hello")
root.geometry("300x200")
button=ttk.Button(root, text="Hello", command=hello)
button.pack()
root.mainloop()

子模組 simpledialog 就是輸入盒的功能, 可讓使用者輸入資料供程式後續運算, 使用前須從 tkinter 匯入此子模組並取個簡名例如 sd, 語法如下 :

from tkinter import simpledialog as sd

simpledialog 提供了三個方法分別用來讀取字串, 整數, 以及浮點數三種型態之輸入 :


 simpledialog 的方法 說明 回傳值
 askstring(title, message) 顯示字串輸入對話框 字串
 askinteger(title, message) 顯示整數輸入對話框 整數
 askfloat(title, message) 顯示浮點數輸入對話框 浮點數
 

這三個方法有 title 與 message 這兩個必要參數, 其實對於數值輸入的 askinteger() 與 askfloat() 還有如下三個可選參數 :
  • minvalue : 設定最小值
  • maxvalue : 設定最大值
  • initialvalue : 設定初始值 (預設值) 
若輸入值超出 minvalue~maxvalue 的範圍會出現提示對話框.


5. tkinter 元件的共同屬性與方法 : 

每一個 tkinter 元件都是物件, 它們有各自專有之屬性與方法, 也有如下之共同屬性與方法: 


 tkinter 元件共同屬性 說明
 width 元件寬度, px 或字元數 (Label)
 height 元件高度, px 或字元數 (Label)
 bg/background 背景色, 可用標準顏色名稱字串例如 'blue' 或 "#0000ff"
 fg/foreground 前景色, 可用標準顏色名稱字串例如 'blue' 或 "#0000ff"
 anchor 元件的錨點位置, 可用 "n", "e", "s", "w", "nw", "ne","sw","se","center"
 font 字型, 例如 "Helvetic 20 bold italic" 或 ("Helvetic", 20, "bold", "italic")
 bitmaps 內建的圖形, 例如 "error","info", "question", "warning", "gray12" 等
 relief 元件的邊框, 例如 "groov", "flat", "raised", "ridge", "solid", "sunken"
 cursors 滑鼠在元件上時的游標型式, 例如 : "heart", "cross", "star" 等

 tkinter 元件共同方法 說明
 config() 即時更改元件屬性值
 keys() 以串列傳回元件的所有屬性值
 pack() 將元件以流水方式放入父容器中
 grid() 將元件以網格方式放入父容器中
 place() 將元件以絕對或相對定位方式放入父容器中


複習完前三篇的主要內容就可以開始進行下一步的測試學習了. 

沒有留言 :