关于验证详解
Entry 组件是支持验证输入内容的合法性的,比如要求输入数字,你输入了字母那就是非法。实现该功能,需要通过设置 validate、validatecommand 和 invalidcommand 选项。
首先启用验证的“开关”是 validate 选项,该选项可以设置的值有:
值 | 含义 |
'focus' | 当 Entry 组件获得或失去焦点的时候验证 |
'focusin' | 当 Entry 组件获得焦点的时候验证 |
'focusout' | 当 Entry 组件失去焦点的时候验证 |
'key' | 当输入框被编辑的时候验证 |
'all' | 当出现上边任何一种情况的时候验证 |
'none' | 1. 关闭验证功能 2. 默认设置该选项(即不启用验证) 3. 注意,是字符串的 'none',而非 None |
invalidcommand 选项指定的函数只有在 validatecommand 的返回值为 False 的时候才被调用。
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() 方法将验证函数包装起来。
EG1:
from tkinter import *
root = Tk()
def test(content, reason, name):
if e1.get() == "peanutfish":
print('Bingo!', content, reason, name)
return True
else:
print('Wrong Wrong!', content, reason, name)
return False
def test2():
print('invalidcommand is called!')
v = StringVar()
CMD = root.register(test)
e1 = Entry(root, textvariable=v, validate='focus', validatecommand=(CMD, '%P', '%V', '%W'), invalidcommand=test2) #使用了传入内容,判断原因,内存中的名称
e1.pack(padx=10, pady=10)
e2 = Entry(root)
e2.pack(padx=10, pady=10)
mainloop()
EG2: 模拟简单的加法计算器:
from tkinter import *
root = Tk()
v1 = StringVar()
v2 = StringVar()
v3 = StringVar()
def check(num):
return num.isdigit():
CMD = root.register(check)
e1 = Entry(root, textvariable=v1, validate='key', validatecommand=(CMD, '%P'))
e2 = Entry(root, textvariable=v2, validate='key', validatecommand=(CMD, '%P'))
e3 = Entry(root, textvariable=v3, state='readonly')
e1.grid(row=0, column=0, padx=10, pady=10)
e2.grid(row=0, column=2, padx=10, pady=10)
e3.grid(row=0, column=4, padx=10, pady=10)
l1 = Label(root, text='+', font='20').grid(row=0, column=1)
l2 = Label(root, text='=', font='20').grid(row=0, column=3)
def calc():
total = int(e1.get()) + int(e2.get())
v3.set(str(total))
b = Button(root, text='Calculate', command=calc).grid(row=1, column=2)
mainloop()
原文: