tkinter验证会导致重复的字段行为

2024-10-01 17:22:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用tkinter编写一些经过验证的入门类。我在python3.3上,水蟒。你知道吗

在下面的代码中,当我开始在两个条目中的一个条目中键入文本时,python会在我键入时将该文本插入到另一个字段中。我不想那样。一个字段应为已验证日期,另一个字段应为已验证整数。你知道吗

我做错什么了?你知道吗

如果我注释掉所有的e1行,那么它就工作了。如果我注释掉e2行,那么它就工作了。但如果我把两者结合在一起,它们就有某种联系。你知道吗

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()

Tags: selfmasterdefaultgetvaluedeffunctionvalidate
2条回答

此代码提供了一个工作解决方案:

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()

不能将普通python变量用作textvariable属性的值。您需要使用StringVarIntVarBooleanVarDoubleVar的实例。通过使用一个普通的python变量,可以有效地为两个小部件提供相同的textvariable,这就是为什么要设置一个,另一个也要设置。你知道吗

但是,由于实际上并没有对任何东西使用textvariable属性,因此只需完全删除该选项,代码就可以运行了。你知道吗

这条线看起来也很可疑:

self.register(self.__validate_entry())        

它可能没有做你认为它在做的事情。首先,它在启动时调用validate\u entry函数,因为用户还没有输入任何数据,所以它可能没有做任何有用的事情,而您只是验证默认值。其次,调用register的唯一原因是使用它返回的值,而您完全忽略了它返回的内容。你应该把那条线去掉,它没用。你知道吗

相关问题 更多 >

    热门问题