Python 內建介面開發框架 Tkinter入門篇 甲

2023-01-23 06:00:24
本文大概 4158 個字,閱讀需花 10 分鐘
內容不多,但也花了一些精力
如要交流,歡迎關注我然後評論區留言
謝謝你的點贊收藏分享

首先,今天先給大家拜個好年!新年快樂,恭喜發財!為了感謝大家對我的鼓勵和支援,特地在公眾號裡搞了一波紅包抽獎活動。如果需要參與沾沾手氣的話,可以在1月23號22:00之前到公眾號訊息頁面回覆關鍵詞【錢兔無量】,然後系統會自動回覆抽獎活動的連結,點選進去看提示繼續操作即可。

農曆新的一年開始了,打工的煩心事兒可以稍停,但是學習不能停止!

關於 Tkinter

上期講過,python 其實有三大流行 GUI 開發框架,包括 PyQt、wxPython 和 Tkinter。wxPython 也在上期文章介紹過,今天給大夥帶來 Tkinter 的入門介紹!

Tkinter 是 python 標準庫內嵌自帶的介面開發框架,算得上是皇親國戚了。如此火熱的 python ,又怎能不瞭解一下它自帶的介面開發框架呢?

Tkinter 有很多強大的地方,比如跨平臺特性。同一套程式碼可以輕鬆執行在 Windows, macOS 和 Linux 系統環境下。它的視覺化元素都是基於本地系統元素渲染而得,所以和原生開發相比看不出來有什麼區別。

另外,Tkinter 和其它 GUI 框架相比非常輕量和簡潔。這就帶來了很明顯的缺點,介面風格有些過時。如果你需要開發光鮮亮麗的應用,可以參考一下我的其它博文,其中可找到其它的解決方案,總有適合你的那一款!而輕量級的優點也是很突出的,如果華麗花哨的視覺化於你是無關緊要的話,Tkinter 真的可以拿來即用,也沒有繁雜的開發流程,方便專注於功能的快速實現。對於急用的工具型軟體,有必要活捉一番 Tkinter。

關於往期相關的文章,有興趣可前往關注我的微信公眾號 「englyf」 檢視,倍感榮幸能得到你的關注!

這將是一個系列文章,你可以瞭解到這些資訊:

Tkinter 應用的基本框架是什麼樣子?
常用的基本控制元件有哪些?
除了基本控制元件,還有主題控制元件?
怎樣佈局介面?
如何與介面元素互動?
手把手寫一個簡單的記事本應用

本文所有測試程式碼執行環境基於 win10 x64。

基本框架

好了,八戒為了見 Tkinter 一面,就像娶媳婦一樣,匆忙揭開蓋頭,一睹為快。

新建檔案 main.py,先寫一個 hello world 吧!

import tkinter as tk

window = tk.Tk()
window.title("hello world !")
window.mainloop()

可以看到,需要先匯入庫 tkinter,名字有點長,所以命名為 tk 方便下面的參照。

絕大部分的介面應用都需要一個頂層視窗,這裡通過範例化類 Tk 獲得。然後在這個頂層視窗的標題列設定標題,呼叫方法 title(),傳入 「hello world」。最後,為了響應使用者的互動和輸入,必須呼叫主視窗的 mainloop() 以啟動事件環。

雖然 tkinter 是 python 標準庫的自帶 GUI 框架,但是在使用前也得先安裝 tk 庫。

pip install tk

安裝完,使用 pip list 確認一下

Package    Version
---------- -------
pip        22.3.1
setuptools 56.0.0
tk         0.1.0

寫作時,當前安裝的最新版本是 0.1.0。

上面的環境設定指令建議在預先準備好的虛擬環境下執行,至於怎麼設定虛擬環境,可以看看我的另一篇文章《Python:靈活的開發環境》

然後在環境下,輸入指令碼啟動指令

python main.py

看看跑起來的介面程式什麼樣子

從上面程式碼來看,沒有冗餘的部分,的確是拿來即用。

基本控制元件

下面是一些基本又常用的控制元件

控制元件類 說明
Label 文字標籤,顯示靜態文字
Button 按鍵,可點選的按鍵
Frame 矩形區域,組合相關控制元件
Entry 單行輸入框,輸入單行文字
Text 多行輸入框,輸入多行文字
Spinbox 範圍輸入框,選擇指定範圍內的值
Scale 刻度條,拖動按鈕選取數值
Progressbar 進度條,顯示進度
Listbox 列表,顯示瀏覽和選擇單行文字項的列表

當然 tkinter 的基本控制元件還有不少沒列出來,由於篇幅有限,本文著重於入門級別,如果你有需要查詢更全面的資訊可以繼續關注本公眾號的後續更新。所以接下來就從上面的表格中挑幾個基本的控制元件來細講,繼續看。

Label 文字標籤

