tkinter --- Tcl/Tk 的 Python 介面

原始碼:Lib/tkinter/__init__.py


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 相關資源:

  • Tk 指令

    Tkinter 所使用的每個底層 Tcl/Tk 指令的綜合參考資料。

  • Tcl/Tk 首頁

    額外的文件,以及連至 Tcl/Tk 核心開發的連結。

書籍:

架構

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

tk

透過實例化Tk 建立的 Tk 應用程式物件。這提供了對 Tcl 直譯器的存取。每個附加到同一個Tk 實例的元件,其tk 屬性都具有相同的值。

master

包含此元件的元件物件。對於TkmasterNone,因為它是主視窗。masterparent 這兩個術語很相似,有時會作為引數名稱互換使用;然而,呼叫winfo_parent() 會回傳元件名稱的字串,而master 則回傳物件。parent/child 反映了樹狀關係,而master/slave 反映了容器結構。

children

此元件的直接子代,形式為一個dict,其中鍵為子元件的名稱,值為子實例物件。

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

一個包含 Tcl/Tk 低階介面的二進位模組。它由主tkinter 模組自動引入,應用程式開發者不應直接使用它。它通常是一個共享函式庫(或 DLL),但在某些情況下可能會與 Python 直譯器靜態連結。

idlelib

Python 的整合開發與學習環境(IDLE)。基於tkinter

tkinter.constants

在將各種參數傳遞給 Tkinter 呼叫時,可用於替代字串的符號常數。由主tkinter 模組自動引入。

tkinter.dnd

(實驗性)對tkinter 的拖放支援。當它被 Tk DND 取代時,將會被棄用。

turtle

在 Tk 視窗中的海龜繪圖。

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.Framettk.Labelttk.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 中實作為獨立指令的操作(如griddestroy),在 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)。

你可以在optionsttk::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

選項名稱

'relief'

1

用於資料庫查詢的選項名稱

'relief'

2

用於資料庫查詢的選項類別

'Relief'

3

預設值

'raised'

4

目前值

'groove'

範例:

>>>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

布林值,01

fill

合法值:'x''y''both''none'

ipadx 和 ipady

一個距離——指定 slave 元件每側的內部填充。

padx 和 pady

一個距離——指定 slave 元件每側的外部填充。

side

合法值為:'left''right''top''bottom'

耦合元件變數

某些元件(如文字輸入元件)的當前值設定可以透過使用特殊選項直接連接到應用程式變數。這些選項是variabletextvariableonvalueoffvaluevalue。這種連接是雙向的:如果變數因任何原因發生變化,與之連接的元件將會更新以反映新值。

不幸的是,在tkinter 的目前實作中,無法透過variabletextvariable 選項將任意的 Python 變數傳遞給元件。唯一適用此功能的變數類型是從tkinter 中定義的一個名為 Variable 的類別繼承的子類別變數。

已經定義了許多有用的 Variable 子類別:StringVarIntVarDoubleVarBooleanVar。要讀取此類變數的目前值,請對其呼叫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() 以停用所有項目,最後,

  • 一個文字字串,它會與從選單頂部掃描到底部的選單項目標籤進行模式匹配。請注意,此索引類型在所有其他類型之後考慮,這意味著標籤為lastactivenone 的選單項目的匹配可能會被解釋為上述的字面值。

圖片

可以透過tkinter.Image 的相應子類別來建立不同格式的圖片:

  • BitmapImage 用於 XBM 格式的圖片。

  • PhotoImage 用於 PGM、PPM、GIF 和 PNG 格式的圖片。後者從 Tk 8.6 開始支援。

任一類型的圖片都是透過filedata 選項建立的(也有其他選項可用)。

在 3.13 版的變更:新增了PhotoImage 方法copy_replace(),用於將一個區域從一個圖片複製到另一個圖片,可能帶有像素縮放和/或子採樣。將from_coords 參數新增到PhotoImage 方法copy()zoom()subsample()。將zoomsubsample 參數新增到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 上不可用。

由於你不知道有多少位元組可供讀取,你可能不想使用BufferedIOBaseTextIOBaseread()readline() 方法,因為這些方法會堅持讀取預定義數量的位元組。對於 sockets(通訊端),recv()recvfrom() 方法可以正常運作;對於其他檔案,請使用原始讀取或os.read(file.fileno(),maxbytecount)

Widget.tk.createfilehandler(file,mask,func)

註冊檔案處理常式回呼函式funcfile 引數可以是一個具有fileno() 方法的物件(例如檔案或 socket(通訊端)物件),或是一個整數檔案描述器。mask 引數是下面三個常數中任意一個的 OR 組合。回呼函式被呼叫的方式如下:

callback(file,mask)
Widget.tk.deletefilehandler(file)

取消註冊檔案處理常式。

_tkinter.READABLE
_tkinter.WRITABLE
_tkinter.EXCEPTION

用於mask 引數的常數。