tkinter
— Python 的 Tcl/Tk 介面¶
tkinter
包(“Tk 介面”)是 Python 對 Tcl/Tk GUI 工具包的標準介面。Tk 和 tkinter
在大多數 Unix 平臺(包括 macOS)以及 Windows 系統上都可用。
從命令列執行 python -m tkinter
應該會開啟一個演示簡單 Tk 介面的視窗,讓你知道 tkinter
已在你的系統上正確安裝,並顯示已安裝的 Tcl/Tk 版本,以便你可以閱讀該版本對應的 Tcl/Tk 文件。
Tkinter 支援一系列 Tcl/Tk 版本,無論是否帶有執行緒支援。Python 官方二進位制發行版捆綁了 Tcl/Tk 8.6 執行緒版。有關支援版本的更多資訊,請參閱 _tkinter
模組的原始碼。
Tkinter 不是一個薄封裝層,而是增加了相當多的自有邏輯,以使體驗更符合 Python 風格。本文件將重點介紹這些增補和改動,對於未變動的細節,將引述官方 Tcl/Tk 文件。
備註
Tcl/Tk 8.5(2007年)引入了一套現代化的主題使用者介面元件以及使用它們的新 API。新舊 API 仍然可用。你在網上找到的大多數文件仍然使用舊 API,可能已經嚴重過時。
參見
- TkDocs
關於使用 Tkinter 建立使用者介面的詳盡教程。解釋了關鍵概念,並使用現代 API 闡述了推薦的方法。
- Tkinter 8.5 參考:一個用於 Python 的 GUI
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 的執行模型是圍繞協作式多工設計的,Tkinter 彌合了這一差異(詳見執行緒模型)。
- Tk
Tk 是一個用 C 實現的 Tcl 包,它添加了用於建立和操作 GUI 部件的自定義命令。每個
Tk
物件都內嵌了自己載入了 Tk 的 Tcl 直譯器例項。Tk 的部件具有高度可定製性,但代價是外觀略顯陳舊。Tk 使用 Tcl 的事件佇列來生成和處理 GUI 事件。- Ttk
主題化 Tk (Ttk) 是一個較新的 Tk 部件系列,相比許多經典的 Tk 部件,它在不同平臺上提供了更好的外觀。Ttk 作為 Tk 的一部分分發,從 Tk 8.5 版本開始。Python 繫結在單獨的模組
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。
from tkinter import *
from tkinter import ttk
- class tkinter.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 系統)的環境中,通常最有用。透過呼叫其loadtk()
方法,可以為由Tcl()
物件建立的物件建立一個 Toplevel 視窗(並初始化 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" 應用程式開始。這並非我們能寫出的最小巧的程式,但它足以說明一些你需要知道的關鍵概念。
from tkinter import *
from tkinter import ttk
root = 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 直譯器。它還會建立一個頂層視窗,稱為根視窗,作為應用程式的主視窗。
下面這行建立了一個框架(frame)部件,在本例中它將包含我們接下來要建立的一個標籤和一個按鈕。該框架被放置在根視窗內。
下一行建立了一個包含靜態文字字串的標籤部件。grid()
方法用於指定標籤在其包含的框架部件中的相對佈局(位置),類似於 HTML 中的表格工作方式。
接著建立了一個按鈕部件,並放置在標籤的右側。當按下時,它將呼叫根視窗的 destroy()
方法。
最後,mainloop()
方法將所有內容顯示在螢幕上,並響應使用者輸入,直到程式終止。
重要的 Tk 概念¶
即使是這個簡單的程式也闡釋了以下關鍵的 Tk 概念:
- 部件 (widgets)
一個 Tkinter 使用者介面由單個的 *部件* 組成。每個部件都表示為一個 Python 物件,從諸如
ttk.Frame
、ttk.Label
和ttk.Button
這樣的類例項化。- 部件層級 (widget hierarchy)
部件以*層級結構*排列。標籤和按鈕包含在一個框架中,該框架又包含在根視窗中。在建立每個*子*部件時,其*父*部件作為第一個引數傳遞給部件建構函式。
- 配置選項 (configuration options)
部件具有*配置選項*,用於修改其外觀和行為,例如標籤或按鈕中要顯示的文字。不同類別的部件將有不同的選項集。
- 幾何管理器 (geometry management)
部件在建立時不會自動新增到使用者介面。像
grid
這樣的*幾何管理器*控制它們在使用者介面中的放置位置。- 事件迴圈 (event loop)
Tkinter 只有在主動執行 *事件迴圈* 時,才會對使用者輸入、程式更改甚至重新整理顯示作出反應。如果你的程式沒有執行事件迴圈,你的使用者介面將不會更新。
理解 Tkinter 如何封裝 Tcl/Tk¶
當你的應用程式使用 Tkinter 的類和方法時,Tkinter 內部正在組裝表示 Tcl/Tk 命令的字串,並在附加到你應用程式的 Tk
例項的 Tcl 直譯器中執行這些命令。
無論是在查閱參考文件、試圖找到正確的方法或選項、調整一些現有程式碼,還是除錯你的 Tkinter 應用程式,有時理解那些底層的 Tcl/Tk 命令長什麼樣會很有用。
為了說明這一點,這裡是上面 Tkinter 指令碼主要部分的 Tcl/Tk 等價物。
ttk::frame .frm -padding 10
grid .frm
grid [ttk::label .frm.lbl -text "Hello World!"] -column 0 -row 0
grid [ttk::button .frm.btn -text "Quit" -command "destroy ."] -column 1 -row 0
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 時,知道你正在使用的類、選項或方法的確切名稱會很有幫助。在互動式 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)))
執行緒模型¶
Python 和 Tcl/Tk 有非常不同的執行緒模型,tkinter
試圖彌合這一差異。如果你使用執行緒,你可能需要注意這一點。
一個 Python 直譯器可以關聯多個執行緒。在 Tcl 中,可以建立多個執行緒,但每個執行緒都關聯一個獨立的 Tcl 直譯器例項。執行緒也可以建立多個直譯器例項,但每個直譯器例項只能由建立它的那個執行緒使用。
每個由 tkinter
建立的 Tk
物件都包含一個 Tcl 直譯器。它還跟蹤是哪個執行緒建立了該直譯器。對 tkinter
的呼叫可以從任何 Python 執行緒進行。在內部,如果一個呼叫來自建立 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 手冊頁。
請注意,手冊頁為每個部件列出了“標準選項”和“部件特定選項”。前者是許多部件共有的選項列表,後者是該特定部件特有的選項。“標準選項”記錄在 options(3) 手冊頁上。
本文件未對標準選項和部件特定選項進行區分。有些選項不適用於某些型別的部件。一個給定的部件是否響應某個特定選項取決於該部件的類別;按鈕有 command
選項,而標籤沒有。
一個給定部件支援的選項列在該部件的手冊頁中,或者可以在執行時透過不帶引數呼叫 config()
方法,或者在該部件上呼叫 keys()
方法來查詢。這些呼叫的返回值是一個字典,其鍵是選項的名稱字串(例如,'relief'
),其值是 5 元組。
有些選項,如 bg
,是長名稱常用選項的同義詞(bg
是“background”的簡寫)。向 config()
方法傳遞一個簡寫選項的名稱將返回一個 2 元組,而不是 5 元組。返回的 2 元組將包含同義詞的名稱和“真實”選項(例如 ('bg', 'background')
)。
索引 |
含義 |
示例 |
---|---|---|
0 |
選項名 |
|
1 |
用於資料庫查詢的選項名 |
|
2 |
用於資料庫查詢的選項類 |
|
3 |
預設值 |
|
4 |
當前值 |
|
示例
>>> print(fred.config())
{'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}
當然,打印出的字典將包含所有可用選項及其值。這只是一個示例。
Packer(佈局管理器)¶
packer 是 Tk 的幾何管理機制之一。幾何管理器用於指定部件在其容器(它們的共同*master*)內的相對位置。與更繁瑣的 *placer*(使用較少,我們在此不作介紹)相比,packer 採用定性關係規範——*上方*、*左側*、*填充*等——併為你計算出確切的放置座標。
任何 *master* 部件的大小由其內部的“slave widgets”的大小決定。packer 用於控制 slave 部件在它們被打包進去的 master 內部出現的位置。你可以將部件打包到框架中,再將框架打包到其他框架中,以實現你想要的佈局。此外,一旦打包,佈局會動態調整以適應配置的增量變化。
請注意,除非用幾何管理器指定了部件的幾何形狀,否則部件不會出現。一個常見的早期錯誤是忘記了幾何規範,然後驚訝於部件已建立但什麼也沒出現。一個部件只有在應用了例如 packer 的 pack()
方法之後才會出現。
pack() 方法可以與關鍵字-選項/值對一起呼叫,這些對控制部件在其容器中出現的位置,以及當主應用程式視窗調整大小時它的行為方式。以下是一些示例:
fred.pack() # defaults to side = "top"
fred.pack(side="left")
fred.pack(expand=1)
Packer 選項¶
有關 packer 及其可接受選項的更廣泛資訊,請參閱手冊頁和 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()
方法。如果你遵循這個協議,部件將始終跟蹤變數的值,無需你進一步干預。
例如:
import tkinter as tk
class App(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.pack()
self.entrythingy = tk.Entry()
self.entrythingy.pack()
# Create the application variable.
self.contents = tk.StringVar()
# Set it to some value.
self.contents.set("this is a variable")
# Tell the entry widget to watch this variable.
self.entrythingy["textvariable"] = self.contents
# Define a callback for when the user hits return.
# It prints the current value of the variable.
self.entrythingy.bind('<Key-Return>',
self.print_contents)
def print_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。當然,如果該部件被打包在一個框架內,master 將不代表一個頂層視窗。要訪問包含任意部件的頂層視窗,你可以呼叫 _root()
方法。該方法以下劃線開頭,表示此函式是實現的一部分,而不是 Tk 功能的介面。
以下是一些典型用法的示例:
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
# create the application
myapp = App()
#
# here are method calls to the window manager class
#
myapp.master.title("My Do-Nothing Application")
myapp.master.maxsize(1000, 400)
# start the program
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"
。- 回撥
這是任何不帶引數的 Python 函式。例如:
def print_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 使用列表字型名稱格式,例如
{courier 10 bold}
。正數大小的字型以點為單位測量;負數大小的字型以畫素為單位測量。- geometry
這是一個形如
widthxheight
的字串,其中 width 和 height 對於大多數部件是以畫素為單位測量的(對於顯示文字的部件是以字元為單位)。例如:fred["geometry"] = "200x100"
。- justify
合法值為字串:
"left"
、"center"
、"right"
和"fill"
。- region
這是一個由四個空格分隔的元素組成的字串,每個元素都是一個合法的距離(見上文)。例如:
"2 3 4 5"
和"3i 2i 4.5i 2i"
以及"3c 2c 4c 10.43c"
都是合法的區域。- relief
確定部件的邊框樣式。合法值為:
"raised"
、"sunken"
、"flat"
、"groove"
和"ridge"
。- scrollcommand
這幾乎總是某個捲軸部件的
set()
方法,但也可以是任何接受單個引數的部件方法。- wrap
必須是以下之一:
"none"
、"char"
或"word"
。
繫結和事件¶
來自部件命令的 bind 方法允許你監視某些事件,並在該事件型別發生時觸發一個回撥函式。bind 方法的形式是:
def bind(self, sequence, func, add=''):
其中:
- 序列
是一個表示目標事件型別的字串。(詳見 bind(3tk) 手冊頁和 John Ousterhout 的書《Tcl and the Tk Toolkit (2nd edition)》的第 201 頁)。
- func
是一個 Python 函式,接受一個引數,在事件發生時被呼叫。一個 Event 例項將作為引數傳遞。(以這種方式部署的函式通常被稱為*回撥函式*。)
- add
是可選的,可以是
''
或'+'
。傳遞一個空字串表示此繫結將替換與該事件關聯的任何其他繫結。傳遞一個'+'
意味著此函式將被新增到繫結到此事件型別的函式列表中。
例如:
def turn_red(self, event):
event.widget["activeforeground"] = "red"
self.button.bind("<Enter>", self.turn_red)
注意在 turn_red()
回撥函式中是如何訪問事件的 widget 欄位的。該欄位包含捕獲到 X 事件的部件。下表列出了你可以訪問的其他事件欄位,以及它們在 Tk 中的表示方式,這在參考 Tk 手冊頁時可能很有用。
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 手冊頁中有最好的描述。
- 選單索引(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()
方法,用於將一個影像的區域複製到另一個影像,可能帶有畫素縮放和/或子取樣。向 PhotoImage
的 copy()
、zoom()
和 subsample()
方法新增 from_coords 引數。向 PhotoImage
的 copy()
方法新增 zoom 和 subsample 引數。
然後,影像物件可以在任何支援 image
選項的部件(例如標籤、按鈕、選單)中使用。在這些情況下,Tk 不會保留對影像的引用。當對影像物件的最後一個 Python 引用被刪除時,影像資料也會被刪除,Tk 將在影像曾被使用的任何地方顯示一個空框。
參見
Pillow 包增加了對 BMP、JPEG、TIFF 和 WebP 等格式的支援。
檔案處理器¶
Tk 允許你註冊和登出一個回撥函式,當檔案描述符上可以進行 I/O 操作時,Tk 主迴圈將呼叫該函式。每個檔案描述符只能註冊一個處理器。示例程式碼:
import tkinter
widget = tkinter.Tk()
mask = tkinter.READABLE | tkinter.WRITABLE
widget.tk.createfilehandler(file, mask, callback)
...
widget.tk.deletefilehandler(file)
此功能在 Windows 上不可用。
由於你不知道有多少位元組可供讀取,你可能不想使用 BufferedIOBase
或 TextIOBase
的 read()
或 readline()
方法,因為這些方法會堅持讀取預定義數量的位元組。對於套接字,recv()
或 recvfrom()
方法可以正常工作;對於其他檔案,請使用原始讀取或 os.read(file.fileno(), maxbytecount)
。
- Widget.tk.createfilehandler(file, mask, func)¶
註冊檔案處理器回撥函式 func。file 引數可以是一個具有
fileno()
方法的物件(例如檔案或套接字物件),也可以是一個整數檔案描述符。mask 引數是下面三個常量中任意一個的“或”組合。回撥函式按以下方式呼叫:callback(file, mask)
- Widget.tk.deletefilehandler(file)¶
登出一個檔案處理器。