Tkinter 元件詳解(七):Entry
Tkinter 元件詳解之Entry
Entry(輸入框)元件通常用於獲取使用者的輸入文字。
何時使用 Entry 元件?
Entry 元件僅允許用於輸入一行文字,如果用於輸入的字串長度比該元件可顯示空間更長,那內容將被滾動。這意味著該字串將不能被全部看到(你可以用滑鼠或鍵盤的方向鍵調整文字的可見範圍)。
如果你希望接收多行文字的輸入,可以使用 Text 元件(後面介紹)。
用法
使用程式碼為 Entry 元件新增文字,可以使用 insert() 方法。如果要替換當前文字,可以先使用 delete() 方法,再使用 insert() 方法實現:
import tkinter as tk master = tk.Tk() e = tk.Entry(master) e.pack(padx=20, pady=20) e.delete(0, "end") e.insert(0, "預設文字...") master.mainloop()
獲取當前輸入框的文字,可以使用 get() 方法:
s = e.get()
你也可以繫結 Entry 元件到 Tkinter 變數(StringVar),並通過該變數設定和獲取輸入框的文字:
v = tk.StringVar()
e = tk.Entry(master, textvariable=v)
e.pack()
v.set("I love Python!")
s = v.get()
下邊的例子演示將 Entry 元件和 Button 元件配合,點選 “獲取資訊” 按鈕時自動清空輸入框並將內容輸出:
import tkinter as tk master = tk.Tk() tk.Label(master, text="作品:").grid(row=0) tk.Label(master, text="作者:").grid(row=1) e1 = tk.Entry(master) e2 = tk.Entry(master) 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") tk.Button(master, text="獲取資訊", width=10, command=show).grid(row=3, column=0, sticky="w", padx=10, pady=5) tk.Button(master, text="退出", width=10, command=master.quit).grid(row=3, column=1, sticky="e", padx=10, pady=5) master.mainloop()
最後需要提到的是 Entry 元件允許通過以下幾種方式指定字元的位置:
- 數字索引號
- "anchoe"
- "end"
- "insert"
滑鼠座標("@x")數字索引號:常規的 Python 索引號,從 0 開始
"anchor":對應第一個被選中的字元(如果有的話)
"end":對應已存在文字的後一個位置
"insert":對應插入游標的當前位置滑鼠座標("@x"):x 是滑鼠位置與 Entry 左側邊緣的水平距離,這樣就可以通過滑鼠相對地定位字元的位置
引數
Entry(master=None, **options)
master -- 父元件
**options -- 元件選項,下方表格詳細列舉了各個選項的具體含義和用法:
選項 | 含義 |
background | 1. 設定 Entry 的背景顏色 2. 預設值由系統指定 |
bg | 跟 background 一樣 |
borderwidth | 1. 設定 Entry 的邊框寬度 2. 預設值是 1 或 2 畫素 |
bd | 跟 borderwidth 一樣 |
cursor | 1. 指定當滑鼠在 Entry 上飄過的時候的滑鼠樣式 2. 預設值由系統指定 |
exportselection | 1. 指定選中的文字是否可以被複制到剪貼簿 2. 預設值是 True 3. 可以修改為 False 表示不允許複製文字 |
font | 1. 指定 Entry 中文字的字型 2. 預設值由系統指定 |
foreground | 1. 設定 Entry 的文字顏色 2. 預設值由系統指定 |
fg | 跟 foreground 一樣 |
highlightbackground | 1. 指定當 Entry 沒有獲得焦點的時候高亮邊框的顏色 2. 預設值由系統指定 |
highlightcolor | 1. 指定當 Entry 獲得焦點的時候高亮邊框的顏色 2. 預設值由系統指定 |
highlightthickness | 1. 指定高亮邊框的寬度 2. 預設值是 1 或 2 畫素 |
insertbackground | 指定輸入游標的顏色 |
insertborderwidth | 1. 指定輸入游標的邊框寬度 2. 如果被設定為非 0 值,游標樣式會被設定為 RAISED 3. 小甲魚溫馨提示:將 insertwidth 設定大一點才能看到效果哦 |
insertofftime | 1. 該選項控制游標的閃爍頻率(滅) 2. 單位是毫秒 |
insertontime | 1. 該選項控制游標的閃爍頻率(亮) 2. 單位是毫秒 |
insertwidth | 1. 指定游標的寬度 2. 預設值是 1 或 2 畫素 |
invalidcommand | 1. 指定當輸入框輸入的內容“非法”時呼叫的函式 2. 也就是指定當 validateCommand 選項指定的函式返回 False 時的函式 3. 詳見本內容最下方小甲魚關於驗證詳解 |
invcmd | 跟 invalidcommand 一樣 |
justify | 1. 定義如何對齊輸入框中的文字 2. 使用 "left","right" 或 "center" 3. 預設值是 "left" |
relief | 1. 指定邊框樣式 2. 預設值是 "sunken" 3. 其他可以選擇的值是 "flat","raised","groove" 和 "ridge" |
selectbackground | 1. 指定輸入框的文字被選中時的背景顏色 2. 預設值由系統指定 |
selectborderwidth | 1. 指定輸入框的文字被選中時的邊框寬度(選中邊框) 2. 預設值由系統指定 |
selectforeground | 1. 指定輸入框的文字被選中時的字型顏色 2. 預設值由系統指定 |
show | 1. 設定輸入框如何顯示文字的內容 2. 如果該值非空,則輸入框會顯示指定字串代替真正的內容 3. 將該選項設定為 "*",則是密碼輸入框 |
state | 1. Entry 元件可以設定的狀態:"normal","disabled" 或 "readonly"(注意,它跟 "disabled" 相似,但它支援選中和拷貝,只是不能修改,而 "disabled" 是完全禁止) 2. 預設值是 "normal" 3. 注意,如果此選項設定為 "disabled" 或 "readonly",那麼呼叫 insert() 和 delete() 方法都會被忽略 |
takefocus | 1. 指定使用 Tab 鍵可以將焦點移動到輸入框中 2. 預設是開啟的,可以將該選項設定為 False 避免焦點在此輸入框中 |
textvariable | 1. 指定一個與輸入框的內容相關聯的 Tkinter 變數(通常是 StringVar) 2. 當輸入框的內容發生改變時,該變數的值也會相應發生改變 |
validate | 1. 該選項設定是否啟用內容驗證 2. 詳見本內容最下方小甲魚關於驗證詳解 |
validatecommand | 1. 該選項指定一個驗證函式,用於驗證輸入框內容是否合法 2. 驗證函式需要返回 True 或 False 表示驗證結果 3. 注意,該選項只有當 validate 的值非 "none" 時才有效 3. 詳見本內容最下方小甲魚關於驗證詳解 |
vcmd | 跟 validatecommand 一樣 |
width | 1. 設定輸入框的寬度,以字元為單位 2. 預設值是 20 3. 對於變寬字型來說,元件的實際寬度等於字型的平均寬度乘以 width 選項的值 |
xscrollcommand | 1. 與 scrollbar(滾動條)元件相關聯 2. 如果你覺得使用者輸入的內容會超過該元件的輸入框寬度,那麼可以考慮設定該選項 3. 使用方法可以參考:Scrollbar 元件 |
方法
delete(first, last=None)
-- 刪除引數 first 到 last 範圍內(包含 first 和 last)的所有內容
-- 如果忽略 last 引數,表示刪除 first 引數指定的選項
-- 使用 delete(0, END) 實現刪除輸入框的所有內容
get()
-- 獲得當前輸入框的內容
icursor(index)
-- 將游標移動到 index 引數指定的位置
-- 這同時也會設定 INSERT 的值
index(index)
-- 返回與 index 引數相應的選項的序號(例如 e.index(END))
insert(index, text)
-- 將 text 引數的內容插入到 index 引數指定的位置
-- 使用 insert(INSERT, text) 將 text 引數指定的字串插入到游標的位置
-- 使用 insert(END, text) 將 text 引數指定的字串插入到輸入框的末尾
scan_dragto(x)
-- 見下方 scan_mark(x)
scan_mark(x)
-- 使用這種方式來實現輸入框內容的滾動
-- 需要將滑鼠按下事件繫結到 scan_mark(x) 方法(x 是滑鼠當前的水平位置),然後再將 <motion> 事件繫結到 scan_dragto(x) 方法(x 是滑鼠當前的水平位置),就可以實現輸入框在當前位置和 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 引數所指定的字元
-- 如果選中的範圍已經包含了該字元,那麼什麼事情也不會發生
-- 如果選中的範圍不包含該字元,那麼會從游標的位置將選中的範圍擴充套件至該字元
selection_clear()
-- 取消選中狀態
selection_from(index)
-- 開始一個新的選中範圍
-- 會設定 ANCHOR 的值
selection_present()
-- 返回輸入框是否有處於選中狀態的文字
-- 如果有則返回 True,否則返回 False
selection_range(start, end)
-- 設定選中範圍
-- start 引數必須必 end 引數小
-- 使用 selection_range(0, END) 選中整個輸入框的所有內容
selection_to(index)
-- 選中 ANCHOR 到 index 引數的間的所有內容
xview(index)
-- 該方法用於確保給定的 index 引數所指定的字元可見
-- 如有必要,會滾動輸入框的內容
xview_moveto(fraction)
-- 根據 fraction 引數給定的比率調整輸入框內容的可見範圍
-- fraction 引數的範圍是 0.0 ~ 1.0,0.0 表示輸入框的開始位置,1.0 表示輸入框的結束位置
xview_scroll(number, what)
-- 根據給定的引數水平滾動輸入框的可見範圍
-- number 引數指定滾動的數量,如果是負數則表示反向滾動
-- what 引數指定滾動的單位,可以是 UNITS 或 PAGES(UNITS 表示一個字元單元,PAGES 表示一頁)
關於驗證詳解
由於查看了不少資料,很多在這裡都沒有解釋清楚,所以這裡單獨列出來詳細講解下。
Entry 元件是支援驗證輸入內容的合法性的,比如要求輸入數字,你輸入了字母那就是非法。實現該功能,需要通過設定 validate、validatecommand 和 invalidcommand 選項。
首先啟用驗證的“開關”是 validate 選項,該選項可以設定的值有:
值 | 含義 |
'focus' | 當 Entry 元件獲得或失去焦點的時候驗證 |
'focusin' | 當 Entry 元件獲得焦點的時候驗證 |
'focusout' | 當 Entry 元件失去焦點的時候驗證 |
'key' | 當輸入框被編輯的時候驗證 |
'all' | 當出現上邊任何一種情況的時候驗證 |
'none' | 1. 關閉驗證功能 2. 預設設定該選項(即不啟用驗證) 3. 注意,是字串的 'none',而非 None |
其次是為 validatecommand 選項指定一個驗證函式,該函式只能返回 True 或 False 表示驗證的結果。一般情況下驗證函式只需要知道輸入框的內容即可,可以通過 Entry 元件的 get() 方法獲得該字串。
下邊的例子中,在第一個輸入框輸入“CSDN” 並通過 Tab 鍵或者滑鼠將焦點轉移到第二個輸入框的時候,驗證功能被成功觸發:
import tkinter as tk
master = tk.Tk()
def test():
if e1.get() == "CSDN":
print("正確!")
return True
else:
print("錯誤!")
e1.delete(0, "end")
return False
v = tk.StringVar()
e1 = tk.Entry(master, textvariable=v, validate="focusout", validatecommand=test)
e2 = tk.Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
然後,invalidcommand 選項指定的函式只有在 validatecommand 的返回值為 False 的時候才被呼叫。
下邊的例子中,在第一個輸入框輸入“csdn”,並通過 Tab 鍵將焦點轉移到第二個輸入框,validatecommand 指定的驗證函式被觸發並返回 False,接著 invalidcommand 被觸發:
import tkinter as tk
master = tk.Tk()
def test():
if e1.get() == "CSDN":
print("正確!")
return True
else:
print("錯誤!")
e1.delete(0, "end")
return False
def test2():
print("我被呼叫了......")
return True
v = tk.StringVar()
e1 = tk.Entry(master, textvariable=v, validate="focusout", validatecommand=test, invalidcommand=test2)
e2 = tk.Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
最後,其實 Tkinter 還有隱藏技能,不過需要冷卻才能觸發,請聽我一一道來......
Tkinter 為驗證函式提供一些額外的選項:
額外選項 | 含義 |
'%d' | 操作程式碼:0 表示刪除操作;1 表示插入操作;2 表示獲得、失去焦點或 textvariable 變數的值被修改 |
'%i' | 1. 當用戶嘗試插入或刪除操作的時候,該選線表示插入或刪除的位置(索引號) 2. 如果是由於獲得、失去焦點或 textvariable 變數的值被修改而呼叫驗證函式,那麼該值是 -1 |
'%P' | 1. 當輸入框的值允許改變的時候,該值有效 2. 該值為輸入框的最新文字內容 |
'%s' | 該值為呼叫驗證函式前輸入框的文字內容 |
'%S' | 1. 當插入或刪除操作觸發驗證函式的時候,該值有效 2. 該選項表示文字被插入和刪除的內容 |
'%v' | 該元件當前的 validate 選項的值 |
'%V' | 1. 呼叫驗證函式的原因 2. 該值是 'focusin','focusout','key' 或 'forced'(textvariable 選項指定的變數值被修改)中的一個 |
'%W' | 該元件的名字 |
為了使用這些選項,你可以這樣寫:validatecommand=(f, s1, s2, ...)
其中,f 就是你“冷卻後”的驗證函式名,s1、s2、s3 這些是額外的選項,這些選項會作為引數依次傳給 f 函式。我們剛剛說了,使用隱藏技能前需要冷卻,其實就是呼叫 register() 方法將驗證函式包裝起來:
import tkinter as tk
master = tk.Tk()
v = tk.StringVar()
def test(content, reason, name):
if content == "CSDN":
print("正確!")
print(content, reason, name)
return True
else:
print("錯誤!")
print(content, reason, name)
return False
testCMD = master.register(test)
e1 = tk.Entry(master, textvariable=v, validate="focusout", validatecommand=(testCMD, '%P', '%v', '%W'))
e2 = tk.Entry(master)
e1.pack(padx=10, pady=10)
e2.pack(padx=10, pady=10)
master.mainloop()
當我故意輸入“CSDN我愛你”的時候,DUANG的一下,是錯誤的,後來我果斷刪除了“我愛你”,嘿,又正確了: