tkinter中的小部件验证
问题描述:
我希望用户能够在Spinbox小部件中输入整数值。如果输入的值不是整数或是Spinbox限制外的整数,只要Spinbox失去焦点,Spinbox内容中的值必须恢复为默认值。tkinter中的小部件验证
在示例代码中,我使用Entry小部件仅用于Spinbox可能会失去焦点。
如果用户回到Spinbox输入新值,则他的输入未验证。 我确认马尔科姆在Interactively validating Entry widget content in tkinter中的评论,只要此命令更新小部件的值,就会清除validatecommand=command
功能。
有没有办法让重复验证的Spinbox中输入的值不只是一次?
from tkinter import *
class GUI:
def __init__(self):
# root window of the whole program
self.root = Tk()
self.root.title('Validate Spinbox')
# registering validate and invalid commands
validate_cmd = (self.root.register(self.validate), '%P')
invalid_cmd = (self.root.register(self.invalid))
# creating a Label
items_lbl = Label(self.root, text="# of items (5-10):")
items_lbl.grid(row=0, column=0)
# creating a Spinbox widget
self.items_var = StringVar()
self.items_var.set(7)
items_count = Spinbox(self.root, textvariable=self.items_var,
from_=5, to=10, width=4, validate='focusout',
validatecommand=validate_cmd,
invalidcommand=invalid_cmd)
items_count.grid(row=0, column=1)
# creating an Entry widget
self.entry_var = StringVar()
self.entry_var.set("Input some text here")
text_entry = Entry(self.root, textvariable=self.entry_var)
text_entry.grid(row=1, column=0)
def validate(self, entry):
try:
value = int(entry)
valid = value in range(5, 11)
except ValueError:
valid = False
if not valid:
self.root.bell()
return valid
def invalid(self):
self.items_var.set(7)
if __name__ == '__main__':
main_window = GUI()
mainloop()
答
我发现了一个很好的解释这里(本章的最后一段验证):
http://stupidpythonideas.blogspot.fr/2013/12/tkinter-validation.html
如果您validatecommand(或invalidcommand)直接或间接地修改条目(例如,通过在其StringVar上调用set),只要函数返回,验证就会被禁用。 (这是Tk如何防止无限循环的验证触发另一个验证。)您必须重新打开它(通过调用config)。但是你不能从函数内部做到这一点,因为它在函数返回后被禁用。
但是您需要应用一些更改才能使用此技巧。
你需要让Spinbox
实例属性,与self
:
self.items_count = Spinbox(self.root, textvariable=self.items_var,
from_=5, to=10, width=4, validate='focusout',
validatecommand=validate_cmd,
invalidcommand=invalid_cmd)
self.items_count.grid(row=0, column=1)
然后你就可以调用self.items_count.after_idle(...)
的validate
方法中:
def validate(self, entry):
try:
value = int(entry)
valid = value in range(5, 11)
except ValueError:
valid = False
if not valid:
self.root.bell()
self.items_count.after_idle(lambda: self.items_count.config(validate='focusout'))
return valid
'validatecommand'停留OK,这是'验证“参数绑定到”重点“事件,得到重置 – PRMoureu
@PRMoureu:谢谢你的回应!有没有办法重置** validate **参数?最优选的是:因为我是Python新手,如果您可以修改我的代码,我会非常感激。 – nkana