新聞中心
tkinter —— Tcl/Tk 的 python 接口
源代碼: Lib/tkinter/__init__.py

tkinter 包 (“Tk 接口”) 是針對 Tcl/Tk GUI 工具包的標(biāo)準(zhǔn) Python 接口。 Tk 和 tkinter 在大多數(shù) Unix 平臺,包括 macOS,以及 Windows 系統(tǒng)上均可使用。
若在命令行執(zhí)行 python -m tkinter,應(yīng)會彈出一個簡單的 Tk 界面窗口, 表明 tkinter 包已安裝完成,還會顯示當(dāng)前安裝的 Tcl/Tk 版本,以便閱讀對應(yīng)版本的 Tcl/Tk 文檔。
Tkinter 支持眾多的 Tcl/Tk 版本,帶或不帶多線程版本均可。官方的 Python 二進(jìn)制版本捆綁了 Tcl/Tk 8.6 多線程版本。關(guān)于可支持版本的更多信息,請參閱 _tkinter 模塊的源代碼。
Tkinter 并不只是做了簡單的封裝,而是增加了相當(dāng)多的代碼邏輯,讓使用體驗(yàn)更具 Python 風(fēng)格(pythonic) 。本文將集中介紹這些增加和變化部分,關(guān)于未改動部分的細(xì)節(jié),請參考 Tcl/Tk 官方文檔。
備注
Tcl/Tk 8.5 (2007) 引入了支持主題的現(xiàn)代風(fēng)格用戶界面組件集以及使用這些組件的新版 API。 舊版和新版 API 都可以使用。 你在網(wǎng)上所能找到的大多數(shù)文檔仍然是使用舊版 API 因此也許已經(jīng)相當(dāng)過時。
參見
-
TkDocs
關(guān)于使用 Tkinter 創(chuàng)建用戶界面的詳細(xì)教程。 講解了關(guān)鍵概念,并介紹了使用現(xiàn)代 API 的推薦方式。
-
Tkinter 8.5 參考手冊:一種 Python GUI
詳細(xì)講解可用的類、方法和選項(xiàng)的 Tkinter 8.5 參考文檔。
Tcl/Tk 資源:
-
Tk 命令
有關(guān) Tkinter 所使用的每個底層 Tcl/Tk 命令的完整參考文檔。
-
Tcl/Tk 主頁
額外的文檔,以及 Tcl/Tk 核心開發(fā)相關(guān)鏈接。
書籍:
-
Modern Tkinter for Busy Python Developers
Mark Roseman 著。 (ISBN 978-1999149567)
-
Python and Tkinter Programming
Alan Moore 著。 (ISBN 978-1788835886)
-
Programming Python
Mark Lutz 著;對 Tkinter 進(jìn)行了精彩的講解。 (ISBN 978-0596158101)
-
Tcl and the Tk Toolkit (2nd edition)
John Ousterhout ,Tcl/Tk 的創(chuàng)造者,與 Ken Jones 合著;未涉及 Tkinter。 (ISBN 978-0321336330)
架構(gòu)
Tcl/Tk 不是只有單個庫,而是由幾個不同的模塊組成的,每個模塊都有各自的功能和各自的官方文檔。 Python 的二進(jìn)制發(fā)行版還會再附加一個模塊。
Tcl
Tcl 是一種動態(tài)解釋型編程語言,正如 Python 一樣。盡管它可作為一種通用的編程語言單獨(dú)使用,但最常見的用法還是作為腳本引擎或 Tk 工具包的接口嵌入到 C 程序中。Tcl 庫有一個 C 接口,用于創(chuàng)建和管理一個或多個 Tcl 解釋器實(shí)例,并在這些實(shí)例中運(yùn)行 Tcl 命令和腳本,添加用 Tcl 或 C 語言實(shí)現(xiàn)的自定義命令。每個解釋器都擁有一個事件隊(duì)列,某些部件可向解釋器發(fā)送事件交由其處理。與 Python 不同,Tcl 的執(zhí)行模型是圍繞協(xié)同多任務(wù)而設(shè)計(jì)的,Tkinter 協(xié)調(diào)了兩者的差別(詳見 Threading model )。
Tk
Tk is a Tcl package implemented in C that adds custom commands to create and manipulate GUI widgets. Each Tk object embeds its own Tcl interpreter instance with Tk loaded into it. Tk’s widgets are very customizable, though at the cost of a dated appearance. Tk uses Tcl’s event queue to generate and process GUI events.
Ttk
帶有主題的 Tk(Ttk)是較新加入的 Tk 部件,相比很多經(jīng)典的 Tk 部件,在各平臺提供的界面更加美觀。自 Tk 8.5 版本開始,Ttk 作為 Tk 的成員進(jìn)行發(fā)布。Python 則捆綁在一個單獨(dú)的模塊中, tkinter.ttk。
在內(nèi)部,Tk 和 Ttk 使用下層操作系統(tǒng)的工具庫,例如在 Unix/X11 上是 Xlib,在 macOS 上是 Cocoa,在 Windows 上是 GDI。
當(dāng)你的 Python 應(yīng)用程序使用 Tkinter 中的某個類,例如創(chuàng)建一個部件時,tkinter 模塊將首先生成一個 Tcl/Tk 命令字符串。 它會把這個 Tcl 命令字符串傳給內(nèi)部的 _tkinter 二進(jìn)制模塊,后者將隨后調(diào)用 Tcl 解釋器來對其求值。 Tcl 解釋器隨后將對 Tk 和/和 Ttk 包發(fā)起調(diào)用,它們又將繼續(xù)對 Xlib, Cocoa 或 GDI 發(fā)起調(diào)用。
Tkinter 模塊
對 Tkinter 的支持分布在多個模塊中。 大多數(shù)應(yīng)用程序?qū)⑿枰髂K tkinter,以及 tkinter.ttk 模塊,后者提供了帶主題的現(xiàn)代部件集及相應(yīng)的 API:
from tkinter import *from tkinter import ttk
class tkinter.Tk(screenName=None, baseName=None, className=’Tk’, useTk=True, sync=False, use=None)
構(gòu)造一個最高層級的 Tk 部件,這通常是一個應(yīng)用程序的主窗口,并為這個部件初始化 Tcl 解釋器。 每個實(shí)例都有其各自所關(guān)聯(lián)的 Tcl 解釋器。
Tk 類通常全部使用默認(rèn)值來初始化。 不過,目前還可識別下列關(guān)鍵字參數(shù):
-
screenName
當(dāng)(作為字符串)給出時,設(shè)置
DISPLAY環(huán)境變量。 (僅限 X11)baseName
預(yù)置文件的名稱。 在默認(rèn)情況下,baseName 是來自于程序名稱 (
sys.argv[0])。className
控件類的名稱。 會被用作預(yù)置文件同時也作為 Tcl 發(fā)起調(diào)用的名稱 (interp 中的 argv0)。
useTk
如果為
True,則初始化 Tk 子系統(tǒng)。 tkinter.Tcl() 函數(shù)會將其設(shè)為False。sync
如果為
True,則同步執(zhí)行所有 X 服務(wù)器命令,以便立即報告錯誤。 可被用于調(diào)試。 (僅限 X11)use
指定嵌入應(yīng)用程序的窗口 id,而不是將其創(chuàng)建為獨(dú)立的頂層窗口。 id 必須以與頂層控件的 -use 選項(xiàng)值相同的方式來指定(也就是說,它具有與
winfo_id()的返回值相同的形式)。請注意在某些平臺上只有當(dāng) id 是指向一個啟用了 -container 選項(xiàng)的 Tk 框架或頂層窗口時此參數(shù)才能正確生效。
Tk 讀取并解釋預(yù)置文件,其名稱為 .*className*.tcl 和 .*baseName*.tcl,進(jìn)入 Tcl 解釋器并基于 .*className*.py 在 .*baseName*.py 的內(nèi)容調(diào)用 exec()。 預(yù)置文件的路徑為 HOME 環(huán)境變量,或者如果它未被設(shè)置,則為 os.curdir。
-
tk
通過實(shí)例化 Tk 創(chuàng)建的 Tk 應(yīng)用程序?qū)ο蟆?這提供了對 Tcl 解釋器的訪問。 每個被附加到相同 Tk 實(shí)例的控件都具有相同的 tk 屬性值。
-
master
包含此控件的控件對象。 對于 Tk,master 將為 None 因?yàn)樗侵鞔翱凇?術(shù)語 master 和 parent 是類似的且有時作為參數(shù)名稱被交替使用;但是,調(diào)用
winfo_parent()將返回控件名稱字符串而 master 將返回控件對象。 parent/child 反映了樹型關(guān)系而 master/slave 反映了容器結(jié)構(gòu)。 -
children
以 dict 表示的此控件的直接下級其中的鍵為子控件名稱而值為子實(shí)例對象。
tkinter.Tcl(screenName=None, baseName=None, className=’Tk’, useTk=False)
Tcl() 函數(shù)是一個工廠函數(shù),它創(chuàng)建的對象類似于 Tk 類創(chuàng)建的,只是不會初始化 Tk 子系統(tǒng)。這在調(diào)動 Tcl 解釋器時最為有用,這時不想創(chuàng)建多余的頂層窗口,或者無法創(chuàng)建(比如不帶 X 服務(wù)的 Unix/Linux 系統(tǒng))。由 Tcl() 創(chuàng)建的對象可調(diào)用 loadtk() 方法創(chuàng)建一個頂層窗口(且會初始化 Tk 子系統(tǒng))。
提供 Tk 支持的模塊包括:
tkinter
主 Tkinter 模塊。
tkinter.colorchooser
讓用戶選擇顏色的對話框。
tkinter.commondialog
本文其他模塊定義的對話框的基類。
tkinter.filedialog
允許用戶指定文件的通用對話框,用于打開或保存文件。
tkinter.font
幫助操作字體的工具。
tkinter.messagebox
訪問標(biāo)準(zhǔn)的 Tk 對話框。
tkinter.scrolledtext
內(nèi)置縱向滾動條的文本組件。
tkinter.simpledialog
基礎(chǔ)對話框和一些便捷功能。
tkinter.ttk
在 Tk 8.5 中引入的帶主題的控件集,提供了對應(yīng)于 tkinter 模塊中許多經(jīng)典控件的現(xiàn)代替代。
附加模塊:
_tkinter
一個包含低層級 Tcl/Tk 接口的二進(jìn)制模塊。 它會被主 tkinter 模塊自動導(dǎo)入,且永遠(yuǎn)不應(yīng)被應(yīng)用程序員所直接使用。 它通常是一個共享庫(或 DLL),但在某些情況下可能被動態(tài)鏈接到 Python 解釋器。
idlelib
Python 的集成開發(fā)與學(xué)習(xí)環(huán)境(IDLE)。 基于 tkinter。
tkinter.constants
當(dāng)向 Tkinter 調(diào)用傳入各種形參時可被用來代替字符串的符號常量。 由主 tkinter 模塊自動導(dǎo)入。
tkinter.dnd
針對 tkinter 的(實(shí)驗(yàn)性的)拖放支持。 當(dāng)以 Tk DND 代替時它將會被棄用。
tkinter.tix
(已棄用)一個增加了部分新控件的較老的第三方 Tcl/Tk 包。 對多數(shù)人來說可以在 tkinter.ttk 中找到更好的替代品。
turtle
Tk 窗口中的海龜繪圖庫。
Tkinter 拾遺
這一章節(jié)的設(shè)計(jì)目的不是要編寫有關(guān) Tk 或 Tkinter 的冗長教程。 要獲取教程,請參閱之前列出的外部資源之一。 相反地,這一章節(jié)提供了對于 Tkinter 應(yīng)用程序大致樣貌的快速指導(dǎo),列出了基本的 Tk 概念,并解釋了 Tkinter 包裝器的構(gòu)造是什么樣的。
這一章節(jié)的剩余部分將幫助你識別在你的 Tkinter 應(yīng)用程序中需要的類、方法和選項(xiàng),以及在哪里可以找到有關(guān)它們的更詳細(xì)文檔,包括官方 Tcl/Tk 參考手冊等。
Hello World 程序
讓我們先來看一個 Tkinter 的 “Hello World” 應(yīng)用程序。 這并不是我們所能寫出的最簡短版本,但也足夠說明你所需要了解的一些關(guān)鍵概念。
from tkinter import *from tkinter import ttkroot = 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()
在導(dǎo)入語句之后,下一行語句創(chuàng)建了一個 Tk 類的實(shí)例,它會初始化 Tk 并創(chuàng)建與其關(guān)聯(lián)的 Tcl 解釋器。 它還會創(chuàng)建一個頂層窗口,名為 root 窗口,它將被作為應(yīng)用程序的主窗口。
下一行創(chuàng)建了一個框架控件,在本示例中它會包含我們即將創(chuàng)建的一個標(biāo)簽和一個按鈕。 框架被嵌在 root 窗口內(nèi)部。
下一行創(chuàng)建了一個包含靜態(tài)文本字符串的標(biāo)簽控件。 grid() 方法被用來指明標(biāo)簽在包含它的框架控件中的相對布局(定位),作用類似于 HTML 中的表格。
接下來創(chuàng)建了一個按鈕控件,并被放置到標(biāo)簽的右側(cè)。 當(dāng)被按下時,它將調(diào)用 root 窗口的 destroy() 方法。
最后,mainloop() 方法將所有控件顯示出來,并響應(yīng)用戶輸入直到程序終結(jié)。
重要的 Tk 概念
即便是這樣簡單的程序也闡明了以下關(guān)鍵 Tk 概念:
控件
Tkinter 用戶界面是由一個個 控件 組成的。 每個控件都由相應(yīng)的 Python 對象表示,由 ttk.Frame, ttk.Label 以及 ttk.Button 這樣的類來實(shí)例化。
控件層級結(jié)構(gòu)
控件按 層級結(jié)構(gòu) 來組織。 標(biāo)簽和按鈕包含在框架中,框架又包含在根窗口中。 當(dāng)創(chuàng)建每個 子 控件時,它的 父 控件會作為控件構(gòu)造器的第一個參數(shù)被傳入。
配置選項(xiàng)
控件具有 配置選項(xiàng),配置選項(xiàng)會改變控件的外觀和行為,例如要在標(biāo)簽或按鈕中顯示的文本。 不同的控件類會具有不同的選項(xiàng)集。
幾何管理
小部件在創(chuàng)建時不會自動添加到用戶界面。一個像``grid``的 幾何管理器 控制這些小部件在用戶界面的位置。
事件循環(huán)
只有主動運(yùn)行一個 事件循環(huán),Tkinter 才會對用戶的輸入做出反應(yīng),改變你的程序,以及刷新顯示。如果你的程序沒有運(yùn)行事件循環(huán),你的用戶界面不會更新。
了解 Tkinter 如何封裝 Tcl/Tk
當(dāng)你的應(yīng)用程序使用 Tkinter 的類和方法時,Tkinter 內(nèi)部匯編代表 Tcl/Tk 命令的字符串,并且在連接到你的應(yīng)用程序的 Tk 實(shí)例的 Tcl 解釋器中執(zhí)行這些命令。
無論是試圖瀏覽參考文檔,或是試圖找到正確的方法或選項(xiàng),調(diào)整一些現(xiàn)有的代碼,亦或是調(diào)試 Tkinter 應(yīng)用程序,有時候理解底層 Tcl/Tk 命令是什么樣子的會很有用。
為了說明這一點(diǎn),下面是 Tcl/Tk 等價于上面 Tkinter 腳本的主要部分。
ttk::frame .frm -padding 10grid .frmgrid [ttk::label .frm.lbl -text "Hello World!"] -column 0 -row 0grid [ttk::button .frm.btn -text "Quit" -command "destroy ."] -column 1 -row 0
Tcl 的語法類似于許多 shell 語言,其中第一個單詞是要執(zhí)行的命令,后面是該命令的參數(shù),用空格分隔。不談太多細(xì)節(jié),請注意以下幾點(diǎn):
-
用于創(chuàng)建窗口小部件(如
ttk::frame)的命令對應(yīng)于 Tkinter 中的 widget 類。 -
Tcl 窗口控件選項(xiàng)(如
-tex)對應(yīng)于 Tkinter 中的關(guān)鍵字參數(shù)。 -
在 Tcl 中,小部件是通過 路徑名 引用的(例如
.frm.btn),而 Tkinter 不使用名稱,而是使用對象引用。 -
控件在控件層次結(jié)構(gòu)中的位置在其(層次結(jié)構(gòu))路徑名中編碼,該路徑名使用一個
.(點(diǎn))作為路徑分隔符。根窗口的路徑名是.(點(diǎn))。在 Tkinter 中,層次結(jié)構(gòu)不是通過路徑名定義的,而是通過在創(chuàng)建每個子控件時指定父控件來定義的。 -
在 Tcl 中以獨(dú)立的 命令 實(shí)現(xiàn)的操作(比如
grid和destroy)在 Tkinter 控件對象上以 方法 表示。稍后您將看到,在其他時候,Tcl 在控件對象調(diào)用的方法,在 Tkinter 也有對應(yīng)的使用。
我該如何…?這個選項(xiàng)會做…?
如果您不確定如何在 Tkinter 中做一些事情,并且您不能立即在您正在使用的教程或參考文檔中找到它,這里有一些策略可以幫助您。
首先,請記住,在不同版本的 Tkinter 和 Tcl/Tk 中,各個控件如何工作的細(xì)節(jié)可能會有所不同。如果您正在搜索文檔,請確保它與安裝在系統(tǒng)上的 Python 和 Tcl/Tk 版本相對應(yīng)。
在搜索如何使用 API 時,知道正在使用的類、選項(xiàng)或方法的確切名稱會有所幫助。內(nèi)省,無論是在交互式 Python shell 中,還是在 print() 中,都可以幫助你確定你需要什么。
要找出控件上可用的配置選項(xiàng),請調(diào)用其 configure() 方法,該方法返回一個字典,其中包含每個對象的各種信息,包括其默認(rèn)值和當(dāng)前值。使用 keys() 獲取每個選項(xiàng)的名稱。
btn = ttk.Button(frm, ...)print(btn.configure().keys())
由于大多數(shù)控件都有許多共同的配置選項(xiàng),因此找出特定于特定控件類的配置選項(xiàng)可能會很有用。將選項(xiàng)列表與更簡單的控件(如框架)的列表進(jìn)行比較是一種方法。
print(set(btn.configure().keys()) - set(frm.configure().keys()))
類似地,你可以使用標(biāo)準(zhǔn)函數(shù) dir() 來查找控件對象的可用方法。如果您嘗試一下,您會發(fā)現(xiàn)有超過200種常見的控件方法,因此再次確認(rèn)那些特定于控件類的方法是有幫助的。
print(dir(btn))print(set(dir(btn)) - set(dir(frm)))
瀏覽 Tcl/Tk 參考手冊
如上所述,官方的 Tk commands 參考手冊(手冊頁)通常有對控件特定操作的最準(zhǔn)確描述。即使您知道需要的選項(xiàng)或方法的名稱,您可能仍然有一些地方可以查找。
雖然 Tkinter 中的所有操作都是通過對控件對象的方法調(diào)用來實(shí)現(xiàn)的,但您已經(jīng)看到許多 Tcl/Tk 操作都是以命令的形式出現(xiàn)的,這些命令以小部件的路徑名作為它的第一個參數(shù),然后是可選參數(shù),例如:
destroy .grid .frm.btn -column 0 -row 0
但是,其他方法看起來更像在控件對象上調(diào)用的方法(實(shí)際上,當(dāng)您在 Tcl/Tk 中創(chuàng)建小部件時,它會使用控件路徑名創(chuàng)建 Tcl 命令,該命令的第一個參數(shù)是要調(diào)用的方法名)。
.frm.btn invoke.frm.lbl configure -text "Goodbye"
在 Tcl/Tk 官方參考文檔中,你會發(fā)現(xiàn)手冊頁上大多數(shù)操作看起來都像是特定控件的的方法調(diào)用(例如,你會在`ttk::button invoke() 方法),而以控件作為參數(shù)的函數(shù)通常有自己的手冊頁(例如,grid )。
您將在 options 或 ttk::widget 手冊頁中找到許多常見的選項(xiàng)和方法,而其他的選項(xiàng)和方法可以在特定控件類的手冊頁中找到。
你還會發(fā)現(xiàn)許多 Tkinter 方法有復(fù)合名稱,例如 winfo_x(),winfo_height(),winfo_viewable()。你可以在 winfo 頁面找到這些文檔。
備注
有些令人困惑的是,所有 Tkinter 小部件上還有一些方法實(shí)際上并不在控件上操作,而是在全局范圍內(nèi)操作,獨(dú)立于任何控件。例如訪問剪貼板或系統(tǒng)響鈴的方法。(它們恰好被實(shí)現(xiàn)為所有 Tkinter 小部件都繼承自的基類 Widget 中的方法)。
線程模型
Python 和 Tcl/Tk 的線程模型大不相同,而 tkinter 則會試圖進(jìn)行調(diào)和。若要用到線程,可能需要注意這一點(diǎn)。
一個 Python 解釋器可能會關(guān)聯(lián)很多線程。在 Tcl 中,可以創(chuàng)建多個線程,但每個線程都關(guān)聯(lián)了單獨(dú)的 Tcl 解釋器實(shí)例。線程也可以創(chuàng)建一個以上的解釋器實(shí)例,盡管每個解釋器實(shí)例只能由創(chuàng)建它的那個線程使用。
Each Tk object created by tkinter contains a Tcl interpreter. It also keeps track of which thread created that interpreter. Calls to tkinter can be made from any Python thread. Internally, if a call comes from a thread other than the one that created the Tk object, an event is posted to the interpreter’s event queue, and when executed, the result is returned to the calling Python thread.
Tcl/Tk 應(yīng)用程序通常是事件驅(qū)動的,這意味著在完成初始化以后,解釋器會運(yùn)行一個事件循環(huán)(即 Tk.mainloop())并對事件做出響應(yīng)。因?yàn)樗菃尉€程的,所以事件處理程序必須快速響應(yīng),否則會阻塞其他事件的處理。為了避免阻塞,不應(yīng)在事件處理程序中執(zhí)行任何耗時很久的計(jì)算,而應(yīng)利用計(jì)時器將任務(wù)分塊,或者在其他線程中運(yùn)行。而其他很多工具包的 GUI 是在一個完全獨(dú)立的線程中運(yùn)行的,獨(dú)立于包括事件處理程序在內(nèi)的所有代碼。
如果 Tcl 解釋器沒有運(yùn)行事件循環(huán)并處理解釋器事件,則除運(yùn)行 Tcl 解釋器的線程外,任何其他線程發(fā)起的 tkinter 調(diào)用都會失敗。
存在一些特殊情況:
Tcl/Tk 庫可編譯為不支持多線程的版本。這時 tkinter 會從初始 Python 線程調(diào)用底層庫,即便那不是創(chuàng)建 Tcl 解釋器的線程。會有一個全局鎖來確保每次只會發(fā)生一次調(diào)用。
雖然 tkinter 允許創(chuàng)建一個以上的 Tk 實(shí)例(都帶有自己的解釋器),但所有屬于同一線程的解釋器均會共享同一個事件隊(duì)列,這樣很快就會一團(tuán)糟。在實(shí)際編程時,一次創(chuàng)建的 Tk 實(shí)例不要超過一個。否則最好在不同的線程中創(chuàng)建,并確保運(yùn)行的是支持多線程的 Tcl/Tk 版本。
為了防止 Tcl 解釋器重新進(jìn)入事件循環(huán),阻塞事件處理程序并不是唯一的做法。甚至可以運(yùn)行多個嵌套的事件循環(huán),或者完全放棄事件循環(huán)。如果在處理事件或線程時碰到棘手的問題,請小心這些可能的事情。
有幾個 tkinter 函數(shù),目前只在創(chuàng)建 Tcl 解釋器的線程中調(diào)用才行。
快速參考
可選配置項(xiàng)
配置參數(shù)可以控制組件顏色和邊框?qū)挾鹊?。可通過三種方式進(jìn)行設(shè)置:
在對象創(chuàng)建時,使用關(guān)鍵字參數(shù)
fred = Button(self, fg="red", bg="blue")
在對象創(chuàng)建后,將參數(shù)名用作字典索引
fred["fg"] = "red"fred["bg"] = "blue"
利用 config() 方法修改對象的多個屬性
fred.config(fg="red", bg="blue")
關(guān)于這些參數(shù)及其表現(xiàn)的完整解釋,請參閱 Tk 手冊中有關(guān)組件的 man 幫助頁。
請注意,man 手冊頁列出了每個部件的“標(biāo)準(zhǔn)選項(xiàng)”和“組件特有選項(xiàng)”。前者是很多組件通用的選項(xiàng)列表,后者是該組件特有的選項(xiàng)。標(biāo)準(zhǔn)選項(xiàng)在 options(3)) man 手冊中有文檔。
本文沒有區(qū)分標(biāo)準(zhǔn)選項(xiàng)和部件特有選項(xiàng)。有些選項(xiàng)不適用于某類組件。組件是否對某選項(xiàng)做出響應(yīng),取決于組件的類別;按鈕組件有一個 command 選項(xiàng),而標(biāo)簽組件就沒有。
組件支持的選項(xiàng)在其手冊中有列出,也可在運(yùn)行時調(diào)用 config() 方法(不帶參數(shù))查看,或者通過調(diào)用組件的 keys() 方法進(jìn)行查詢。這些調(diào)用的返回值為字典,字典的鍵是字符串格式的選項(xiàng)名(比如 'relief'),字典的值為五元組。
有些選項(xiàng),比如 bg 是全名通用選項(xiàng)的同義詞(bg 是 “background”的簡寫)。向 config() 方法傳入選項(xiàng)的簡稱將返回一個二元組,而不是五元組。傳回的二元組將包含同義詞的全名和“真正的”選項(xiàng)(比如 ('bg', 'background'))。
|
索引 |
含意 |
示例 |
|---|---|---|
0 | 選項(xiàng)名稱 |
|
1 | 數(shù)據(jù)庫查找的選項(xiàng)名稱 |
|
2 | 數(shù)據(jù)庫查找的選項(xiàng)類 |
|
3 | 默認(rèn)值 |
|
4 | 當(dāng)前值 |
|
示例:
>>> print(fred.config()){'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}
當(dāng)然,輸出的字典將包含所有可用選項(xiàng)及其值。這里只是舉個例子。
包裝器
包裝器是 Tk 的形狀管理機(jī)制之一。 形狀(geometry )管理器用于指定多個部件在容器(共同的 主 組件)內(nèi)的相對位置。與更為麻煩的 定位器 相比(不太常用,這里不做介紹),包裝器可接受定性的相對關(guān)系—— 上面 、左邊 、填充 等,并確定精確的位置坐標(biāo)。
主 部件的大小都由其內(nèi)部的 “從屬部件” 的大小決定。包裝器用于控制從屬部件在主部件中出現(xiàn)的位置。可以把部件包入框架,再把框架包入其他框架中,搭建出所需的布局。此外,只要完成了包裝,組件的布局就會進(jìn)行動態(tài)調(diào)整,以適應(yīng)布局參數(shù)的變化。
請注意,只有用形狀管理器指定幾何形狀后,部件才會顯示出來。忘記設(shè)置形狀參數(shù)是新手常犯的錯誤,驚訝于創(chuàng)建完部件卻啥都沒出現(xiàn)。部件只有在應(yīng)用了類似于打包器的 pack() 方法之后才會顯示在屏幕上。
調(diào)用 pack() 方法時可以給出由關(guān)鍵字/參數(shù)值組成的鍵值對,以便控制組件在其容器中出現(xiàn)的位置,以及主程序窗口大小變動時的行為。下面是一些例子:
fred.pack() # defaults to side = "top"fred.pack(side="left")fred.pack(expand=1)
包裝器的參數(shù)
關(guān)于包裝器及其可接受的參數(shù),更多信息請參閱 man 手冊和 John Ousterhout 書中的第 183 頁。
anchor
anchor 類型。 表示包裝器要放置的每個從屬組件的位置。
expand
布爾型,0 或 1 。
fill
合法值為:'x' 、'y' 、'both' 、'none'。
ipadx 和 ipady
距離值,指定從屬部件的內(nèi)邊距。
padx 和 pady
距離值,指定從屬部件的外邊距。
side
合法值為:'left'、 'right' 、 'top'、 'bottom'。
部件與變量的關(guān)聯(lián)
通過一些特定參數(shù),某些組件(如文本輸入組件)的當(dāng)前設(shè)置可直接與應(yīng)用程序的變量關(guān)聯(lián)。這些參數(shù)包括 variable 、 textvariable 、 onvalue 、 offvalue 、 value。這種關(guān)聯(lián)是雙向的:只要這些變量因任何原因發(fā)生變化,其關(guān)聯(lián)的部件就會更新以反映新的參數(shù)值。
不幸的是,在目前 tkinter 的實(shí)現(xiàn)代碼中,不可能通過 variable 或 textvariable 參數(shù)將任意 Python 變量移交給組件。變量只有是 tkinter 中定義的 Variable 類的子類,才能生效。
已經(jīng)定義了很多有用的 Variable 子類: StringVar 、 IntVar 、DoubleVar 和 BooleanVar。調(diào)用 get() 方法可以讀取這些變量的當(dāng)前值;調(diào)用 set() 方法則可改變變量值。只要遵循這種用法,組件就會保持跟蹤變量的值,而不需要更多的干預(yù)。
例如:
import tkinter as tkclass 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('', 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 有個實(shí)用命令 wm,用于與窗口管理器進(jìn)行交互。wm 命令的參數(shù)可用于控制標(biāo)題、位置、圖標(biāo)之類的東西。在 tkinter 中,這些命令已被實(shí)現(xiàn)為 Wm 類的方法。頂層部件是 Wm 類的子類,所以可以直接調(diào)用 Wm 的這些方法。
要獲得指定部件所在的頂層窗口,通常只要引用該部件的主窗口即可。當(dāng)然,如果該部件是包裝在框架內(nèi)的,那么主窗口不代表就是頂層窗口。為了獲得任意組件所在的頂層窗口,可以調(diào)用 _root() 方法。該方法以下劃線開頭,表明其為 Python 實(shí)現(xiàn)的代碼,而非 Tk 提供的某個接口。
以下是一些典型用法:
import tkinter as tkclass App(tk.Frame):def __init__(self, master=None):super().__init__(master)self.pack()# create the applicationmyapp = App()## here are method calls to the window manager class#myapp.master.title("My Do-Nothing Application")myapp.master.maxsize(1000, 400)# start the programmyapp.mainloop()
Tk 參數(shù)的數(shù)據(jù)類型
anchor
合法值是羅盤的方位點(diǎn):"n" 、"ne" 、"e" 、"se" 、"s" 、"sw" 、"w" 、"nw" 和 "center" 。
bitmap
內(nèi)置已命名的位圖有八個:'error'、 'gray25' 、'gray50' 、'hourglass'、 'info' 、'questhead' 、'question' 、'warning' 。若要指定位圖的文件名,請給出完整路徑,前面加一個 @,比如 "@/usr/contrib/bitmap/gumby.bit"。
boolean
可以傳入整數(shù) 0 或 1,或是字符串 "yes" 或 "no"。
callback — 回調(diào)
指任何無需調(diào)用參數(shù)的 Python 函數(shù)。 例如:
def print_it():print("hi there")fred["command"] = print_it
color
可在 rgb.txt 文件中以顏色名的形式給出,或是 RGB 字符串的形式,4 位 :"#RGB" ,8 位 :"#RRGGBB",12 位:"#RRRGGGBBB",16 位:"#RRRRGGGGBBBB",其中R、G、B 為合法的十六進(jìn)制數(shù)值。 詳見 Ousterhout 書中的第 160 頁。
cursor
可采用 cursorfont.h 中的標(biāo)準(zhǔn)光標(biāo)名稱,去掉 XC_ 前綴。 比如要獲取一個手形光標(biāo)(XC_hand2),可以用字符串 "hand2"。也可以指定自己的位圖和掩碼文件作為光標(biāo)。參見 Ousterhout 書中的第 179 頁。
distance
屏幕距離可以用像素或絕對距離來指定。像素是數(shù)字,絕對距離是字符串,后面的字符表示單位:c 是厘米,i 是英寸,m 是毫米,p 則表示打印機(jī)的點(diǎn)數(shù)。例如,3.5 英寸可表示為 "3.5i"。
font
Tk 采用一串名稱的格式表示字體,例如 {courier 10 bold}。正數(shù)的字體大小以點(diǎn)為單位,負(fù)數(shù)的大小以像素為單位。
geometry
這是一個 widthxheight 形式的字符串,其中寬度和高度對于大多數(shù)部件來說是以像素為單位的(對于顯示文本的部件來說是以字符為單位的)。例如:fred[“geometry”] = “200x100”。
justify
合法的值為字符串: "left" 、 "center" 、 "right" 和 "fill" 。
region
這是包含四個元素的字符串,以空格分隔,每個元素是表示一個合法的距離值(見上文)。例如:"2 3 4 5" 、 "3i 2i 4.5i 2i" 和 "3c 2c 4c 10.43c" 都是合法的區(qū)域值。
relief
決定了組件的邊框樣式。 合法值包括:"raised"、 "sunken" 、"flat" 、"groove" 和 "ridge" 。
scrollcommand
這幾乎就是帶滾動條部件的 set() 方法,但也可是任一只有一個參數(shù)的部件方法。
wrap
只能是以下值之一:"none" 、 "char" 、 "word"。
綁定和事件
部件命令中的 bind 方法可覺察某些事件,并在事件發(fā)生時觸發(fā)一個回調(diào)函數(shù)。bind 方法的形式是:
def bind(self, sequence, func, add=''):
其中:
sequence
是一個表示事件的目標(biāo)種類的字符串。(詳情請看 bind(3tk) 的手冊頁和 John Outsterhout 的書,:title-reference:`Tcl and the Tk Toolkit (2nd edition) 的手冊頁和 John Outsterhout 的書,:title-reference:`Tcl and the Tk Toolkit (2nd edition)),第 201 頁。)
func
是帶有一個參數(shù)的 Python 函數(shù),發(fā)生事件時將會調(diào)用。傳入的參數(shù)為一個 Event 實(shí)例。(以這種方式部署的函數(shù)通常稱為 回調(diào)函數(shù)。)
add
可選項(xiàng), '' 或 '+' 。傳入空字符串表示本次綁定將替換與此事件關(guān)聯(lián)的其他所有綁定。傳遞 '+' 則意味著加入此事件類型已綁定函數(shù)的列表中。
例如:
def turn_red(self, event):event.widget["activeforeground"] = "red"self.button.bind("", self.turn_red)
請注意,在 turn_red() 回調(diào)函數(shù)中如何訪問事件的 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 參數(shù)
很多控件都需要傳入 index 參數(shù)。該參數(shù)用于指明 Text 控件中的位置,或指明 Entry 控件中的字符,或指明 Menu 控件中的菜單項(xiàng)。
Entry 控件的索引(index、view index 等)
Entry 控件帶有索引屬性,指向顯示文本中的字符位置。這些 tkinter 函數(shù)可用于訪問文本控件中的這些特定位置:
Text 控件的索引
Text 控件的索引語法非常復(fù)雜,最好還是在 Tk 手冊中查看。
Menu 索引(menu.invoke()、menu.entryconfig() 等)
菜單的某些屬性和方法可以操縱特定的菜單項(xiàng)。只要屬性或參數(shù)需要用到菜單索引,就可用以下方式傳入:
-
一個整數(shù),指的是菜單項(xiàng)的數(shù)字位置,從頂部開始計(jì)數(shù),從 0 開始;
-
字符串
"active",指的是當(dāng)前光標(biāo)所在的菜單; -
字符串
"last",指的是上一個菜單項(xiàng); -
帶有
@前綴的整數(shù),比如@6,這里的整數(shù)解釋為菜單坐標(biāo)系中的 y 像素坐標(biāo); -
表示沒有任何菜單條目的字符串
"none"經(jīng)常與 menu.activate() 一同被用來停用所有條目,以及 —— -
與菜單項(xiàng)的文本標(biāo)簽進(jìn)行模式匹配的文本串,從菜單頂部掃描到底部。請注意,此索引類型是在其他所有索引類型之后才會考慮的,這意味著文本標(biāo)簽為
last、active或none的菜單項(xiàng)匹配成功后,可能會視為這些單詞文字本身。
圖片
通過 tkinter.Image 的各種子類可以創(chuàng)建相應(yīng)格式的圖片:
-
BitmapImage對應(yīng) XBM 格式的圖片。 -
PhotoImage對應(yīng) PGM、PPM、GIF 和 PNG 格式的圖片。后者自 Tk 8.6 開始支持。
這兩種圖片可通過 file 或 data 屬性創(chuàng)建的(也可能由其他屬性創(chuàng)建)。
然后可在某些支持 image 屬性的控件中(如標(biāo)簽、按鈕、菜單)使用圖片對象。這時,Tk 不會保留對圖片對象的引用。當(dāng)圖片對象的最后一個 Python 引用被刪除時,圖片數(shù)據(jù)也會刪除,并且 Tk 會在用到圖片對象的地方顯示一個空白框。
參見
The Pillow package adds support for formats such as BMP, JPEG, TIFF, and WebP, among others.
文件處理程序
Tk 允許為文件操作注冊和注銷一個回調(diào)函數(shù),當(dāng)對文件描述符進(jìn)行 I/O 時,Tk 的主循環(huán)會調(diào)用該回調(diào)函數(shù)。每個文件描述符只能注冊一個處理程序。示例代碼如下:
import tkinterwidget = tkinter.Tk()mask = tkinter.READABLE | tkinter.WRITABLEwidget.tk.createfilehandler(file, mask, callback)...widget.tk.deletefilehandler(file)
在 Windows 系統(tǒng)中不可用。
由于不知道可讀取多少字節(jié),你可能不希望使用 BufferedIOBase 或 TextIOBase 的 read() 或 readline() 方法,因?yàn)檫@些方法必須讀取預(yù)定數(shù)量的字節(jié)。 對于套接字,可使用 recv() 或 recvfrom() 方法;對于其他文件,可使用原始讀取方法或 os.read(file.fileno(), maxbytecount)。
Widget.tk.createfilehandler(file, mask, func)
注冊文件處理程序的回調(diào)函數(shù) func。 file 參數(shù)可以是具備 fileno() 方法的對象(例如文件或套接字對象),也可以是整數(shù)文件描述符。 mask 參數(shù)是下述三個常量的邏輯“或”組合?;卣{(diào)函數(shù)將用以下格式調(diào)用:
callback(file, mask)
Widget.tk.deletefilehandler(file)
注銷文件處理函數(shù)。
tkinter.READABLE
tkinter.WRITABLE
tkinter.EXCEPTION
Constants used in the mask arguments.
分享名稱:創(chuàng)新互聯(lián)Python教程:tkinter——Tcl/Tk的Python接口
標(biāo)題路徑:http://fisionsoft.com.cn/article/cdighss.html


咨詢
建站咨詢
