先載入一些必備包:
from tkinter import ttk, Tk
from tkinter import N, W, E, S
from tkinter import HORIZONTAL, VERTICAL
from tkinter import StringVar
1 標(biāo)簽:ttk.Label
標(biāo)簽是顯示文本或圖像的小部件建瘫,用戶通常只能查看文本或圖像,但不能與之交互。標(biāo)簽用于識(shí)別控件或用戶界面的其他部分、提供文本反饋或結(jié)果等弯屈。一般的使用方法:
label = ttk.Label(parent, text='')
下面詳細(xì)介紹其主要參數(shù),在 tk/tcl 中被稱為配置選項(xiàng)(configuration option):
1.1 展示文本
在窗口顯示的信息是由 text
設(shè)定的拇勃,對(duì)于用戶來(lái)說(shuō)全释,是不可更改的,但對(duì)于開(kāi)發(fā)者來(lái)說(shuō)闭翩,它是可以改變的挣郭。
root = Tk() # 主窗口
# 設(shè)置標(biāo)簽
label = ttk.Label(root, text='您好')
label.grid() # 在 root 布局
可以通過(guò)索引的方式獲取文本信息:
label['text']
顯示結(jié)果為:
'您好'
也可以通過(guò) configure
函數(shù)獲取文本信息:
label.configure('text')
顯示結(jié)果為:
('text', 'text', 'Text', '', '您好')
由于有兩種獲取文本信息的方式,所以疗韵,對(duì)應(yīng)的也有兩種修改文本信息的方式:
- 索引賦值
label['text'] = '早上好'
- 修改
configure
的text
參數(shù)的值:
label.configure(text='早上好')
1.2 監(jiān)視標(biāo)簽
可以使用 "textvariable"
選項(xiàng)監(jiān)視您的代碼的變量兑障,同時(shí)也支持修改變量取值。
res = StringVar() # 用于監(jiān)視的變量
label['textvariable'] = res
使用 set
方法可以修改監(jiān)視變量:
res.set('再見(jiàn)')
此時(shí) label['text']
的取值也被改變:
label['text']
顯示結(jié)果為:
'再見(jiàn)'
使用get
方法可以獲取監(jiān)視變量的取值:
res.get()
顯示結(jié)果為:
'再見(jiàn)'
1.3 顯示圖片
展示圖片需要兩步,首先使用 PhotoImage
載入圖片旺垒,最后使用 ttk.Label
的 'image'
選項(xiàng)彩库。
from tkinter import PhotoImage
# 先載入圖片
img = PhotoImage(file='images/image.gif')
label['image'] = img # 設(shè)置配置選項(xiàng)
可以設(shè)置 'compound'
選項(xiàng)用于設(shè)定圖片與文本的混搭顯示布局。取值的含義分別為 'text'
(僅顯示文本)先蒋,'image'
(僅顯示圖片)骇钦,'center'
(文本在圖片中央),'top'
(圖片在文本上方)竞漾,'left'
眯搭,'bottom'
和 'right'
。比如:
label['compound'] = 'top'
1.4 布局設(shè)置
雖然標(biāo)簽的整體布局(即標(biāo)簽位于用戶界面中的位置和大幸邓辍)由幾何管理器確定鳞仙,但幾個(gè)特殊的選項(xiàng)可以幫助您更好地控制標(biāo)簽在幾何管理器提供的框中的顯示方式。
如果提供給標(biāo)簽的框大于標(biāo)簽對(duì)其內(nèi)容的要求笔时,則可以使用 "anchor"
選項(xiàng)指定標(biāo)簽應(yīng)附加到哪個(gè)邊或角棍好,這將在相反的邊緣或角中留下任何空白≡使ⅲ可能的值被指定為指南針?lè)较颍?code>"n"(北邊或上邊緣)借笙、"ne"
(東北或右上角)、"e"
较锡、"s"
业稼,"sw"
,"w"
蚂蕴,"nw"
或 "center"
低散。
您還可以使用 "justify"
選項(xiàng)控制文本的對(duì)齊方式,該選項(xiàng)可以具有值 "left", "center" or "right"骡楼。如果只有一行文本熔号,這與使用 "anchor"
選項(xiàng)幾乎相同,但多行文本更有用君编。
比如跨嘉,設(shè)置:
label['anchor'] = 'sw'
1.5 字體、顏色等
帶有 "style"
選項(xiàng)的小部件可用來(lái)修改字體吃嘿、顏色等祠乃。您可以使用 "font"
配置選項(xiàng)指定用于顯示標(biāo)簽文本的字體。
前景(文本)和背景顏色也可以通過(guò) "foreground"
和 "background"
選項(xiàng)進(jìn)行更改兑燥。
label['font'] = 'Arial 20'
label["foreground"] = 'red'
label["background"] = 'lightblue'
# 顯示窗口
root.mainloop()
顯示結(jié)果為:
2 文本輸入框:ttk.Entry
Entry(文本輸入框)為用戶提供了一個(gè)單行文本字段亮瓷,他們可以用來(lái)輸入字符串值。 這些幾乎可以是任何東西:名字降瞳,城市嘱支,密碼蚓胸,社會(huì)保險(xiǎn)號(hào)等等。
使用 ttk.Entry
函數(shù)創(chuàng)建 Entry除师∨嫔牛可以指定 "width"
配置選項(xiàng),以提供 Entry 的寬的字符數(shù)汛聚。例如锹安,允許您為郵政編碼提供一個(gè)較短的 Entry。
通常使用 "textvariable"
配置選項(xiàng)指定的鏈接變量來(lái)訪問(wèn) Entry 的值倚舀。 請(qǐng)注意叹哭,與各種按鈕不同,Entry 旁邊沒(méi)有單獨(dú)的文本或圖像來(lái)標(biāo)識(shí)它們痕貌。 為此使用單獨(dú)的標(biāo)簽小部件风罩。
您也可以直接獲取或更改 Entry 小部件的值,而無(wú)需通過(guò)鏈接變量舵稠。 "get"
方法返回當(dāng)前值超升,"delete"
和 "insert"
(對(duì)應(yīng)插入光標(biāo)的當(dāng)前位置),"end"
(對(duì)應(yīng)已存在文本的后一個(gè)位置),"anchor"
(如果有的話哺徊,對(duì)應(yīng)第一個(gè)被選中的字符)方法可讓您更改內(nèi)容廓俭,例如
print('current value is %s' % name.get())
name.delete(0,'end') # delete between two indices, 0-based
name.insert(0, 'your name') # insert new text at a given index
請(qǐng)注意,Entry小部件沒(méi)有 "command"
選項(xiàng)唉工,每當(dāng) Entry 更改時(shí),該選項(xiàng)都將調(diào)用回調(diào)汹忠。 要監(jiān)視更改淋硝,您應(yīng)該監(jiān)視鏈接變量的更改。
2.1 密碼:Passwords
Entry可用于密碼宽菜,其中實(shí)際內(nèi)容顯示為項(xiàng)目符號(hào)或其他符號(hào)谣膳。 為此,將 "show"
配置選項(xiàng)設(shè)置為要顯示的字符铅乡,例如 “*”继谚。
下面直接看一個(gè)例子:
from tkinter import ttk, Tk, StringVar
if __name__ == '__main__':
root = Tk() # 主窗口
root.title('Entry 測(cè)試')
root.geometry('400x300') # 設(shè)定窗口大小
user_name = StringVar() # 記錄用戶名稱
user_name.set('Tom')
# 設(shè)置字符個(gè)數(shù)不得超過(guò) 7
name = ttk.Entry(root, textvariable=user_name, width=7) # root 上的 Entry 小部件
name.pack()
# 隱藏名稱
hide_name = ttk.Entry(root, textvariable=user_name, show=' ')
hide_name.pack()
# 隱藏為 *
hide_name1 = ttk.Entry(root, textvariable=user_name, show='*')
hide_name1.pack()
root.mainloop()
顯示結(jié)果為:
2.2 小部件狀態(tài):Widget States
像各種按鈕一樣,也可以通過(guò) "state"
命令將 Entry 置于禁用狀態(tài)(并使用 "instate"
查詢)阵幸。 Entry 也可以使用狀態(tài)標(biāo)志 "readonly"
花履; 如果設(shè)置,則用戶無(wú)法更改 Entry挚赊,盡管他們?nèi)匀豢梢赃x擇其中的文本(并將其復(fù)制到剪貼板)诡壁。 還有一個(gè) "invalid"
狀態(tài),如果輸入窗口小部件驗(yàn)證失敗則設(shè)置荠割。(具體說(shuō)明見(jiàn)按鈕:ttk.Button)
2.3 驗(yàn)證輸入內(nèi)容的合法性的
我們需要利用 ttk.Entry
的 'validate'
與 'validatecommand'
選項(xiàng)妹卿,檢查輸入的文本是否合法旺矾,具體的步驟是:
- 定義一個(gè)負(fù)責(zé)檢查輸入內(nèi)容的回調(diào)函數(shù),如果合法則返回
True
夺克,否則返回False
箕宙; - 使用
ttk.Entry
的方法register
將回調(diào)函數(shù)封裝為 Tcl,它會(huì)返回一個(gè)字符串铺纽,用它來(lái)設(shè)定'validatecommand'
選項(xiàng)柬帕; - 設(shè)置
'validate'
,聲明調(diào)用回調(diào)函數(shù)的時(shí)機(jī)室囊,常用的選項(xiàng)有:-
'focus'
:輸入框獲取或者失去焦點(diǎn)時(shí) -
'focusin'
:輸入框獲取焦點(diǎn)時(shí) -
'focusin'
:輸入框失去焦點(diǎn)時(shí) -
'key'
:內(nèi)容改變時(shí) -
'all'
:以上任何情況發(fā)生時(shí) -
'none'
:關(guān)閉內(nèi)容檢查雕崩,這是默認(rèn)值
-
具體的選項(xiàng)描述見(jiàn)下表:
選項(xiàng) | 描述 |
---|---|
'validate' | 該選項(xiàng)設(shè)置是否啟用內(nèi)容驗(yàn)證 |
'invalidcommand' | 1. 指定當(dāng)輸入框輸入的內(nèi)容“非法”時(shí)調(diào)用的函數(shù);2. 也就是指定當(dāng) 'validatecommand' 選項(xiàng)指定的函數(shù)返回 False 時(shí)的函數(shù) |
'validatecommand' | 1. 該選項(xiàng)指定一個(gè)驗(yàn)證函數(shù)融撞,用于驗(yàn)證輸入框內(nèi)容是否合法盼铁;2. 驗(yàn)證函數(shù)需要返回 True 或 False 表示驗(yàn)證結(jié)果;3. 注意尝偎,該選項(xiàng)只有當(dāng) 'validate' 的值非 "none" 時(shí)才有效 |
比如饶火,下面的代碼驗(yàn)證輸入內(nèi)容是否為 "Python":
class Window(Tk):
def __init__(self):
super().__init__()
self.in_var = StringVar() # 輸入變量
self.out_var = StringVar() # 輸出變量
self.input_entry = ttk.Entry(textvariable=self.in_var)
self.input_entry['validate'] = "focusout"
self.input_entry['validatecommand'] = self.test
# 測(cè)試 self.input_entry 光標(biāo) 離開(kāi)之后的驗(yàn)證
self.show_entry = ttk.Entry(textvariable=self.out_var)
self._layout()
def test(self):
'''驗(yàn)證輸入內(nèi)容是否為 Python'''
if self.input_entry.get() == 'Python':
self.out_var.set('輸入正確')
return True
else:
self.out_var.set('輸入錯(cuò)誤')
return False
def _layout(self):
self.input_entry.grid()
self.show_entry.grid()
window = Window()
window.mainloop()
添加如下兩個(gè)設(shè)置:
self.input_entry['invalidcommand'] = self.test2
def test2(self):
self.show_entry.insert('end', " 我被調(diào)用了......")
return True
便可在驗(yàn)證 'invalidcommand'
的使用情況。
2.4 使用注冊(cè)機(jī)制驗(yàn)證輸入內(nèi)容的合法性的
我們也可以使用注冊(cè)機(jī)制驗(yàn)證輸入內(nèi)容的合法性的致扯。即使用配置選項(xiàng) validatecommand=(register_func, s1, s2, ...)
肤寝,其中 register_func
為驗(yàn)證函數(shù)名,s1
抖僵、s2
這些是額外的選項(xiàng)鲤看,這些選項(xiàng)會(huì)作為參數(shù)依次傳給 register_func
函數(shù)。下表列出額外的選項(xiàng)的描述:
額外選項(xiàng) | 含義 |
---|---|
'%d' | 操作代碼:0 表示刪除操作耍群;1 表示插入操作义桂;2 表示獲得、失去焦點(diǎn)或 'textvariable' 變量的值被修改 |
'%i' | 1. 當(dāng)用戶嘗試插入或刪除操作的時(shí)候蹈垢,該選線表示插入或刪除的位置(索引號(hào))慷吊;2. 如果是由于獲得、失去焦點(diǎn)或 'textvariable' 變量的值被修改而調(diào)用驗(yàn)證函數(shù)曹抬,那么該值是 -1 |
'%P' | 1. 當(dāng)輸入框的值允許改變的時(shí)候溉瓶,該值有效;2. 該值為輸入框的最新文本內(nèi)容 |
'%s' | 該值為調(diào)用驗(yàn)證函數(shù)前輸入框的文本內(nèi)容 |
'%S' | 1. 當(dāng)插入或刪除操作觸發(fā)驗(yàn)證函數(shù)的時(shí)候谤民,該值有效堰酿;2. 該選項(xiàng)表示文本被插入和刪除的內(nèi)容 |
'%v' | 該組件當(dāng)前的 'validate' 選項(xiàng)的值 |
'%V' | 1. 調(diào)用驗(yàn)證函數(shù)的原因;2. 該值是 'focusin'赖临,'focusout'胞锰,'key' 或 'forced'('textvariable' 選項(xiàng)指定的變量值被修改)中的一個(gè) |
'%W' | 該組件的名字 |
下面看一個(gè)例子:
class Window(Tk):
def __init__(self):
super().__init__()
self.in_var = StringVar() # 輸入變量
self.out_var = StringVar() # 輸出變量
self.input_entry = ttk.Entry(textvariable=self.in_var)
self.input_entry['validate'] = "focusout"
self.test_cmd= self.register(self.test) # 注冊(cè)
self.input_entry['validatecommand'] = (self.test_cmd, '%P', '%v', '%W')
# 測(cè)試 self.input_entry 光標(biāo) 離開(kāi)之后的驗(yàn)證
self.show_label = ttk.Label(textvariable=self.out_var)
self._layout()
def test(self, content, reason, name):
'''驗(yàn)證輸入內(nèi)容是否為 Python'''
if content == 'Python':
str1 = '輸入正確\n'
str1 += f"{content}, {reason}, {name}"
self.out_var.set(str1)
return True
else:
str1 = '輸入錯(cuò)誤\n'
str1 += f"{content}, {reason}, {name}"
self.out_var.set(str1)
return False
def _layout(self):
self.input_entry.grid()
self.show_label.grid()
window = Window()
window.mainloop()
顯示效果:
您也可以使用類的重寫(xiě)功能修改驗(yàn)證內(nèi)容,比如:
class ValidatingEntry(Entry):
# base class for validating entry widgets
def __init__(self, master, value="", **kw):
apply(Entry.__init__, (self, master), kw)
self.__value = value
self.__variable = StringVar()
self.__variable.set(value)
self.__variable.trace("w", self.__callback)
self.config(textvariable=self.__variable)
def __callback(self, *dummy):
value = self.__variable.get()
newvalue = self.validate(value)
if newvalue is None:
self.__variable.set(self.__value)
elif newvalue != value:
self.__value = newvalue
self.__variable.set(self.newvalue)
else:
self.__value = value
def validate(self, value):
# override: return value, new value, or None if invalid
return value
3 按鈕:ttk.Button
按鈕非常適合用戶交互兢榨,特別是點(diǎn)擊按鈕以執(zhí)行某些操作嗅榕。與標(biāo)簽一樣顺饮,它們可以顯示文本或圖像,但也具有用于控制其行為的一系列新選項(xiàng)凌那。通常它們的內(nèi)容和命令回調(diào)是同時(shí)設(shè)置的:
button = ttk.Button(parent, text='Okay', command=submitForm)
3.1 文本或圖像
按鈕同樣有的 "text"
, "textvariable"
(很少使用)兼雄,"image"
和 "compound"
配置選項(xiàng)作為標(biāo)簽,用于控制按鈕是否顯示文本或圖像(同 ttk.Entry)帽蝶。按鈕還有一個(gè) "default"
選項(xiàng)赦肋,告訴 Tk 按鈕是用戶界面中的默認(rèn)按鈕(即,如果用戶點(diǎn)擊 Enter 或 Return 將調(diào)用的按鈕)(可以使用鍵盤(pán)的 Tab
進(jìn)行按鈕間的跳轉(zhuǎn))励稳。將此選項(xiàng)設(shè)置為 "active"
以指定這默認(rèn)按鈕為激活狀態(tài)佃乘;常規(guī)狀態(tài)為 "normal"
。請(qǐng)注意驹尼,設(shè)置此選項(xiàng)不會(huì)創(chuàng)建事件綁定趣避,需要使返回或輸入鍵激活按鈕。示例如下:
root = Tk()
root.geometry('200x100')
b = ttk.Button(root, text='普通狀態(tài)')
b.grid()
b1 = ttk.Button(root, text='激活狀態(tài)')
b1.grid()
b1["default"] = "active"
root.mainloop()
顯示結(jié)果為:
3.2 按鈕狀態(tài)
按鈕和許多其他小部件的狀態(tài)可以是:正常狀態(tài)新翎,被按下的狀態(tài)程帕,被禁用狀態(tài)(按鈕灰顯且無(wú)法按下,當(dāng)按鈕的命令在給定時(shí)間點(diǎn)不適用時(shí)地啰,將執(zhí)行此操作)愁拭。
其實(shí),所有主題小部件都帶有一個(gè)內(nèi)部狀態(tài)亏吝,這是一系列二進(jìn)制標(biāo)志岭埠。您可以設(shè)置或清除這些不同的標(biāo)志,以及使用 "state"
和 "instate"
方法檢查當(dāng)前設(shè)置蔚鸥。按鈕使用 "disabled"
標(biāo)志來(lái)控制用戶是否可以按下該按鈕枫攀。例如:
主題小部件可用的狀態(tài)標(biāo)志的列表有:"active", "disabled", "focus", "pressed", "selected", "background", "readonly", "alternate" 和 "invalid"。這些都在主題小部件參考中有描述株茶。
3.3 命令回調(diào)
"command"
選項(xiàng)用于在按鈕的操作和應(yīng)用程序之間提供接口。當(dāng)用戶單擊按鈕時(shí)图焰,解釋器將調(diào)用該選項(xiàng)提供的腳本启盛。直接看一個(gè)例子:
root = Tk()
var = StringVar() # 設(shè)置文字變量?jī)?chǔ)存器
lb = ttk.Label(root,
textvariable=var, # 使用 textvariable 替換 text, 因?yàn)檫@個(gè)可以變化
width=15,
background='green', font='Arial 18')
lb.grid()
on_hit = False # 默認(rèn)初始狀態(tài)為 False
def hit_me():
global on_hit
if on_hit: # 從 True 狀態(tài)變成 False 狀態(tài)
on_hit = False
var.set('') # 設(shè)置 文字為空
else: # 從 False 狀態(tài)變成 True 狀態(tài)
on_hit = True
var.set('你打了我') # 設(shè)置標(biāo)簽的文字
b = ttk.Button(root, text='打我', command=hit_me)
b.grid()
root.mainloop()
顯示結(jié)果為:
實(shí)現(xiàn)的功能是:當(dāng)點(diǎn)擊按鈕時(shí),顯示文字 你打了我
技羔,再點(diǎn)一次文字便會(huì)消失僵闯。
還可以要求按鈕從應(yīng)用程序調(diào)用(invoke
)命令回調(diào)。這很有用藤滥,因此您不需要重復(fù)在程序中多次使用 command
鳖粟,即使按鈕的狀態(tài)發(fā)生改變也無(wú)需修改代碼∽景恚可以看一個(gè)例子:
class ClickInvoke(Tk):
def __init__(self):
super().__init__()
self.lb_var1 = StringVar()
self.lb_var2 = StringVar()
self.layout()
def layout(self):
self.lb1 = ttk.Label(textvariable=self.lb_var1, widt=15,
background='green', font='Arial 18')
self.lb2 = ttk.Label(textvariable=self.lb_var2, widt=15,
background='red', font='Arial 18')
self.b1 = ttk.Button(text='Button 1', command=self.click1)
self.b2 = ttk.Button(text='Button 2', command=self.click2)
self.b3 = ttk.Button(text='Button 3', command=self.click3)
self.lb1.grid()
self.b1.grid(column=0, row=1, sticky=(W, E))
self.b2.grid(column=1, row=1, sticky=(W, E))
self.b3.grid(column=2, row=1, sticky=(W, E))
self.lb2.grid()
def click1(self):
self.lb_var1.set('Button 1 clicked.')
self.lb_var2.set('')
def click2(self):
self.lb_var2.set('Button 2 clicked.')
self.lb_var1.set('')
def click3(self):
self.b1.invoke() # 調(diào)用按鈕 `Button 1`
self.lb_var2.set('Button 3 clicked.')
app = ClickInvoke()
app.mainloop()
顯示的結(jié)果為:
實(shí)現(xiàn)的功能是:點(diǎn)擊按鈕 Button 1
時(shí)僅僅顯示綠色區(qū)域的文字向图,點(diǎn)擊按鈕 Button 2
僅僅顯示紅色區(qū)域的文字泳秀,點(diǎn)擊按鈕 Button 3
時(shí),紅色區(qū)域的文字發(fā)生改變榄攀,同時(shí)也回調(diào)了按鈕 Button 1
嗜傅。
4 復(fù)選按鈕:ttk.Checkbutton
復(fù)選按鈕類似于常規(guī)按鈕,不同之處在于用戶不僅可以按下它調(diào)用命令回調(diào)檩赢,而且還包含某種二進(jìn)制值(如 toggle)吕嘀。當(dāng)要求用戶在兩個(gè)選項(xiàng)(例如,兩個(gè)不同的值)之間進(jìn)行選擇時(shí)贞瞒,便可使用復(fù)選按鈕偶房。
創(chuàng)建方法:
measureSystem = StringVar()
check = ttk.Checkbutton(parent, text='Use Metric',
command=metricChanged,
variable=measureSystem,
onvalue='metric', offvalue='imperial')
復(fù)選按鈕使用的選項(xiàng)與常規(guī)按鈕相同: "text", "textvariable"军浆,"image" 和 "compound" 選項(xiàng)控制標(biāo)簽的顯示(復(fù)選框本身旁邊)棕洋,并且 "state" 和 "instate" 方法允許您設(shè)置 " disabled" 狀態(tài)標(biāo)志以啟用或禁用復(fù)選按鈕。 同樣瘾敢, "command" 選項(xiàng)使您可以指定每次用戶切換檢查按鈕時(shí)都要調(diào)用的腳本拍冠, "invoke" 方法也將執(zhí)行相同的回調(diào)。
我們之前已經(jīng)了解了如何使用 "textvariable" 選項(xiàng)將小部件的標(biāo)簽與程序中的變量相關(guān)聯(lián)簇抵。 與之類似庆杜,復(fù)選按鈕使用 "variable"
選項(xiàng)用于讀取或更改窗口小部件的當(dāng)前值,并在切換窗口小部件時(shí)進(jìn)行更新碟摆。 默認(rèn)情況下晃财,選中小部件時(shí)典蜕,復(fù)選按鈕使用的值為 “1” ,未選中時(shí)使用的值為 “0” ,可以使用 "onvalue"
(選中的取值)和 "offvalue"
(未選中的取值) 選項(xiàng)將其更改為幾乎所有值。
看一個(gè)例子:
from tkinter import IntVar
class MyLove(Tk):
def __init__(self):
super().__init__()
self.title('愛(ài)好') # 設(shè)定標(biāo)題
self.geometry('200x100') # 設(shè)定尺寸
self.var1 = IntVar()
self.var2 = IntVar()
self.lb = ttk.Label(background='yellow', width=20, text='')
self.c1 = ttk.Checkbutton(text='Python', variable=self.var1,
command=self.print_love)
self.c2 = ttk.Checkbutton(text='C++', variable=self.var2,
command=self.print_love)
self.lb.grid()
self.c1.grid()
self.c2.grid()
def print_love(self):
if (self.var1.get() == 1) & (self.var2.get() == 0):
self.lb.config(text='僅僅喜歡 Python ')
elif (self.var1.get() == 0) & (self.var2.get() == 1):
self.lb.config(text='僅僅喜歡 C++')
elif (self.var1.get() == 0) & (self.var2.get() == 0):
self.lb['text'] = '都不喜歡'
else:
self.lb['text'] = '都是我的菜'
root = MyLove()
root.mainloop()
顯示結(jié)果為:
當(dāng)鏈接的變量既不包含 "onvalue"
也不包含 "offvalue"
(甚至不存在)時(shí)碍讨,會(huì)發(fā)生什么? 在這種情況下,復(fù)選按鈕將進(jìn)入特殊的 "tristate"
或不確定模式净捅; 您有時(shí)會(huì)在用戶界面中看到此信息,其中的復(fù)選框僅包含一個(gè)破折號(hào),而不是空白或帶有復(fù)選標(biāo)記。 在這種狀態(tài)下柑晒,將設(shè)置狀態(tài)標(biāo)志 "alternate"
,因此可以使用 "instate"
方法進(jìn)行檢查:
check.instate(['alternate'])
由于復(fù)選按鈕不會(huì)自動(dòng)設(shè)置(或創(chuàng)建)鏈接變量嗅绸,因此您的程序需要確保將變量設(shè)置為適當(dāng)?shù)钠鹗贾怠?/p>
5 單選按鈕:ttk.Radiobutton
單選按鈕使您可以在多個(gè)互斥的選項(xiàng)之一之間進(jìn)行選擇羹铅;與選擇按鈕不同,它不僅限于兩個(gè)選擇芳室。 單選按鈕始終在一組中一起使用,當(dāng)選擇的數(shù)量相當(dāng)少(例如3-5)時(shí),它是一個(gè)不錯(cuò)的選擇。
單選按鈕是使用 ttk.Radiobutton
函數(shù)創(chuàng)建的,通常作為一個(gè)集合來(lái)創(chuàng)建:
phone = StringVar()
home = ttk.Radiobutton(parent, text='Home', variable=phone, value='home')
office = ttk.Radiobutton(parent, text='Office', variable=phone, value='office')
cell = ttk.Radiobutton(parent, text='Mobile', variable=phone, value='cell')
單選按鈕與復(fù)選按鈕共享大多數(shù)相同的配置選項(xiàng)禁悠。 一個(gè)例外是將 "onvalue"
和 "offvalue"
選項(xiàng)替換為單個(gè) "value"
選項(xiàng)站玄。 該集合中的每個(gè)單選按鈕將具有相同的鏈接變量,但具有不同的值。 當(dāng)變量具有給定值時(shí)晾剖,單選按鈕將被選中锉矢,否則未選中。 當(dāng)鏈接的變量不存在時(shí)齿尽,單選按鈕還會(huì)顯示 "tristate"
或不確定狀態(tài)沽损,可以通過(guò) "alternate"
狀態(tài)標(biāo)志進(jìn)行檢查。
看一個(gè)例子:
class RadioLove(Tk):
def __init__(self):
super().__init__()
self.title('獨(dú)愛(ài)') # 設(shè)定標(biāo)題
self.geometry('200x100') # 設(shè)定尺寸
self.var = StringVar()
self.lb = ttk.Label(background='yellow', width=20, text='')
self.lb.grid()
r1 = self.radio('選 蘋(píng)果', "蘋(píng)果")
r2 = self.radio('選 香蕉', "香蕉")
r3 = self.radio('選 橘子', "橘子")
[r.grid() for r in (r1, r2, r3)]
def print_love(self):
self.lb['text'] = f"鐘愛(ài)于{self.var.get()}"
def radio(self, text, value):
kw = {
'text': text,
'variable': self.var,
'value': value,
'command': self.print_love
}
return ttk.Radiobutton(**kw)
root = RadioLove()
root.mainloop()
顯示結(jié)果為:
6 ttk.Frame:框架
框架是顯示為簡(jiǎn)單矩形框的小部件循头∶喙溃框架主要用作其他小部件的容器〈叮框架是使用 ttk.Frame
類創(chuàng)建的
frame = ttk.Frame(parent)
框架可以采用幾種不同的配置選項(xiàng)改變其的顯示方式壹士。
6.1 要求的尺寸
像任何其他小部件一樣,創(chuàng)建后偿警,它通過(guò)(父)幾何管理器添加到用戶界面躏救。 通常,框架將向幾何管理器請(qǐng)求的大小將由其中包含的任何小部件的大小和布局確定(這些小部件在管理框架本身內(nèi)容的幾何管理器的控制下)螟蒸。
如果出于某種原因盒使,您想要一個(gè)不包含其他小部件的空框架,則應(yīng)該使用 "width"
或者 "height"
配置選項(xiàng)顯式設(shè)置框架從其父幾何管理器請(qǐng)求的尺寸(否則七嫌,最終會(huì)得到一個(gè)很小的框架)少办。
一般地,幾何管理器的尺寸(Size)使用 "width"
或者 "height"
的配置選項(xiàng)進(jìn)行設(shè)定诵原,其單位默認(rèn)是 pixel(像素)英妓。比如 "350","350c"绍赛,"350i"蔓纠,"350p" 分別表示“350像素”,“350厘米”吗蚌,“350英寸”腿倚,“350打印機(jī)點(diǎn)(1/72 英寸)”。
6.2 Padding:填充
"padding"
配置選項(xiàng)用于在窗口小部件內(nèi)部請(qǐng)求額外的空間蚯妇。這樣敷燎,如果您要在框架中放置其他小部件,則始終會(huì)有一些余量箩言。 單個(gè)數(shù)字始終指定相同的填充硬贯,兩個(gè)數(shù)字的列表可讓您指定水平和垂直填充,而四個(gè)數(shù)字的列表可讓您依次指定左側(cè)陨收,頂部饭豹,右側(cè)和底部的填充。比如:
frame['padding'] = (5,10)
6.3 邊框:Borders
為此,您需要設(shè)置 "borderwidth"
配置選項(xiàng)(默認(rèn)為 0墨状,即沒(méi)有邊框),以及 "relief"
選項(xiàng)菲饼,該選項(xiàng)指定邊框的視覺(jué)外觀: "flat" (默認(rèn))肾砂,"raised", "sunken" 宏悦,"solid"镐确,"ridge" 或 "groove"。比如:
frame['borderwidth'] = 2
frame['relief'] = 'sunken'
6.4 改變風(fēng)格
還有一個(gè) "style"
配置選項(xiàng)饼煞,這對(duì)于所有主題小部件都是通用的源葫,它可以讓您控制其外觀或行為的幾乎任何方面。比如:
style = ttk.Style()
style.configure("BW.TLabel", foreground="black", background="white")
l1 = ttk.Label(text="Test", style="BW.TLabel")
l2 = ttk.Label(text="Test", style="BW.TLabel")
7 一個(gè)例子:創(chuàng)建一個(gè)英尺轉(zhuǎn)換為米的工具
代碼:
from tkinter import ttk, Tk, StringVar
from tkinter import N, W, E, S
class App(ttk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.feet = StringVar()
self.meters = StringVar()
self._layout()
for child in self.winfo_children():
child.grid_configure(padx=5, pady=5)
@property
def widgets(self):
_widgets = [
[ttk.Entry(self, width=14, textvariable=self.feet),
ttk.Label(self, text="feet")],
[ttk.Label(self, text="is equivalent to"),
ttk.Label(self, textvariable=self.meters),
ttk.Label(self, text="meters")],
[ttk.Button(self, text="Calculate", command=self.calculate)]
]
return _widgets
def grid_layout(self):
for n_row, row in enumerate(self.widgets):
for n_col, widget in enumerate(row):
widget.grid(column=n_col, row=n_row, sticky=(E, W))
def _layout(self):
# 設(shè)定 master 的 Resize
self.master.columnconfigure(0, weight=1)
self.master.rowconfigure(0, weight=1)
self['padding'] = 3, 3, 12, 12
self.grid(column=0, row=0, sticky=(N, W, E, S))
self.grid_layout()
def calculate(self, *args):
try:
value = float(self.feet.get())
self.meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0)
except ValueError:
pass
root = Tk()
root.title('Feet to Meters')
app = App(master=root)
app.mainloop()
顯示結(jié)果為:
為了支持 <Enter>
(鍵盤(pán)回車(chē))鍵盤(pán)觸發(fā)事件砖瞧,可以這樣:
class App1(App):
def __init__(self, master=None):
super().__init__(master)
self.widgets[0][0].focus()
self.master.bind('<Return>', self.calculate)
# 鍵盤(pán)觸發(fā)事件
root = Tk()
root.title('Feet to Meters')
app = App1(master=root)
app.mainloop()
如果想要為 ttk.Frame
添加統(tǒng)一的配置息堂,可以這樣:
class App(ttk.Frame):
def __init__(self):
super().__init__()
self.option_add("*Font", "arial 40 bold") # 添加統(tǒng)一的字體設(shè)定