Python的門面擔當 - Tkinter
在大多數時候,我們都在黑黢黢的控制檯裡執行 Python 指令碼。這看起來很酷很 GEEK。但對於部分場景下的使用者來說,這樣就不大美觀和人性化了:我們需要互動更方便的圖形化產品,也就是 GUI (圖形使用者介面,Graphical User Interface)。
Python 有很多可實現 GUI 的庫,在之前的文章中有過一個整理: ofollow,noindex" target="_blank">在這個什麼都看臉的時代,如何用 GUI 提高 python 程式的顏值? 但沒有針對某個具體的庫做介紹。最近有同學提到希望給講解下 GUI 的開發,那麼今天就來做個簡單的“快速上手”。
而我們要介紹的庫,就是
Tkinter
相比較其他的 GUI 庫,Tkinter 有個優勢在於,它是 Python 內建的 GUI 庫 ,無需另行安裝,省事了一點點。另外如果你要將開發出的程式打包成 exe,它也比第三方庫稍稍更容易一點點。
而功能上,Tkinter 已足夠處理大多數小型 GUI 程式的需求。其開發的程式在各主流作業系統上均可執行。Python 的內建編輯器 IDLE 就是使用 Tkinter 開發的。因此,我個人在之前的開發中,是將 Tkinter 作為首選。
(當然, PyQt 也是很強大的 GUI 庫,可以做出複雜酷炫的介面效果。而原有 QT 開發經驗的人更是很容易上手。)
Hello GUI World
我們從一個最簡單的 Tkinter GUI 程式說起:
import tkinter as tk root = tk.Tk() root.mainloop()

1.建立一個 Tk 視窗物件;2.呼叫這個物件的訊息主迴圈。 一個視窗就出現了。在這個視窗之上,可以新增各種輸入框、按鈕、文字等,可以增加對各種動作的處理。
以往我們寫的程式(比如猜數字、罰點球、查天氣等)大多是有一個固定的執行流程。而 GUI 程式的不同之處在於,通常它們是由“ 事件驅動 ”的:程式執行後,相當於進入一個迴圈一直執行。如果你不做任何操作,這個視窗就一直在這裡。看起來是靜止的,但程式實際上是在等待你的操作: 通過與視窗中的“ 控制元件 ”進行互動,比如點選按鈕、輸入文字、勾選選項等,產生不同的“ 事件 ”,程式再根據預設的“ 響應 ”做處理。 就算要結束程式,也是通過“關閉視窗”和“退出”事件。
這就是 mainloop 的意義所在:監聽各種事件。理解了這一點,也就理解了 GUI 程式的基本邏輯。
控制元件
所謂 控制元件 ,就是 GUI 圖形化介面上的物件,或者說功能元素。比如輸入框、文字框、按鈕、下拉選單、滾動條等等,窗體本身也可以認為是一個控制元件。一個控制元件包含了資料和操作,決定了頁面上的元素放在哪裡、長什麼樣、有什麼樣的效果。
舉幾個 Tkinter 常用控制元件的例子:
label = tk.Label(root, text="Hello, world!") label.pack() btn = tk.Button(root, text="OK") btn.pack() entry = tk.Entry(root) entry.pack() root.mainloop()

在呼叫 mainloop
前,增加了 Label (文字標籤)、 Button (按鈕)、 Entry (輸入框)三個控制元件,通過 pack()
方法把它們新增到了視窗之上。
Tkinter 有 15 個核心控制元件,每個控制元件有多種設定,這裡不展開介紹,網上可以很容易搜到詳細的文件說明。
另外除了這些基本控制元件之外,Tkinter 還提供了一個 ttk 模組,增加了幾個控制元件並對部分已有控制元件進行了優化。例如:
from tkinter import ttk entry = ttk.Entry(window) entry.pack() combo = ttk.Combobox(window) combo['values'] = ('IDLE', 'PyCharm', 'VSCode', 'SublimeText') combo.pack()

完整示例程式碼在文末附上。
對於控制元件屬性的設定,有 3 種方法:
- 在 建立 時通過 引數 設定。如
btn = Button(root, text="Click", fg="red", bg="blue", command=click)
- 通過 字典 的方式修改。如
btn["fg"] = "green"
- 通過 config 函式修改。如
btn.config(fg="green", bg="yellow")
佈局
如果只是簡單的用 pack()
方法將控制元件新增到視窗上,它們將按順序從上往下的放置。這顯然無法滿足複雜的需求。
Tkinter 提供了三種佈局方式:
1. Pack
pack 是最簡單的佈局管理方式,除了像我們前面直接呼叫外,可以加上 fill、padx、pady、ipadx、ipady、side 等引數,調整放置的邊距、填充方式、對齊方式等。
btn.pack(fill=tk.X, padx=5, pady=20, side=tk.LEFT)
2. Place
用 place 替代 pack,可以精確地指定空間的放置座標及長寬。
btn.place(x=50, y=100, width=120, height=25)
3. Grid
Grid 佈局的邏輯在於,將視窗像表格一樣劃分成不同的格子,將控制元件放置進去。例如:

當控制元件數量眾多時,這種佈局方式更有條理。
btn.grid(row=1, column=0)
順便提一句,如果你希望可以像 VB 那樣所見即所得地設計窗體控制元件,可以瞭解下 Visual Tkinter 這個工具。
事件
前面說的都是外在的形式,一個 GUI 程式要能執行,離不開內部的事件響應。即:當用戶做了一個操作,程式要做出怎樣的反應。
事件要與特定的控制元件相繫結,比如按鈕有點選事件,輸入框有按鍵事件,窗體有關閉事件等。
常用的 2 種繫結方法:
1. command
通過控制元件的 command 引數指定響應函式:
def onClick(): print('clicked!') btn = Button(root, text='click', command=onClick)
注意這裡傳遞引數時,onClick 後面不能加上括號。(思考下加與不加的區別在哪裡?)
2. bind
通過 bind 方法繫結不同的事件:
def onButton(event): print("Clicked:", event.x, event.y) def onKey(event): print("Pressed", event.char) entry.bind('<Button-1>', onButton) entry.bind('<Key>', onKey)
控制元件、佈局、事件響應,就是 GUI 開發的幾個重要部分。對此有了整體認識後,剩下的就是查閱相關文件和練習了。
如果有不理解的部分或想要深入瞭解的細節問題,可以在我們的 論壇 http:// bbs.crossincode.com 上發帖討論,或在 知識星球 上提問。

運用上述內容,我們把課程最初的猜數字遊戲改成一個 GUI 版本。
獲取詳細程式碼,請在公眾號( Crossin的程式設計教室 )裡回覆關鍵字 GUI
【 課後作業 】實現一個簡單的 GUI 程式,猜數字或者一個簡單的登入框、一個小計算器等等,可以用 Tkinter,也可以用其他 GUI 庫。歡迎留言你的程式碼,或發在論壇上。
下課!
════
其他文章及回答:
如何自學Python |新手引導 |精選Python 問答 |Python單詞表 |知乎下載器 |人工智慧 |嘻哈 |爬蟲 |我用Python |高考 |requests |AI平臺
歡迎搜尋及關注: Crossin的程式設計教室