[Tkinter-discuss] validation woes

Jeff Cagle jrcagle at juno.com
Wed Oct 1 05:15:23 CEST 2008


I want an Entry widget to accept a single digit only.  Here's the attempt:

---
import Tkinter as Tk

class MyEntry(Tk.Entry):

    def __init__(self, parent, **kwargs):
        kwargs['validate']='key'     # could also be 'all' -- has the 
same result
        kwargs['vcmd']=self.validate
        Tk.Entry.__init__(self, parent, **kwargs)

    def validate(self):
        print self.get()  # diagnostic only
        if self.get() in [''] + list("123456789"):
            return True
        else:
            self.bell()
            return False

if __name__=="__main__":
    main = Tk.Tk()
    main.e = MyEntry(main)
    main.e.grid()
    main.mainloop()

---

I'd like to think this is straightforward, but No.

I type in MyEntry: 1
printed value: (empty string)
contents of MyEntry: 1

I type in MyEntry: 11
printed value: 1
contents of MyEntry: 11

I type in MyEntry: 111 (bell rings)
printed value: 11
contents of MyEntry: 11

I type in MyEntry: a
printed value: (empty string)
contents of MyEntry: a

I type in MyEntry: a1 (bell rings)
printed value: a
contents of MyEntry: a

Near as I can tell, validate() is called after a key is pressed and 
displayed in the Entry widget, but *before* the pressed key has been 
added to MyEntry's contents.  Hence, validate() has no way of knowing 
what the new keypress is -- it can only validate the past entry.  Once 
it does so, the new key is added to MyEntry's contents.

How can validate() discover the new keypress in order to validate it 
prior to addition to the Entry widget?  Yikes!

Thanks in advance,
Jeff Cagle




More information about the Tkinter-discuss mailing list