tkinter 是 python 內建的 GUI。
Hello World
1 | from tkinter import * |
基本元件介紹
Widget
winfo_exists() 可檢查是否存在/顯示
winfo_children() 回傳底下所有 widget
Frame
1 | Style().configure('red.TFrame', background='red') # 自訂風格,字尾必為.TFrame,調整背景為紅色 |
清空 Frame
1 | def clear_frame(frame): |
Label
可透過[‘text’]或 config 修改文字,config 可修改 UI 屬性
1 | label = Label(window, text='Label') |
Button
點擊事件有兩種設定方式:
- 透過 command,只能處理左鍵單擊
- 透過 bind,event.widget 可取得原物件
1 | btn = Button(window, text='Button', command=lambda: messagebox.showinfo(message='I am info')) |
Entry
修改文字有兩種設定方式
- 透過 textvarialbe
- 透過 insert,END 為 tkinter 常數,表示結尾
1 | value = StringVar() |
ScrolledText
沒有 textvariable 屬性,只能用 insert()修改文字
1 | result_text = ScrolledText(master) |
Combobox
下拉式選單
1 | cb = Combobox(window) |
TreeView
可捲動的表格
1 | def sort_column(col, reverse): |
展開/收合 TreeView
1 | def tree_open(open): |
欄位可選取
1 | tv.bind('<Double-1>', _on_double_click) |
PanedWindow
可調整的佈局元件
1 | pw = PanedWindow(orient=HORIZONTAL) |
Toplevel
使用彈窗顯示 QR code
1 | import qrcode |
自訂元件
切記底下元素,例如_label 的 master 要是 TextField 的 self,而不是 master。
1 | class TextField(Frame): |
佈局
Pack
1 | label.pack(anchor=W) # 靠左呈現 |
Grid
1 | label.grid(row=0, column=0, sticky=W) # 靠左呈現 |
自動佈局,每三個項目為一列
1 | def auto_grid(parent, widget): |
Bind
- <Button-1> 左鍵點擊
- <Button-2> windows 和 unix 是中鍵點擊,mac 是右鍵點擊,可用
platform.system() == 'Darwin'
判斷,Darwin 為 mac - <Button-3> 右鍵點擊
- <Double-1> 左鍵連擊
參考http://tcl.tk/man/tcl8.7/TkCmd/bind.html
lambda 與閉包
閉包會把上一層的變數偷渡捕捉進來自己的 function scope,Javascript 便是用閉包來模擬 class。
參考https://medium.com/citycoddee/python進階技巧-4-lambda-function-與-closure-之謎-7a385a35e1d8
舉例來說,當用 for 迴圈實作多個元件與按鈕,下面的寫法 submit()永遠只會取到最後被指派的元件。
1 | from tkinter import * |
解法一,調整 lambda 寫法。
1 | test = Button(window, text="Click me!", command=lambda e=input.get(): submit(e)) |
解法二,將實作元件部分抽成 function,使用閉包捕捉上一層的變數來用。
1 | from tkinter import * |