Question

Playing around with Python - tkInter - Entry widget - when I use validatecommand (below), the check happens the first time the string > Max, but when I continue to enter text the check steps - there's no delete or insert after the first time? Any advice? (outside of not building a desktop app via python)


#!/usr/bin/env python
from Tkinter import *

class MyEntry(Entry):

    def __init__(self, master, maxchars):
        Entry.__init__(self, master, validate = "key",    validatecommand=self.validatecommand)
        self.MAX = maxchars

    def validatecommand(self, *args):
        if len(self.get()) >= self.MAX:
            self.delete(0,3)
            self.insert(0, "no")
        return True

if __name__ == '__main__':
    tkmain = Tk()
    e = MyEntry(tkmain, 5)
    e.grid()
    tkmain.mainloop()
Was it helpful?

Solution

From the Tk man:

The validate option will also set itself to none when you edit the entry widget from within either the validateCommand or the invalidCommand. Such editions will override the one that was being validated. If you wish to edit the entry widget (for example set it to {}) during validation and still have the validate option set, you should include the command

after idle {%W config -validate %v}

don't know how to translate that to python.

OTHER TIPS

Here is a code sample that will limit the input to 5 characters:

import Tkinter as tk

master = tk.Tk()

def callback():
    print e.get()

def val(i):
    print "validating"
    print i

    if int(i) > 4:
        print "False"
        return False
    return True

vcmd = (master.register(val), '%i')

e = tk.Entry(master, validate="key", validatecommand=vcmd)
e.pack()

b = tk.Button(master, text="OK", command=lambda: callback())
b.pack()

tk.mainloop()

I threw in a bunch of print statements so you can sort of see what it's doing in the console.

Here are the other substitutions you can pass:

   %d   Type of action: 1 for insert, 0  for  delete,  or  -1  for  focus,
        forced or textvariable validation.

   %i   Index of char string to be inserted/deleted, if any, otherwise -1.

   %P   The value of the entry if the edit is allowed.  If you are config-
        uring  the  entry  widget to have a new textvariable, this will be
        the value of that textvariable.

   %s   The current value of entry prior to editing.

   %S   The text string being inserted/deleted, if any, {} otherwise.

   %v   The type of validation currently set.

   %V   The type of validation that triggered the callback (key,  focusin,
        focusout, forced).

   %W   The name of the entry widget.

I'm sure exactly what the reason is, but I have a hunch. The validation check is done every time the entry is edited. I did some testing and found that it does indeed execute, and can do all sorts of things during the validation every time. What causes it to stop working correctly is when you edit it from within the validatecommand function. This causes it to stop calling the validate function any further. I guess it no longer recognizes further edits to the entry value or something.

lgal Serban seems to have the behind the scenes info on why this occurs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top