Python tkinter验证会导致重复的字段行为
我试图用tkinter编写一些经过验证的入门类。我使用的是Python 3.3,Anacondas 在下面的代码中,当我开始在两个条目之一中键入文本时,python会在我键入时将该文本插入到另一个字段中。我不想那样。一个字段应为已验证日期,另一个字段应为已验证整数 我做错了什么 如果我注释掉所有e1行,那么它就工作了。如果我注释掉e2行,那么它就工作了。但如果我把两者都放在一起,那么它们就有某种联系Python tkinter验证会导致重复的字段行为,python,python-3.x,tkinter,pydev,anaconda,Python,Python 3.x,Tkinter,Pydev,Anaconda,我试图用tkinter编写一些经过验证的入门类。我使用的是Python 3.3,Anacondas 在下面的代码中,当我开始在两个条目之一中键入文本时,python会在我键入时将该文本插入到另一个字段中。我不想那样。一个字段应为已验证日期,另一个字段应为已验证整数 我做错了什么 如果我注释掉所有e1行,那么它就工作了。如果我注释掉e2行,那么它就工作了。但如果我把两者都放在一起,那么它们就有某种联系 import pandas as pd from tkinter import * clas
import pandas as pd
from tkinter import *
class ValidatedEntry(Entry):
def __init__(self,*args,**kwargs):
Entry.__init__(self,*args,**kwargs)
if 'default_value' in kwargs.keys():
self.default_value = kwargs['default_value']
else:
self.default_value = 0
self.previous_value = self.default_value
self.config(textvariable=self.default_value)
self.register(self.__validate_entry())
self.config(validate='focusout',validatecommand=self.__validate_entry)
def __validate_entry(self):
print('validating')
try:
self.validation_function(self.get())
self.previous_value = self.get()
return True
except Exception:
self.delete(0,END)
self.insert(0,self.previous_value)
return False
def validation_function(self,value):
print('should we get here?')
i=int(self.get())
#raise NotImplemented('This is abstract so you can''t implement it.')
class IntegerEntry(ValidatedEntry):
def validation_function(self,value):
print('checking int {0}'.format(value))
i=int(self.get())
class DateEntry(ValidatedEntry):
def validation_function(self,value):
print('checking date {0}'.format(value))
d=pd.datetime.strptime(value,'%Y-%m-%d')
master = Tk()
e1 = IntegerEntry(master)
e1.pack()
e1.focus_set()
e2 = DateEntry(master)
e2.pack()
b = Button(master, text="get", width=10)
b.pack()
mainloop()
不能使用普通python变量作为
textvariable
属性的值。您需要使用StringVar
、IntVar
、BooleanVar
或DoubleVar
的实例。通过使用一个普通的python变量,可以有效地为两个小部件提供相同的textvariable
,这就是为什么要设置一个,另一个也要设置
但是,由于您实际上没有对任何内容使用textvariable
属性,因此只需完全删除该选项,代码就可以正常工作
这条线看起来也很可疑:
self.register(self.__validate_entry())
它可能没有做你认为它在做的事情。首先,它在启动时调用validate_entry函数,因为用户还没有输入任何数据,所以它可能没有做任何有用的事情——您只是验证默认值。其次,调用register的唯一原因是使用它返回的值,而您完全忽略了它返回的内容。您只需删除该行,它是无用的。此代码提供了一个有效的解决方案:
import pandas as pd
from tkinter import *
from tkinter import messagebox
class ValidatedEntry(Entry):
def __init__(self,master,default_value):
Entry.__init__(self,master)
if not self.validate_value(default_value):
raise ValueError('default_value of wrong type')
self.previous_value = default_value
self.insert(0,default_value)
self.config(validate='focusout',validatecommand=self.__validate_entry)
def __validate_entry(self):
if self.validate_value(self.get()):
self.previous_value = self.get()
return True
else:
messagebox.showinfo('Validation Error', 'validation failed - reverting to previous value of {0}'.format(self.previous_value))
self.delete(0,END)
self.insert(0,self.previous_value)
return False
def validate_value(self,value):
raise NotImplemented('This is abstract so you can''t implement it.')
class FloatEntry(ValidatedEntry):
def validate_value(self,value):
print('checking float {0}'.format(value))
try:
f=float(value)
return True
except Exception:
return False
class IntegerEntry(ValidatedEntry):
def validate_value(self,value):
print('checking int {0}'.format(value))
try:
i=int(value)
return True
except Exception:
return False
class DateEntry(ValidatedEntry):
def validate_value(self,value):
print('checking date {0}'.format(value))
try:
d=pd.datetime.strptime(value,'%Y-%m-%d')
return True
except Exception:
return False
master = Tk()
e1 = IntegerEntry(master,'0')
e1.pack()
e1.focus_set()
e2 = DateEntry(master,'2013-01-01')
e2.pack()
e3 = FloatEntry(master,'10.0')
e3.pack()
b = Button(master, text="get", width=10)
b.pack()
mainloop()
谢谢太完美了!如果你描述了你做了什么来修复它,你的答案会更有用,而不是要求读者看每一行,试图找出你做了什么不同。