The Tkinter Entry Widget
##簡介
Entry(輸入框)組件通常用于獲取用戶的輸入文本。
##何時使用 Entry 組件?
Entry 組件僅允許用于輸入一行文本,如果用于輸入的字符串長度比該組件可顯示空間更長,那內(nèi)容將被滾動。這意味著該字符串將不能被全部看到(你可以用鼠標(biāo)或鍵盤的方向鍵調(diào)整文本的可見范圍)。
如果你希望接收多行文本的輸入,可以使用 Text 組件(后面介紹)。
##用法
使用代碼為 Entry 組件添加文本,可以使用 insert() 方法。如果要替換當(dāng)前文本,可以先使用 delete() 方法,再使用 insert() 方法實現(xiàn):
from tkinter import *
master = Tk()
e = Entry(master)
e.pack(padx=20, pady=20)
e.delete(0, "end")
e.insert(0, "默認(rèn)文本...")
master.mainloop()
獲取當(dāng)前輸入框的文本,可以使用 get() 方法:
s = e.get()
你也可以綁定 Entry 組件到 Tkinter 變量(StringVar),并通過該變量設(shè)置和獲取輸入框的文本:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("老甲魚")
s = v.get()
下邊的例子演示將 Entry 組件和 Button 組件配合,點(diǎn)擊 “獲取信息” 按鈕時自動清空輸入框并將內(nèi)容輸出:
from tkinter import *
root = Tk()
Label(root,text="作品").grid(row=0,column=0)
Label(root,text="作者").grid(row=1,column=0)
e1 = Entry(root)
e2 = Entry(root)
e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)
def show():
print("作品:《%s》" %e1.get())
print("作者:%s" %e2.get())
e1.delete(0, "end")
e2.delete(0, "end")
Button(root,text = "獲取信息",width = 10,command = show) .grid(row = 3,column = 0,sticky = W,padx =10,pady =5)
Button(root,text = "退出", width = 10,command = root.quit) .grid(row = 3,column = 1,sticky = E,padx =10,pady =5)
mainloop()
(代碼解析:首先就是先來兩個Label標(biāo)簽,分別是作品和作者,然后,剛剛說了這次使用(網(wǎng)格)grid()來布局組件,grid的話他是允許用表格的形式來管理組件的位置,他的選項有row和column分別代表的是行和列,作品這個組件的位置就是在0行0列,作者的位置就是在0行0列,如上圖的分布 接著是兩個輸入框,都是放在root窗口,再使用grid來布局,這兩個輸入框組件,上圖可以看到,他們是位置分別就是0行1列和1行1列,然后再通過padx和pady設(shè)置一下內(nèi)邊距,好看一些 接著是要添加兩個按鈕,首先是第一個按鈕是獲取信息,然后給他設(shè)置一下寬度,在設(shè)置一個command選項,當(dāng)按鈕點(diǎn)下時就去執(zhí)行show方法,那么show方法就是輸入框?qū)ο骵1和e2通過get方法獲取到文本框的內(nèi)容,然后輸出,輸出完后在用delete方法情況輸入框,然后退出的按鈕的command就設(shè)置root.quit就可以了,即調(diào)用根方法的quit方法, 接著就是把這兩個按鈕擺放好,即分別是2行0列和2行1列,但是要求一個按鈕偏左邊,一個靠右邊,這里就需要設(shè)置一個sticky的屬性,sticky就是控制組件在 grid 分配的空間中的位置,他的值和之前的anchor很相似,同樣使用"n", “e”, “s”, “w” 以及它們的組合來定位(ewsn代表東西南北,上北下南左西右東),然后在設(shè)置一下padx和pady他就不會挨著墻角了) ※運(yùn)行成功后點(diǎn)擊退出是沒反應(yīng)的,退不來,因為我們使用的 IDLE 也是使用 tkinter 寫出來的,他們這里會發(fā)生沖突,雙擊你源文件打開,用系統(tǒng)cmd窗口來運(yùn)行就可以正常退出,如果想在IDLE可以退出,可以使用root.destroy
最后需要提到的是 Entry 組件允許通過以下幾種方式指定字符的位置:
※數(shù)字索引號
※"anchoe"
※"end"
※"insert"
鼠標(biāo)坐標(biāo)("@x")
數(shù)字索引號:常規(guī)的 Python 索引號,從 0 開始
"anchor":對應(yīng)第一個被選中的字符(如果有的話)
"end":對應(yīng)已存在文本的后一個位置
"insert":對應(yīng)插入光標(biāo)的當(dāng)前位置
鼠標(biāo)坐標(biāo)("@x"):x 是鼠標(biāo)位置與 Entry 左側(cè)邊緣的水平距離,這樣就可以通過鼠標(biāo)相對地定位字符的位置
##參數(shù) Entry(master=None, **options) (class)
master – 父組件
**options – 組件選項,下方表格詳細(xì)列舉了各個選項的具體含義和用法:
選項 | 含義 | background | 1. 設(shè)置 Entry 的背景顏色 2. 默認(rèn)值由系統(tǒng)指定 | bg | 跟 background 一樣 | borderwidth | 1. 設(shè)置 Entry 的邊框?qū)挾?br> 2. 默認(rèn)值是 1 或 2 像素 | bd | 跟 borderwidth 一樣 | cursor | 1. 指定當(dāng)鼠標(biāo)在 Entry 上飄過的時候的鼠標(biāo)樣式 2. 默認(rèn)值由系統(tǒng)指定 | exportselection | 1. 指定選中的文本是否可以被復(fù)制到剪貼板 2. 默認(rèn)值是 True 3. 可以修改為 False 表示不允許復(fù)制文本 | font | 1. 指定 Entry 中文本的字體 2. 默認(rèn)值由系統(tǒng)指定 | foreground | 1. 設(shè)置 Entry 的文本顏色 2. 默認(rèn)值由系統(tǒng)指定 | fg | 跟 foreground 一樣 | highlightbackground | 1. 指定當(dāng) Entry 沒有獲得焦點(diǎn)的時候高亮邊框的顏色 2. 默認(rèn)值由系統(tǒng)指定 | highlightcolor | 1. 指定當(dāng) Entry 獲得焦點(diǎn)的時候高亮邊框的顏色 2. 默認(rèn)值由系統(tǒng)指定 | highlightthickness | 1. 指定高亮邊框的寬度 2. 默認(rèn)值是 1 或 2 像素 | insertbackground | 指定輸入光標(biāo)的顏色 | insertborderwidth | 1. 指定輸入光標(biāo)的邊框?qū)挾?br> 2. 如果被設(shè)置為非 0 值,光標(biāo)樣式會被設(shè)置為 RAISED 3. 小甲魚溫馨提示:將 insertwidth 設(shè)置大一點(diǎn)才能看到效果哦 | insertofftime | 1. 該選項控制光標(biāo)的閃爍頻率(滅) 2. 單位是毫秒 | insertontime | 1. 該選項控制光標(biāo)的閃爍頻率(亮) 2. 單位是毫秒 | insertwidth | 1. 指定光標(biāo)的寬度 2. 默認(rèn)值是 1 或 2 像素 | invalidcommand | 1. 指定當(dāng)輸入框輸入的內(nèi)容“非法”時調(diào)用的函數(shù) 2. 也就是指定當(dāng) validateCommand 選項指定的函數(shù)返回 False 時的函數(shù) 3. 詳見本內(nèi)容最下方小甲魚關(guān)于驗證詳解 | invcmd | 跟 invalidcommand 一樣 | justify | 1. 定義如何對齊輸入框中的文本 2. 使用 "left","right" 或 "center" 3. 默認(rèn)值是 "left" | relief | 1. 指定邊框樣式 2. 默認(rèn)值是 "sunken" 3. 其他可以選擇的值是 "flat","raised","groove" 和 "ridge" | selectbackground | 1. 指定輸入框的文本被選中時的背景顏色 2. 默認(rèn)值由系統(tǒng)指定 | selectborderwidth | 1. 指定輸入框的文本被選中時的邊框?qū)挾龋ㄟx中邊框) 2. 默認(rèn)值由系統(tǒng)指定 | selectforeground | 1. 指定輸入框的文本被選中時的字體顏色 2. 默認(rèn)值由系統(tǒng)指定 | show | 1. 設(shè)置輸入框如何顯示文本的內(nèi)容 2. 如果該值非空,則輸入框會顯示指定字符串代替真正的內(nèi)容 3. 將該選項設(shè)置為 "*",則是密碼輸入框 | state | 1. Entry 組件可以設(shè)置的狀態(tài):"normal","disabled" 或 "readonly"(注意,它跟 "disabled" 相似,但它支持選中和拷貝,只是不能修改,而 "disabled" 是完全禁止) 2. 默認(rèn)值是 "normal" 3. 注意,如果此選項設(shè)置為 "disabled" 或 "readonly",那么調(diào)用 insert() 和 delete() 方法都會被忽略 | takefocus | 1. 指定使用 Tab 鍵可以將焦點(diǎn)移動到輸入框中 2. 默認(rèn)是開啟的,可以將該選項設(shè)置為 False 避免焦點(diǎn)在此輸入框中 | textvariable | 1. 指定一個與輸入框的內(nèi)容相關(guān)聯(lián)的 Tkinter 變量(通常是 StringVar) 2. 當(dāng)輸入框的內(nèi)容發(fā)生改變時,該變量的值也會相應(yīng)發(fā)生改變 | validate | 1. 該選項設(shè)置是否啟用內(nèi)容驗證 2. 詳見本內(nèi)容最下方小甲魚關(guān)于驗證詳解 | validatecommand | 1. 該選項指定一個驗證函數(shù),用于驗證輸入框內(nèi)容是否合法 2. 驗證函數(shù)需要返回 True 或 False 表示驗證結(jié)果 3. 注意,該選項只有當(dāng) validate 的值非 "none" 時才有效 3. 詳見本內(nèi)容最下方小甲魚關(guān)于驗證詳解 | vcmd | 跟 validatecommand 一樣 | width | 1. 設(shè)置輸入框的寬度,以字符為單位 2. 默認(rèn)值是 20 3. 對于變寬字體來說,組件的實際寬度等于字體的平均寬度乘以 width 選項的值 | xscrollcommand | 1. 與 scrollbar(滾動條)組件相關(guān)聯(lián) 2. 如果你覺得用戶輸入的內(nèi)容會超過該組件的輸入框?qū)挾龋敲纯梢钥紤]設(shè)置該選項 3. 使用方法可以參考:Scrollbar 組件 |
##方法
delete(first, last=None)
— 刪除參數(shù) first 到 last 范圍內(nèi)(包含 first 和 last)的所有內(nèi)容 — 如果忽略 last 參數(shù),表示刪除 first 參數(shù)指定的選項 — 使用 delete(0, END) 實現(xiàn)刪除輸入框的所有內(nèi)容
get()
— 獲得當(dāng)前輸入框的內(nèi)容
icursor(index)
— 將光標(biāo)移動到 index 參數(shù)指定的位置 — 這同時也會設(shè)置 INSERT 的值
index(index)
– 返回與 index 參數(shù)相應(yīng)的選項的序號(例如 e.index(END))
insert(index, text)
— 將 text 參數(shù)的內(nèi)容插入到 index 參數(shù)指定的位置 — 使用 insert(INSERT, text) 將 text 參數(shù)指定的字符串插入到光標(biāo)的位置 — 使用 insert(END, text) 將 text 參數(shù)指定的字符串插入到輸入框的末尾
scan_dragto(x)
— 見下方 scan_mark(x)
scan_mark(x)
— 使用這種方式來實現(xiàn)輸入框內(nèi)容的滾動 — 需要將鼠標(biāo)按下事件綁定到 scan_mark(x) 方法(x 是鼠標(biāo)當(dāng)前的水平位置),然后再將 事件綁定到 scan_dragto(x) 方法(x 是鼠標(biāo)當(dāng)前的水平位置),就可以實現(xiàn)輸入框在當(dāng)前位置和 sacn_mack(x) 指定位置之間的水平滾動
select_adjust(index) — 與 selection_adjust(index) 相同,見下方解釋
select_clear() — 與 selection_clear() 相同,見下方解釋
select_from(index) — 與 selection_from(index) 相同,見下方解釋
select_present() — 與 selection_present() 相同,見下方解釋
select_range(start, end) — 與 selection_range(start, end) 相同,見下方解釋
select_to(index) — 與 selection_to(index) 相同,見下方解釋
selection_adjust(index) — 該方法是為了確保輸入框中選中的范圍包含 index 參數(shù)所指定的字符 — 如果選中的范圍已經(jīng)包含了該字符,那么什么事情也不會發(fā)生 — 如果選中的范圍不包含該字符,那么會從光標(biāo)的位置將選中的范圍擴(kuò)展至該字符
selection_clear() — 取消選中狀態(tài)
selection_from(index) — 開始一個新的選中范圍 — 會設(shè)置 ANCHOR 的值
selection_present() — 返回輸入框是否有處于選中狀態(tài)的文本 — 如果有則返回 True,否則返回 False
selection_range(start, end) — 設(shè)置選中范圍 — start 參數(shù)必須必 end 參數(shù)小 — 使用 selection_range(0, END) 選中整個輸入框的所有內(nèi)容
selection_to(index) – 選中 ANCHOR 到 index 參數(shù)的間的所有內(nèi)容
xview(index) – 該方法用于確保給定的 index 參數(shù)所指定的字符可見 – 如有必要,會滾動輸入框的內(nèi)容
xview_moveto(fraction) – 根據(jù) fraction 參數(shù)給定的比率調(diào)整輸入框內(nèi)容的可見范圍 – fraction 參數(shù)的范圍是 0.0 ~ 1.0,0.0 表示輸入框的開始位置,1.0 表示輸入框的結(jié)束位置
xview_scroll(number, what) – 根據(jù)給定的參數(shù)水平滾動輸入框的可見范圍 – number 參數(shù)指定滾動的數(shù)量,如果是負(fù)數(shù)則表示反向滾動 – what 參數(shù)指定滾動的單位,可以是 UNITS 或 PAGES(UNITS 表示一個字符單元,PAGES 表示一頁)
##關(guān)于驗證詳解 由于查看了不少資料,很多在這里都沒有解釋清楚,所以這里單獨(dú)列出來詳細(xì)講解下。
Entry 組件是支持驗證輸入內(nèi)容的合法性的,比如要求輸入數(shù)字,你輸入了字母那就是非法。實現(xiàn)該功能,需要通過設(shè)置 validate、validatecommand 和 invalidcommand 選項。
首先啟用驗證的“開關(guān)”是 validate 選項,該選項可以設(shè)置的值有:
值 | 含義 | 'focus' | 當(dāng) Entry 組件獲得或失去焦點(diǎn)的時候驗證 | 'focusin' | 當(dāng) Entry 組件獲得焦點(diǎn)的時候驗證 | 'focusout' | 當(dāng) Entry 組件失去焦點(diǎn)的時候驗證 | 'key' | 當(dāng)輸入框被編輯的時候驗證 | 'all' | 當(dāng)出現(xiàn)上邊任何一種情況的時候驗證 | 'none' | 1. 關(guān)閉驗證功能 2. 默認(rèn)設(shè)置該選項(即不啟用驗證) 3. 注意,是字符串的 'none',而非 None |
上面是他可以設(shè)置的值有哪些,表示在什么情況下去驗證,去調(diào)用驗證函數(shù),而驗證函數(shù)是在validatecommand里邊指定的,跟button里邊的command選項是一樣的道理,validatecommand函數(shù)只能返回 True 或 False 表示驗證的結(jié)果。一般情況下驗證函數(shù)只需要知道輸入框的內(nèi)容即可,可以通過 Entry 組件的 get() 方法獲得該字符串。
下邊的例子中,在第一個輸入框輸入“老甲魚”,并通過 Tab 鍵將焦點(diǎn)轉(zhuǎn)移到第二個輸入框的時候,驗證功能被成功觸發(fā):
from tkinter import *
master = Tk()
def test():
if e1.get() == "老甲魚":
print("正確!")
return True
else:
print("錯誤!")
e1.delete(0, "end")
return False
v = StringVar()
e1 = Entry(master, textvariable=v, validate="focusout", validatecommand=test)
e2 = Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
然后,invalidcommand 選項指定的函數(shù)只有在 validatecommand 的返回值為 False 的時候才被調(diào)用。
下邊的例子中,在第一個輸入框輸入“老甲魚”,并通過 Tab 鍵將焦點(diǎn)轉(zhuǎn)移到第二個輸入框,validatecommand 指定的驗證函數(shù)被觸發(fā)并返回 False,接著 invalidcommand 被觸發(fā):
from tkinter import *
master = Tk()
def test():
if e1.get() == "老甲魚":
print("正確!")
return True
else:
print("錯誤!")
e1.delete(0, "end")
return False
def test2():
print("我被調(diào)用了......")
return True
v = StringVar()
e1 = Entry(master, textvariable=v, validate="focusout", validatecommand=test, invalidcommand=test2)
e2 = Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
最后,其實 Tkinter 還有隱藏技能,不過需要冷卻才能觸發(fā),請聽老甲魚一一道來…
Tkinter 為驗證函數(shù)提供一些額外的選項:
Tkinter 為驗證函數(shù)提供一些額外的選項:
額外選項 | 含義 | '%d' | 操作代碼:0 表示刪除操作;1 表示插入操作;2 表示獲得、失去焦點(diǎn)或 textvariable 變量的值被修改 | '%i' | 1. 當(dāng)用戶嘗試插入或刪除操作的時候,該選線表示插入或刪除的位置(索引號) 2. 如果是由于獲得、失去焦點(diǎn)或 textvariable 變量的值被修改而調(diào)用驗證函數(shù),那么該值是 -1 | '%P' | 1. 當(dāng)輸入框的值允許改變的時候,該值有效 2. 該值為輸入框的最新文本內(nèi)容 | '%s' | 該值為調(diào)用驗證函數(shù)前輸入框的文本內(nèi)容 | '%S' | 1. 當(dāng)插入或刪除操作觸發(fā)驗證函數(shù)的時候,該值有效 2. 該選項表示文本被插入和刪除的內(nèi)容 | '%v' | 該組件當(dāng)前的 validate 選項的值 | '%V' | 1. 調(diào)用驗證函數(shù)的原因 2. 該值是 'focusin','focusout','key' 或 'forced'(textvariable 選項指定的變量值被修改)中的一個 | '%W' | 該組件的名字,不過是 tk 變量在內(nèi)部注冊的名字,為一串?dāng)?shù)字。 |
為了使用這些選項,你可以這樣寫:validatecommand=(f, s1, s2, …)
其中,f 就是你“冷卻后”的驗證函數(shù)名,s1、s2、s3 這些就是上面表里額外的選項,這些選項會作為參數(shù)依次傳給 f 函數(shù)。我們剛剛說了,使用隱藏技能前需要冷卻,其實就是調(diào)用 register() 方法將驗證函數(shù)包裝起來: (這個f也就是剛剛的上個例子validatecommand=test方法,在這里直接套進(jìn)去不行,因為這樣子Tkinter他不認(rèn),認(rèn)不了你,所以需要先調(diào)用register() 方法將驗證函數(shù)先包裝起來,包裝成Tkinter能夠認(rèn)出來的東西)
from tkinter import *
master = Tk()
v = StringVar()
def test(content, reason, name):
if content == "老甲魚":
print("正確!")
print(content, reason, name)
return True
else:
print("錯誤!")
print(content, reason, name)
return False
testCMD = master.register(test)
e1 = Entry(master, textvariable=v, validate="focusout", validatecommand=(testCMD, '%P', '%v', '%W'))
e2 = Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
當(dāng)我故意輸入“小甲魚”的時候,DUANG的一下,是錯誤的,后來我輸入“老甲魚”,嘿,又正確了: (解析:對比上個例子可以發(fā)現(xiàn),test方法不再是沒有參數(shù)的方法了,他有三個參數(shù),是在Entry組件的validatecommand選項中出現(xiàn):validatecommand=(testCMD, '%P’, '%v’, '%W’),第一個%P查看上面的表可以知道是表示說他的值是輸入框的最新文本內(nèi)容,就是當(dāng)輸入框的值有改變的時候,%P就會有內(nèi)容作為參數(shù)傳到test方法的content參數(shù),另外兩個也是類似的道理,他們?nèi)齻€作為額外選項,作為參數(shù)傳給test方法,然后%v就是表示該組件當(dāng)前的 validate 選項的值,%W就是表示該組件的名字,在這里該組件就是e1,輸出的就是e1在Tkinter里邊注冊的名字)
|