Python ttk条目小部件-验证条目-无效的文本条目不会导致还原到以前的文本
Python 3.1 我试图验证ttk.Entry小部件的字符串输入是否可以转换为浮点。下面的简单代码显示validate函数在其任务中是成功的,并且正确返回true/false 我的理解是,如果条目小部件从其validatecommand返回“false”,它应该恢复到在尝试条目发生之前存储在textvariable中的任何内容 但这并没有发生——新条目出现了,尽管它是无效的 想必我错过了一些愚蠢的事情Python ttk条目小部件-验证条目-无效的文本条目不会导致还原到以前的文本,python,validation,ttk,Python,Validation,Ttk,Python 3.1 我试图验证ttk.Entry小部件的字符串输入是否可以转换为浮点。下面的简单代码显示validate函数在其任务中是成功的,并且正确返回true/false 我的理解是,如果条目小部件从其validatecommand返回“false”,它应该恢复到在尝试条目发生之前存储在textvariable中的任何内容 但这并没有发生——新条目出现了,尽管它是无效的 想必我错过了一些愚蠢的事情 from tkinter import * from tkinter.ttk import
from tkinter import *
from tkinter.ttk import *
root = Tk()
text = StringVar()
text.set('100.0')
def validate(inp):
print(inp)
if inp in '0123456789.-+':
try:
float(inp)
print('float')
return True
except ValueError:
print('notfloat')
return False
else:
print('notfloat')
return False
vcmd = root.register(validate)
a = Entry(textvariable = text,
validate = 'focusout',
validatecommand = (vcmd,'%P'))
a.pack()
b = Entry()
b.pack()
root.mainloop()
请尝试以下操作:
from tkinter import *
from tkinter.ttk import *
root = Tk()
text = StringVar()
text.set('100.0')
def validate(inp):
try:
float(inp)
except ValueError:
return False
return True
vcmd = root.register(validate)
a = Entry(textvariable=text,
validate='key',
validatecommand=(vcmd, '%P'))
a.pack()
b = Entry()
b.pack()
root.mainloop()
我使用了validate='key'
并更换validate
功能a检查b中包含的子字符串a
>>> '100.00' in '0123456789.-+'
False
>>> '100.00' in 'blah blah 100.00 blah blah'
True
备选方案 使用
focusout
:
from tkinter import *
from tkinter.ttk import *
root = Tk()
text = StringVar()
text.set('100.0')
last_ok_value = text.get()
def validate(inp):
global last_ok_value
try:
float(inp)
except ValueError:
return False
last_ok_value = inp
return True
def invalidate():
text.set(last_ok_value)
vcmd = root.register(validate)
ivcmd = root.register(invalidate)
a = Entry(textvariable=text,
validate='focusout',
validatecommand=(vcmd, '%P'),
invalidcommand=(ivcmd,))
a.pack()
b = Entry()
b.pack()
root.mainloop()
使用类:
from tkinter import *
from tkinter.ttk import *
class FloatEntry(Entry):
def __init__(self, *args, **kwargs):
initial_value = kwargs.pop('initial_value', '100.00')
assert self.validate(initial_value), 'Invalid initial_value given'
self.last_valid_value = initial_value
self.text = StringVar(value=initial_value)
Entry.__init__(self, *args, textvariable=self.text, **kwargs)
self.vcmd = self.register(self.validate)
self.ivcmd = self.register(self.invalidate)
self['validate'] = 'focusout'
self['validatecommand'] = self.vcmd, '%P',
self['invalidcommand'] = self.ivcmd,
def validate(self, inp):
try:
float(inp)
except ValueError:
return False
self.last_valid_value = inp
return True
def invalidate(self):
self.text.set(self.last_valid_value)
root = Tk()
FloatEntry(initial_value='100.0').pack()
Entry().pack()
root.mainloop()
谢谢-我可以看到需要如何更改验证函数。但你能解释为什么“键”起作用而“聚焦输出”不起作用吗?我想使用focusout-使用“键”意味着临时空白条目(例如,用户在键入自己的条目之前删除默认条目)失败。要扩展它-基本上,在用户完成条目并尝试转到我的应用程序的其他部分后进行验证是有意义的,当他们还在输入/删除/输入框中的任何内容时就不会了。@Tom,我添加了一个使用
focusout
的替代版本。我使用临时变量(last\u ok\u value
)来存储最后一个有效输入。@Tom,使用focusout
,当焦点丢失时调用验证,这与编辑无关。只有键
是可用的。看,是的。那就是我的问题了。似乎正确的方法是定义一个invalidcommand处理程序,将文本设置回原来的状态。(如您所建议的,但将其放在invalidcommand处理程序中,而不是作为验证处理程序的一部分。)