tkinter
--- Tcl/Tk 的 Python 介面¶
tkinter
套件(「Tk 介面」)是 Tcl/Tk GUI 工具集的標準 Python 介面。Tk 和tkinter
在大多數 Unix 平台(包含 macOS)以及 Windows 系統上都可以使用。
從命令列執行python-mtkinter
應該會開啟一個展示簡單 Tk 介面的視窗,讓你知道tkinter
已正確安裝在你的系統上,並且也會顯示已安裝的 Tcl/Tk 版本,這樣你就可以閱讀該版本專屬的 Tcl/Tk 文件。
Tkinter 支援一系列的 Tcl/Tk 版本,這些版本可以是有或沒有執行緒支援的建構版本。官方的 Python 二進位發行版捆綁了有執行緒支援的 Tcl/Tk 8.6。關於支援版本的更多資訊,請參閱_tkinter
模組的原始碼。
Tkinter 並非一個輕薄的包裝器,而是加入了相當多自身的邏輯,使其體驗更具 Python 風格(pythonic)。本文件將著重於這些新增和變更,對於未變更的細節,則會引導讀者參閱官方的 Tcl/Tk 文件。
備註
Tcl/Tk 8.5(2007)引入了一套現代化的主題式使用者介面元件,以及一個用以操作它們的新 API。新舊 API 目前都還能使用。你在網路上找到的大多數文件仍使用舊版 API,而且可能已經嚴重過時。
也參考
- TkDocs
關於使用 Tkinter 建立使用者介面的詳盡教學。內容解釋了關鍵概念,並使用現代 API 來說明建議的方法。
- Tkinter 8.5 reference: a GUI for Python
Tkinter 8.5 的參考文件,詳細說明了可用的類別、方法和選項。
Tcl/Tk 相關資源:
書籍:
- Modern Tkinter for Busy Python Developers
由 Mark Roseman 所著。(ISBN 978-1999149567)
- Python GUI programming with Tkinter
由 Alan D. Moore 所著。(ISBN 978-1788835886)
- Programming Python
由 Mark Lutz 所著;對 Tkinter 有極佳的涵蓋。(ISBN 978-0596158101)
- Tcl and the Tk Toolkit (2nd edition)
由 Tcl/Tk 發明者 John Ousterhout 與 Ken Jones 所著;不包含 Tkinter。(ISBN 978-0321336330)
架構¶
Tcl/Tk 並非單一函式庫,而是由幾個不同的模組所組成,每個模組都有獨立的功能和官方文件。Python 的二進位發行版也隨附了一個附加模組。
- Tcl
Tcl 是一個動態直譯的程式語言,就像 Python 一樣。雖然它可以作為通用程式語言獨立使用,但它最常被嵌入到 C 應用程式中,作為腳本引擎或 Tk 工具集的介面。Tcl 函式庫有一個 C 介面,可用於建立和管理一個或多個 Tcl 直譯器的實例,在這些實例中執行 Tcl 指令和腳本,並新增以 Tcl 或 C 實作的自訂指令。每個直譯器都有一個事件佇列,並有設施可以向其傳送事件並加以處理。與 Python 不同,Tcl 的執行模型是圍繞著協同多工(cooperative multitasking)設計的,而 Tkinter 則彌合了這種差異(詳情請參閱Threading model)。
- Tk
Tk 是一個以 C 實作的Tcl 套件,它新增了自訂指令來建立和操作 GUI 元件。每個
Tk
物件都嵌入了自己載入 Tk 的 Tcl 直譯器實例。Tk 的元件非常可自訂,但代價是外觀較為過時。Tk 使用 Tcl 的事件佇列來產生和處理 GUI 事件。- Ttk
主題式 Tk(Ttk)是較新的一族 Tk 元件,相較於許多傳統的 Tk 元件,它在不同平台上提供了更好的外觀。從 Tk 8.5 版開始,Ttk 作為 Tk 的一部分發行。Python 的繫結(bindings)則在一個獨立的模組
tkinter.ttk
中提供。
在內部,Tk 和 Ttk 使用底層作業系統的設施,即 Unix/X11 上的 Xlib、macOS 上的 Cocoa、Windows 上的 GDI。
當你的 Python 應用程式使用 Tkinter 中的類別(例如,建立一個元件)時,tkinter
模組會先組合一個 Tcl/Tk 指令字串。它將該 Tcl 指令字串傳遞給一個內部的_tkinter
二進位模組,後者再呼叫 Tcl 直譯器來對其進行計算。Tcl 直譯器接著會呼叫 Tk 和/或 Ttk 套件,而這些套件又會再呼叫 Xlib、Cocoa 或 GDI。
Tkinter 模組¶
對 Tkinter 的支援分散在數個模組中。大多數應用程式將需要主要的tkinter
模組,以及tkinter.ttk
模組,後者提供了現代主題式元件集和 API:
fromtkinterimport*fromtkinterimportttk
- classtkinter.Tk(screenName=None,baseName=None,className='Tk',useTk=True,sync=False,use=None)¶
建構一個頂層 Tk 元件,它通常是應用程式的主視窗,並為此元件初始化一個 Tcl 直譯器。每個實例都有其自己關聯的 Tcl 直譯器。
Tk
類別通常使用所有預設值來實例化。然而,目前可辨識下列關鍵字引數:- screenName
當給定(作為字串)時,設定
DISPLAY
環境變數。(僅限 X11)- baseName
設定檔的名稱。預設情況下,baseName 是從程式名稱(
sys.argv[0]
)衍生而來。- className
元件類別的名稱。用作設定檔,也用作呼叫 Tcl 時的名稱(interp 中的argv0)。
- useTk
若為
True
,則初始化 Tk 子系統。tkinter.Tcl()
函式會將此設定為False
。- sync
若為
True
,則同步執行所有 X 伺服器指令,以便立即回報錯誤。可用於偵錯。(僅限 X11)- use
指定要嵌入應用程式的視窗id,而不是將其建立為獨立的頂層視窗。id 必須以與頂層元件的 -use 選項值相同的方式指定(也就是說,其形式類似
winfo_id()
回傳的形式)。請注意,在某些平台上,只有當id 指向一個已啟用 -container 選項的 Tk 框架或頂層視窗時,此功能才能正常運作。
Tk
會讀取名為.className.tcl
和.baseName.tcl
的設定檔,並在 Tcl 直譯器中進行直譯,並對.className.py
和.baseName.py
的內容呼叫exec()
。設定檔的路徑是HOME
環境變數,如果未定義,則是os.curdir
。
- tkinter.Tcl(screenName=None,baseName=None,className='Tk',useTk=False)¶
Tcl()
函式是一個工廠函式,它建立的物件與Tk
類別建立的物件非常相似,只是它不會初始化 Tk 子系統。這在驅動 Tcl 直譯器時最為有用,尤其是在不希望建立額外頂層視窗的環境中,或者在無法建立的環境中(例如沒有 X 伺服器的 Unix/Linux 系統)。由Tcl()
物件建立的物件可以透過呼叫其loadtk()
方法來建立一個頂層視窗(並初始化 Tk 子系統)。
提供 Tk 支援的模組包括:
tkinter
主要的 Tkinter 模組。
tkinter.colorchooser
讓使用者選擇顏色的對話方塊。
tkinter.commondialog
此處列出的其他模組中定義的對話方塊的基底類別。
tkinter.filedialog
讓使用者指定要開啟或儲存的檔案的通用對話方塊。
tkinter.font
協助處理字型的工具程式。
tkinter.messagebox
存取標準的 Tk 對話方塊。
tkinter.scrolledtext
內建垂直捲軸的文字元件。
tkinter.simpledialog
基本的對話方塊和便利函式。
tkinter.ttk
在 Tk 8.5 中引入的主題式元件集,為主
tkinter
模組中的許多傳統元件提供了現代化的替代方案。
額外模組:
Tkinter 應急指南¶
本節並非旨在成為 Tk 或 Tkinter 的詳盡教學。為此,請參閱前面提到的外部資源之一。相反地,本節提供了一個快速導覽,介紹 Tkinter 應用程式的外觀、識別基礎的 Tk 概念,並解釋 Tkinter 包裝器的結構。
本節的其餘部分將幫助你識別在 Tkinter 應用程式中所需的類別、方法和選項,以及在哪裡可以找到關於它們的更詳細文件,包括在官方的 Tcl/Tk 參考手冊中。
一個 Hello World 程式¶
我們將從一個 Tkinter 的 "Hello World" 應用程式開始。這不是我們能寫出的最小程式,但足以說明一些你需要知道的關鍵概念。
fromtkinterimport*fromtkinterimportttkroot=Tk()frm=ttk.Frame(root,padding=10)frm.grid()ttk.Label(frm,text="Hello World!").grid(column=0,row=0)ttk.Button(frm,text="Quit",command=root.destroy).grid(column=1,row=0)root.mainloop()
在引入之後,下一行建立了一個Tk
類別的實例,它會初始化 Tk 並建立其關聯的 Tcl 直譯器。它還會建立一個頂層視窗,稱為根視窗,作為應用程式的主視窗。
接下來的一行建立了一個框架元件,在本例中,它將包含我們接下來要建立的一個標籤和一個按鈕。該框架被放置在根視窗內。
下一行建立了一個包含靜態文字字串的標籤元件。grid()
方法用於指定標籤在其包含的框架元件中的相對佈局(位置),類似於 HTML 中表格的運作方式。
然後建立一個按鈕元件,並放置在標籤的右側。當按下時,它將呼叫根視窗的destroy()
方法。
最後,mainloop()
方法將所有內容顯示在螢幕上,並回應使用者輸入,直到程式終止。
重要的 Tk 概念¶
即使是這個簡單的程式也說明了以下關鍵的 Tk 概念:
- 元件(widgets)
一個 Tkinter 使用者介面是由個別的元件所組成。每個元件都表示為一個 Python 物件,從
ttk.Frame
、ttk.Label
和ttk.Button
等類別實例化而來。- 元件階層(widget hierarchy)
元件被安排在一個階層中。標籤和按鈕被包含在一個框架內,而框架又被包含在根視窗內。在建立每個子元件時,其父元件會作為第一個引數傳遞給元件的建構函式。
- 設定選項(configuration options)
元件具有設定選項,可以修改其外觀和行為,例如在標籤或按鈕中顯示的文字。不同類別的元件會有不同的選項集。
- 佈局管理(geometry management)
元件在建立時不會自動新增到使用者介面中。像
grid
這樣的佈局管理器(geometry manager)會控制它們在使用者介面中的放置位置。- 事件迴圈(event loop)
Tkinter 只有在主動執行事件迴圈時,才會對使用者輸入、程式的變更,甚至螢幕刷新做出反應。如果你的程式沒有執行事件迴圈,你的使用者介面將不會更新。
了解 Tkinter 如何包裝 Tcl/Tk¶
當你的應用程式使用 Tkinter 的類別和方法時,Tkinter 內部正在組合代表 Tcl/Tk 指令的字串,並在附加到你應用程式Tk
實例的 Tcl 直譯器中執行這些指令。
無論是試圖瀏覽參考文件、尋找正確的方法或選項、改寫一些現有程式碼,還是偵錯你的 Tkinter 應用程式,在某些時候,了解那些底層 Tcl/Tk 指令的樣貌會很有幫助。
為了說明,以下是上面 Tkinter 腳本主要部分的 Tcl/Tk 對等程式碼。
ttk::frame.frm-padding10grid.frmgrid[ttk::label.frm.lbl-text"Hello World!"]-column0-row0grid[ttk::button.frm.btn-text"Quit"-command"destroy ."]-column1-row0
Tcl 的語法類似於許多 shell 語言,第一個字是要執行的指令,後面跟著該指令的引數,以空格分隔。在不深入太多細節的情況下,請注意以下幾點:
用於建立元件的指令(如
ttk::frame
)對應於 Tkinter 中的元件類別。Tcl 元件選項(如
-text
)對應於 Tkinter 中的關鍵字引數。在 Tcl 中,元件是透過路徑名稱(如
.frm.btn
)來參照,而 Tkinter 不使用名稱,而是使用物件參照。元件在元件階層中的位置被編碼在其(階層式)路徑名稱中,該路徑名稱使用
.
(點)作為路徑分隔符。根視窗的路徑名稱就是.
(點)。在 Tkinter 中,階層不是由路徑名稱定義的,而是在建立每個子元件時指定父元件來定義的。在 Tcl 中實作為獨立指令的操作(如
grid
或destroy
),在 Tkinter 中則表示為元件物件上的方法。正如你稍後會看到的,在其他時候,Tcl 使用的看起來像是對元件物件的方法呼叫,這更接近 Tkinter 中的用法。
我該如何...?哪個選項可以...?¶
如果你不確定如何在 Tkinter 中做某件事,並且無法立即在你正在使用的教學或參考文件中找到它,這裡有一些可能有幫助的策略。
首先,請記住,個別元件的運作細節可能會因 Tkinter 和 Tcl/Tk 的不同版本而異。如果你正在搜尋文件,請確保它對應於你系統上安裝的 Python 和 Tcl/Tk 版本。
在搜尋如何使用 API 時,知道你正在使用的類別、選項或方法的確切名稱會很有幫助。自省(Introspection),無論是在互動式 Python shell 中還是使用print()
,都可以幫助你識別所需內容。
要找出任何元件上有哪些可用的設定選項,請呼叫其configure()
方法,該方法會回傳一個字典,其中包含有關每個物件的各種資訊,包括其預設值和目前值。使用keys()
僅取得每個選項的名稱。
btn=ttk.Button(frm,...)print(btn.configure().keys())
由於大多數元件有許多共通的設定選項,找出特定於某個元件類別的選項會很有用。將選項串列與像框架這樣較簡單的元件的選項串列進行比較,是做到這一點的一種方法。
print(set(btn.configure().keys())-set(frm.configure().keys()))
同樣地,你可以使用標準的dir()
函式來尋找元件物件可用的方法。如果你試一下,你會看到有超過 200 個常見的元件方法,所以再次強調,識別特定於某個元件類別的方法是很有幫助的。
print(dir(btn))print(set(dir(btn))-set(dir(frm)))
瀏覽 Tcl/Tk 參考手冊¶
如前所述,官方的Tk 指令 參考手冊(man pages)通常是對元件上特定操作作用的最準確描述。即使你知道所需選項或方法的名稱,你可能仍有幾個地方需要查看。
雖然 Tkinter 中的所有操作都實作為對元件物件的方法呼叫,但你已經看到許多 Tcl/Tk 操作顯示為指令,這些指令將元件路徑名稱作為其第一個參數,後面跟著可選的參數,例如:
destroy.grid.frm.btn-column0-row0
然而,其他的看起來更像是對元件物件呼叫的方法(事實上,當你在 Tcl/Tk 中建立一個元件時,它會建立一個以元件路徑名稱為名的 Tcl 指令,該指令的第一個參數是要呼叫的方法名稱)。
.frm.btninvoke.frm.lblconfigure-text"Goodbye"
在官方的 Tcl/Tk 參考文件中,你會在特定元件的 man page 上找到大多數看起來像方法呼叫的操作(例如,你可以在ttk::button man page 上找到invoke()
方法),而將元件作為參數的函式通常有自己的 man page(例如grid)。
你可以在options 或ttk::widget man page 中找到許多常見的選項和方法,而其他的則在特定元件類別的 man page 中找到。
你還會發現許多 Tkinter 方法有複合名稱,例如winfo_x()
、winfo_height()
、winfo_viewable()
。你可以在winfo man page 中找到所有這些文件的說明。
備註
有點令人困惑的是,所有 Tkinter 元件上還有一些方法,它們實際上並不是對該元件進行操作,而是在全域範圍內操作,獨立於任何元件。例如存取剪貼簿或系統鈴聲的方法。(它們恰好被實作為所有 Tkinter 元件都繼承的基底Widget
類別中的方法)。
執行緒模型¶
Python 和 Tcl/Tk 有非常不同的執行緒模型,tkinter
試圖彌合這種差異。如果你使用執行緒,你可能需要意識到這一點。
一個 Python 直譯器可能有多個與之關聯的執行緒。在 Tcl 中,可以建立多個執行緒,但每個執行緒都有一個獨立的 Tcl 直譯器實例與之關聯。執行緒也可以建立多個直譯器實例,但每個直譯器實例只能由建立它的那個執行緒使用。
由tkinter
建立的每個Tk
物件都包含一個 Tcl 直譯器。它還會追蹤是哪個執行緒建立了該直譯器。可以從任何 Python 執行緒呼叫tkinter
。在內部,如果呼叫來自建立Tk
物件的執行緒以外的執行緒,則會將一個事件發佈到直譯器的事件佇列中,執行後,結果會回傳給呼叫的 Python 執行緒。
Tcl/Tk 應用程式通常是事件驅動的,這意味著在初始化之後,直譯器會執行一個事件迴圈(即Tk.mainloop()
)並回應事件。因為它是單執行緒的,事件處理常式必須快速回應,否則它們會阻塞其他事件的處理。為避免這種情況,任何長時間執行的計算都不應在事件處理常式中執行,而是使用計時器將其分解成更小的部分,或在另一個執行緒中執行。這與許多 GUI 工具集不同,在那些工具集中,GUI 在一個與所有應用程式碼(包括事件處理常式)完全分離的執行緒中執行。
如果 Tcl 直譯器沒有在執行事件迴圈和處理事件,那麼從執行 Tcl 直譯器的執行緒以外的執行緒發出的任何tkinter
呼叫都將失敗。
存在一些特殊情況:
Tcl/Tk 函式庫可以被建構成不具備執行緒感知能力。在這種情況下,
tkinter
會從原始的 Python 執行緒呼叫該函式庫,即使這與建立 Tcl 直譯器的執行緒不同。一個全域鎖確保一次只發生一個呼叫。雖然
tkinter
允許你建立多個Tk
物件的實例(每個都有自己的直譯器),但屬於同一個執行緒的所有直譯器共享一個共同的事件佇列,這很快就會變得混亂。在實務上,不要一次建立多個Tk
的實例。否則,最好在不同的執行緒中建立它們,並確保你正在執行一個具備執行緒感知能力的 Tcl/Tk 建構版本。阻塞事件處理常式並不是防止 Tcl 直譯器重新進入事件迴圈的唯一方法。甚至可以執行多個巢狀的事件迴圈或完全放棄事件迴圈。如果你在事件或執行緒方面做任何複雜的操作,請注意這些可能性。
目前有少數幾個
tkinter
函式只有在從建立 Tcl 直譯器的執行緒中呼叫時才能正常運作。
實用參考¶
設定選項¶
選項控制著諸如元件的顏色和邊框寬度等。選項可以透過三種方式設定:
- 在物件建立時,使用關鍵字引數
fred=Button(self,fg="red",bg="blue")
- 在物件建立後,將選項名稱視為字典索引
fred["fg"]="red"fred["bg"]="blue"
- 在物件建立後,使用 config() 方法更新多個屬性
fred.config(fg="red",bg="blue")
有關給定選項及其行為的完整解釋,請參閱相關元件的 Tk man pages。
請注意,man pages 為每個元件列出了「標準選項」和「元件特定選項」。前者是許多元件共有的選項串列,後者是該特定元件特有的選項。標準選項記錄在options(3) man page 中。
本文件中未對標準選項和元件特定選項進行區分。某些選項不適用於某些類型的元件。給定元件是否回應特定選項取決於該元件的類別;按鈕有command
選項,標籤則沒有。
給定元件支援的選項列在該元件的 man page 中,或者可以在 runtime 透過不帶引數呼叫config()
方法,或對該元件呼叫keys()
方法來查詢。這些呼叫的回傳值是一個字典,其鍵是選項名稱的字串(例如'relief'
),其值是 5-tuples。
某些選項,如bg
,是具有長名稱的常見選項的同義詞(bg
是 "background" 的簡寫)。將簡寫選項的名稱傳遞給config()
方法將回傳一個 2-tuple,而不是 5-tuple。回傳的 2-tuple 將包含同義詞的名稱和「真實」選項(例如('bg','background')
)。
索引 | 含義 | 範例 |
---|---|---|
0 | 選項名稱 |
|
1 | 用於資料庫查詢的選項名稱 |
|
2 | 用於資料庫查詢的選項類別 |
|
3 | 預設值 |
|
4 | 目前值 |
|
範例:
>>>print(fred.config()){'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}
當然,印出的字典將包含所有可用的選項及其值。這僅作為一個範例。
Packer 佈局管理器¶
packer 是 Tk 的佈局管理(geometry manager)機制之一。佈局管理器(geometry manager)用於指定元件在其容器(它們共同的master)內的相對位置。與較為繁瑣的placer(較不常用,我們在此不予介紹)相比,packer 採用定性的關係規範——上方、左方、填滿等——並為你計算出確切的放置座標。
任何master 元件的大小由其內部的「slave 元件」的大小決定。packer 用於控制 slave 元件在被 packed 的 master 內部出現的位置。你可以將元件 pack 到框架中,再將框架 pack 到其他框架中,以達到你想要的佈局。此外,一旦 packed,佈局會動態調整以適應設定的增量變更。
請注意,元件在透過佈局管理器(geometry manager)指定其佈局(geometry)之前是不會出現的。一個常見的早期錯誤是忽略了佈局(geometry)指定,然後在元件被建立但沒有任何東西出現時感到驚訝。一個元件只有在例如 packer 的pack()
方法被應用於其上之後才會出現。
pack() 方法可以與關鍵字選項/值對一起呼叫,以控制元件在其容器中出現的位置,以及當主應用程式視窗調整大小時它的行為方式。以下是一些範例:
fred.pack()# 預設為 side = "top"fred.pack(side="left")fred.pack(expand=1)
Packer 選項¶
有關 packer 及其可接受選項的更詳盡資訊,請參閱 man pages 和 John Ousterhout 書中的第 183 頁。
- anchor
錨點類型。表示 packer 將每個 slave 放置在其區域中的位置。
- expand
布林值,
0
或1
。- fill
合法值:
'x'
、'y'
、'both'
、'none'
。- ipadx 和 ipady
一個距離——指定 slave 元件每側的內部填充。
- padx 和 pady
一個距離——指定 slave 元件每側的外部填充。
- side
合法值為:
'left'
、'right'
、'top'
、'bottom'
。
耦合元件變數¶
某些元件(如文字輸入元件)的當前值設定可以透過使用特殊選項直接連接到應用程式變數。這些選項是variable
、textvariable
、onvalue
、offvalue
和value
。這種連接是雙向的:如果變數因任何原因發生變化,與之連接的元件將會更新以反映新值。
不幸的是,在tkinter
的目前實作中,無法透過variable
或textvariable
選項將任意的 Python 變數傳遞給元件。唯一適用此功能的變數類型是從tkinter
中定義的一個名為 Variable 的類別繼承的子類別變數。
已經定義了許多有用的 Variable 子類別:StringVar
、IntVar
、DoubleVar
和BooleanVar
。要讀取此類變數的目前值,請對其呼叫get()
方法,要更改其值,則呼叫set()
方法。如果你遵循此協定,元件將始終追蹤變數的值,無需你進一步干預。
舉例來說:
importtkinterastkclassApp(tk.Frame):def__init__(self,master):super().__init__(master)self.pack()self.entrythingy=tk.Entry()self.entrythingy.pack()# 建立應用程式變數。self.contents=tk.StringVar()# 將其設定為某個值。self.contents.set("this is a variable")# 告訴 entry 元件監視此變數。self.entrythingy["textvariable"]=self.contents# 為使用者按下 return 鍵定義一個回呼。# 它會印出變數的目前值。self.entrythingy.bind('<Key-Return>',self.print_contents)defprint_contents(self,event):print("Hi. The current entry content is:",self.contents.get())root=tk.Tk()myapp=App(root)myapp.mainloop()
視窗管理器¶
在 Tk 中,有一個工具指令wm
,用於與視窗管理器互動。wm
指令的選項允許你控制標題、位置、圖示點陣圖等。在tkinter
中,這些指令已實作為Wm
類別上的方法。頂層元件是Wm
類別的子類別,因此可以直接呼叫Wm
方法。
要取得包含給定元件的頂層視窗,你通常可以直接參照該元件的 master。當然,如果該元件被 packed 在一個框架內,master 將不代表一個頂層視窗。要取得包含任意元件的頂層視窗,你可以呼叫_root()
方法。此方法以底線開頭,表示此函式是實作的一部分,而不是 Tk 功能的介面。
以下是一些常見用法範例:
importtkinterastkclassApp(tk.Frame):def__init__(self,master=None):super().__init__(master)self.pack()# 建立應用程式myapp=App()## 以下是對視窗管理器類別的方法呼叫#myapp.master.title("My Do-Nothing Application")myapp.master.maxsize(1000,400)# 啟動程式myapp.mainloop()
Tk 選項資料型別¶
- anchor
合法值為羅盤方位點:
"n"
、"ne"
、"e"
、"se"
、"s"
、"sw"
、"w"
、"nw"
,以及"center"
。- bitmap
有八個內建的、命名的點陣圖:
'error'
、'gray25'
、'gray50'
、'hourglass'
、'info'
、'questhead'
、'question'
、'warning'
。要指定一個 X 點陣圖檔名,請給出檔案的完整路徑,並在前面加上一個@
,例如"@/usr/contrib/bitmap/gumby.bit"
。- boolean
你可以傳遞整數 0 或 1,或字串
"yes"
或"no"
。- callback
這是任何不帶引數的 Python 函式。例如:
defprint_it():print("hi there")fred["command"]=print_it
- color
顏色可以以 rgb.txt 檔案中的 X 顏色名稱給出,或以表示 RGB 值的字串給出,範圍可以是 4 位元:
"#RGB"
、8 位元:"#RRGGBB"
、12 位元:"#RRRGGGBBB"
或 16 位元:"#RRRRGGGGBBBB"
,其中 R、G、B 在此代表任何合法的十六進位數字。詳情請參閱 Ousterhout 書中的第 160 頁。- cursor
可以使用
cursorfont.h
中的標準 X 游標名稱,無需XC_
前綴。例如,要取得手形游標(XC_hand2
),請使用字串"hand2"
。你也可以指定自己的點陣圖和遮罩檔案。請參閱 Ousterhout 書中的第 179 頁。- distance
螢幕距離可以以像素或絕對距離指定。像素以數字給出,絕對距離以字串給出,尾隨字元表示單位:
c
代表公分,i
代表英寸,m
代表毫米,p
代表印刷的點。例如,3.5 英寸表示為"3.5i"
。- font
Tk 使用串列字型名稱格式,例如
{courier10bold}
。帶有正數的字型大小以點為單位;帶有負數的大小以像素為單位。- geometry
這是一個
widthxheight
形式的字串,其中 width 和 height 對於大多數元件是以像素為單位(對於顯示文字的元件則以字元為單位)。例如:fred["geometry"]="200x100"
。- justify
合法值為字串:
"left"
、"center"
、"right"
和"fill"
。- region
這是一個由四個以空格分隔的元素組成的字串,每個元素都是一個合法的距離(見上文)。例如:
"2345"
、"3i2i4.5i2i"
和"3c2c4c10.43c"
都是合法的區域。- relief
決定元件的邊框樣式。合法值為:
"raised"
、"sunken"
、"flat"
、"groove"
和"ridge"
。- scrollcommand
這幾乎總是某個捲軸元件的
set()
方法,但也可以是任何接受單一引數的元件方法。- wrap
必須是以下之一:
"none"
、"char"
或"word"
。
繫結與事件¶
來自元件指令的 bind 方法允許你監視某些事件,並在該事件類型發生時觸發一個回呼函式。bind 方法的形式是:
defbind(self,sequence,func,add=''):
其中:
- sequence
是一個表示目標事件類型的字串。(詳情請參閱bind(3tk) man page,以及 John Ousterhout 的書Tcl and the Tk Toolkit (2nd edition) 的第 201 頁)。
- func
是一個 Python 函式,接受一個引數,在事件發生時被呼叫。一個 Event 實例將作為引數傳遞。(以這種方式部署的函式通常稱為回呼。)
- add
是可選的,可以是
''
或'+'
。傳遞一個空字串表示此繫結將取代與此事件關聯的任何其他繫結。傳遞一個'+'
意味著此函式將被新增到繫結到此事件類型的函式串列中。
舉例來說:
defturn_red(self,event):event.widget["activeforeground"]="red"self.button.bind("<Enter>",self.turn_red)
請注意在turn_red()
回呼中如何存取事件的 widget 欄位。此欄位包含捕獲 X 事件的元件。下表列出了你可以存取的其他事件欄位,以及它們在 Tk 中的表示方式,這在參閱 Tk man pages 時可能很有用。
Tk | Tkinter 事件欄位 | Tk | Tkinter 事件欄位 |
---|---|---|---|
%f | focus | %A | char |
%h | height | %E | send_event |
%k | keycode | %K | keysym |
%s | state | %N | keysym_num |
%t | time | %T | type |
%w | width | %W | widget |
%x | x | %X | x_root |
%y | y | %Y | y_root |
index 參數¶
許多元件需要傳遞 "index" 參數。這些參數用於指向 Text 元件中的特定位置、Entry 元件中的特定字元,或 Menu 元件中的特定選單項目。
- Entry 元件索引(index、view index 等)
Entry 元件具有參照所顯示文字中字元位置的選項。你可以使用這些
tkinter
函式來存取文字元件中的這些特殊點:- Text 元件索引
Text 元件的索引表示法非常豐富,在 Tk man pages 中有最好的描述。
- 選單索引(menu.invoke()、menu.entryconfig() 等)
選單的某些選項和方法會操作特定的選單項目。每當選項或參數需要選單索引時,你可以傳入:
一個整數,它參照元件中項目的數字位置,從頂部開始計數,從 0 開始;
字串
"active"
,它參照目前在游標下的選單位置;字串
"last"
,它參照最後一個選單項目;一個以
@
為前綴的整數,如@6
,其中該整數被解釋為選單座標系統中的 y 像素座標;字串
"none"
,表示完全沒有選單項目,最常用於 menu.activate() 以停用所有項目,最後,一個文字字串,它會與從選單頂部掃描到底部的選單項目標籤進行模式匹配。請注意,此索引類型在所有其他類型之後考慮,這意味著標籤為
last
、active
或none
的選單項目的匹配可能會被解釋為上述的字面值。
圖片¶
可以透過tkinter.Image
的相應子類別來建立不同格式的圖片:
BitmapImage
用於 XBM 格式的圖片。PhotoImage
用於 PGM、PPM、GIF 和 PNG 格式的圖片。後者從 Tk 8.6 開始支援。
任一類型的圖片都是透過file
或data
選項建立的(也有其他選項可用)。
在 3.13 版的變更:新增了PhotoImage
方法copy_replace()
,用於將一個區域從一個圖片複製到另一個圖片,可能帶有像素縮放和/或子採樣。將from_coords 參數新增到PhotoImage
方法copy()
、zoom()
和subsample()
。將zoom 和subsample 參數新增到PhotoImage
方法copy()
。
然後,圖片物件可以在任何支援image
選項的元件(例如標籤、按鈕、選單)中使用。在這些情況下,Tk 將不會保留對圖片的參照。當對圖片物件的最後一個 Python 參照被刪除時,圖片資料也會被刪除,Tk 將在使用該圖片的任何地方顯示一個空框。
也參考
Pillow 套件新增了對 BMP、JPEG、TIFF 和 WebP 等格式的支援。
檔案處理常式¶
Tk 允許你註冊和取消註冊一個回呼函式,當檔案描述器上可以進行 I/O 時,該函式將從 Tk 主迴圈中被呼叫。每個檔案描述器只能註冊一個處理常式。範例程式碼:
importtkinterwidget=tkinter.Tk()mask=tkinter.READABLE|tkinter.WRITABLEwidget.tk.createfilehandler(file,mask,callback)...widget.tk.deletefilehandler(file)
此功能在 Windows 上不可用。
由於你不知道有多少位元組可供讀取,你可能不想使用BufferedIOBase
或TextIOBase
的read()
或readline()
方法,因為這些方法會堅持讀取預定義數量的位元組。對於 sockets(通訊端),recv()
或recvfrom()
方法可以正常運作;對於其他檔案,請使用原始讀取或os.read(file.fileno(),maxbytecount)
。
- Widget.tk.createfilehandler(file,mask,func)¶
註冊檔案處理常式回呼函式func。file 引數可以是一個具有
fileno()
方法的物件(例如檔案或 socket(通訊端)物件),或是一個整數檔案描述器。mask 引數是下面三個常數中任意一個的 OR 組合。回呼函式被呼叫的方式如下:callback(file,mask)
- Widget.tk.deletefilehandler(file)¶
取消註冊檔案處理常式。