Search code examples
pythontkintertkinter-entry

validatecommand in Tkinter—loop validating?


This is what I have so far

vdcm = (self.register(self.checkForInt), '%S')
roundsNumTB = Entry(self, validate = 'key', validatecommand = vdcm)

Then the checkForInt() function is defined as so

def checkForInt(self, S):
        return (S.isDigit())

The entry box is meant to take an even number, and a number only; not characters. If a character is inputted, it is rejected. This will only work once though. If a character is inputted, the next keystroke which is an input is not rejected.

If someone could tell me how to make it permanently check to make sure the string is a digit, and an even one at that, it would be appreciated.

This is the error message I get if it's any help

Exception in Tkinter callback
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1470, in __call__
    return self.func(*args)
  File "[py directory]", line 101, in checkForInt
    return (S.isDigit())
AttributeError: 'str' object has no attribute 'isDigit'

Solution

  • I think the function call is isdigit() and not isDigit(), note the capitalization difference. If you want to test that the input is an integer and is even you would have to first convert the string using int() and test:

    def checkForEvenInt(self, S):
        if S.isdigit():
            if int(S) % 2 is 0:
                return True
        return False
    

    Keep in mind that Python is quite case-sensitive, including functions. For example, here's an iPython session:

    In [1]: def my_func(): return True
    
    In [2]: my_func()
    Out[2]: True
    
    In [3]: my_Func()
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-25-ac6a0a3aba88> in <module>()
    ----> 1 my_Func()
    
    NameError: name 'my_Func' is not defined