做介面的時候,如果你需要顯示一些靜態的文字,比如在某些元素前面顯示一個名稱,那麼就可以用到控制元件 Label。這裡要注意,控制元件 Label 被設計用於向用戶顯示文字,而不是獲取文字。

比如,要顯示一行文字 display text with framework tkinter

import tkinter as tk

window = tk.Tk()
lbl = tk.Label(
    master=window,
    text="display text with tkinter framework",
    fg="white",
    bg="black",
    width=40,
    height=10
    )
lbl.pack()
window.mainloop()

範例化類 Label 的時候,演示了傳入引數 master,text,fg,bg,width 和 height。

引數 master 用於指定被範例化的控制元件被放置在哪個父控制元件中,這裡指定將範例化的控制元件 Label 放置在頂層視窗 window 中。

注意:如果 master 引數被忽略,那麼被範例化的控制元件就預設被放置在頂層視窗中。

引數 text 傳入的內容就是要顯示的文字字串。

引數 fg 和 bg 分別是 fontground 和 background 的縮寫,分別表示字型顏色和背景顏色。可以輸入有效的顏色名字,比如 "white","black","red","orange","yellow","green","blue","purple"等 ,或者輸入 # 開頭的 RGB 值,比如 "#34A2FE"。

引數 width 和引數 height 分別用於設定控制元件的寬高。

要注意的是,上面用到的引數 width 和引數 height 的單位不是畫素而是文字單位,1個單位 width 表示文字字元 0 的寬度,1個單位 height 表示文字字元 0 的高度。所以,如果 width 和 height 數值相等,那麼實際顯示效果也不會是正方形。

像上面說的那樣子,單純建立完控制元件是無法顯示出來的。為了顯示控制元件,還需要呼叫幾何圖形管理器(geometry manager),如程式碼所示,這裡使用的幾何圖形管理器是 pack。當然也可以選用其它的管理器,在下面的介面佈局主題章節中會專門介紹,繼續看。

看看顯示效果

另外,tkinter 對提供的帶有文字的部分控制元件,比如 Label 等,在範例化時,還有個非常有用的引數 textvariable。這個引數需要傳入 tkinter 提供的特定字串型別的變數。然後,在需要讀取和修改控制元件文字時,可以直接操作傳入引數 textvariable 的變數。舉個栗子

import tkinter as tk

window = tk.Tk()
var_lbl = tk.StringVar()
var_lbl.set("display text with tkinter framework")
lbl = tk.Label(
    master=window,
    fg="white",
    bg="black",
    width=40,
    height=10,
    textvariable=var_lbl
    )
lbl.pack()
print(f"{var_lbl.get()}")
window.mainloop()

通過 tkinter 提供的 StringVar() 生成特殊字串型別的量賦給變數 var_lbl,然後傳給控制元件範例化的引數 textvariable。在讀取控制元件 Label 的文字時,可通過 var_lbl.get() 獲取。如果需要修改控制元件的文字,可通過 var_lbl.set() 傳入字串即可。

執行的程式介面和上面的無異,但是命令終端會有輸出

(.venv) D:\englyf\python>python main.py
display text with tkinter framework

Button 按鍵

在介面中,為了觸發某些動作,一般通過點選按鍵來啟動。那麼,tkinter 是怎麼新增按鍵控制元件?

下面舉個栗子,新增一個帶有文字顯示 Click me! 的按鍵。

import tkinter as tk

window = tk.Tk()
btn = tk.Button(
    text="Click me!",
    width=25,
    height=5,
    bg="blue",
    fg="yellow"
    )
btn.pack()
window.mainloop()

引數 text 輸入顯示的文字字串,引數 width 輸入控制元件寬度,引數 height 輸入控制元件高度,引數 bg 輸入代表背景顏色的名字,引數 fg 輸入代表字型顏色的名字。

要注意的是,上面用到的引數 width 和引數 height 的單位同樣是文字單位。

控制元件 Button 同樣支援引數 textvariable。

看看顯示效果

然後,你可能有疑問,程式碼中為什麼沒看到觸發動作的內容?莫慌!這個其實屬於互動的範疇,在下面的互動章節有專門介紹,繼續看。

Frame 矩形區域

一般介面中,為了顯示豐富的功能,經常需要把各種各樣的控制元件組合在一起,那麼就需要有控制元件充當組合貼上板功能,而控制元件 Frame 剛好可以擔起這個責任。

控制元件 Frame 用於組合相關控制元件,或者在控制元件之間提供填充的矩形區域,所以 Frame 是控制元件容器,也屬於佈局的內容,這裡提前說說看,方便後邊參照控制元件 Frame 對其它控制元件的演示。下面舉個栗子,在控制元件 Frame 上新增靜態標籤 Label 和按鍵 Button 各一個。

import tkinter as tk

window = tk.Tk()
frame = tk.Frame()
label = tk.Label(
    master=frame,
    text="I'm a label in Frame"
    )
label.pack()
button = tk.Button(
    master=frame,
    text="I'm a button in Frame"
    )
button.pack()
frame.pack()
window.mainloop()

為了把控制元件 Label 和 Button 貼上到控制元件容器 Frame 中,只需要把控制元件容器 Frame 的範例參照賦值給各個控制元件的範例化引數 master 即可。相當於為各個控制元件指定父控制元件,那麼這裡的控制元件 Label 和 Button 也被稱之為子控制元件。

道理類似於:一個孩子只能有一個父親,一個父親卻可以有多個孩子。

看看顯示效果

可以看到,控制元件 Label 排在控制元件 Button 的上面,那麼怎麼反過來呢?

import tkinter as tk

window = tk.Tk()
frame = tk.Frame()
label = tk.Label(
    master=frame,
    text="I'm a label in Frame"
    )
button = tk.Button(
    master=frame,
    text="I'm a button in Frame"
    )
button.pack()
label.pack()
frame.pack()
window.mainloop()

看看顯示效果

Entry 單行輸入框

介面中一般會有一些輸入框,比如現在要介紹的單行文字輸入框控制元件 Entry。如果輸入的內容比較少,那麼就適合使用這個控制元件 Entry。

下面舉個栗子,新增一個單行文字輸入框。

import tkinter as tk

window = tk.Tk()
entry = tk.Entry(
    fg="yellow",
    bg="blue",
    width=50
    )
entry.pack()
window.mainloop()

範例化單行輸入框控制元件,引數 fg 表示字型顏色,引數 bg 表示背景色,引數 width 也是文字單元的寬度。與其關注輸入控制元件的樣色,不如關心一下怎麼從輸入控制元件讀取內容。

獲取全部內容,使用 get()。

清空控制元件的內容,使用 delete()。輸入引數 first 和 last 設定刪除的字元索引範圍,從 first 開始到 last 結束,不包括 last。last 可以忽略,也可以填 tk.END,表示刪除內容到最後位置。

插入內容,使用 insert()。輸入引數 index 和 string 設定在索引 index 處,插入內容 string。

控制元件 Entry 同樣支援引數 textvariable。

看看顯示效果

Text 多行輸入框

再來看看多行輸入框控制元件 Text。如果輸入的內容比較多,需要換行才能比較好地顯示,那麼就適合使用這個控制元件 Text。

下面舉個栗子,新增一個多行文字輸入框。

import tkinter as tk

window = tk.Tk()
text = tk.Text(
    fg="yellow",
    bg="blue",
    width=50
    )
text.pack()
window.mainloop()

範例化多行輸入框控制元件,輸入的引數和控制元件 Entry 類似,這裡略過了。重點說一下對這個控制元件的內容讀寫操作。

獲取內容,使用 get()。如果沒有輸入引數,會引起程式執行異常。因為這個方法至少需要輸入一個引數 index,用於表示獲取的開始位置。還可以輸入多一個引數 index,用於表示獲取的結束位置,此引數可忽略,若忽略則表示獲取內容到最後結束位置。

清空控制元件的內容,使用 delete()。

插入內容,使用 insert()。輸入引數 index 和 chars 設定在索引 index 處,插入內容 chars。index 可以使用類似 <line>.<column> 的格式,比如

text.insert("1.2", "Hello")

上面的程式碼,表示在第1行2列處,插入字串 Hello

看看顯示效果

Spinbox 範圍輸入框

在有些介面中,也時常會看到有些輸入框,只能從指定範圍內選取值,並且右側有向上或向下的箭頭按鈕,點選向上或向下的箭頭可按照步進值對輸入框中的值加或減,但不能超過設定的範圍值。

下面舉個栗子,新增一個這樣子的輸入框,並且輸入範圍限定在0, 100之間,步進為1。

import tkinter as tk

window = tk.Tk()
spinbox = tk.Spinbox(
    master=window,
    from_=0,
    to=100,
    increment=1
    )
spinbox.pack()
window.mainloop()

範例化控制元件 Spinbox,引數 from_ 輸入範圍的最小值,引數 to 輸入範圍的最大值,引數 increment 設定步進值。

獲取內容,使用 get(),返回值是輸入框中的字串。

刪除輸入框中的內容,使用 delete()。輸入引數 first 和 last,分別指定開始字元的索引和結束字元的索引。如果忽略 last,那麼預設 last = first+1。

插入內容,使用 insert()。輸入引數 index 和 s,index 代表開始插入的索引,s 表示插入的字串。

控制元件 Spinbox 同樣支援引數 textvariable。

看看顯示效果


由於篇幅受限,本系列教學還未完結,下一篇《Python 內建介面開發框架 Tkinter入門篇 乙》將在本公眾號稍後推播,如果你對此教學有興趣或者想和我一起交流更多精彩內容,歡迎關注我的微信公眾號 【englyf】,等著你哦!