On Fri, 22 Feb 2013 21:59:50 +0600 Teodor the Thinker <doctorl...@gmail.com> wrote:
> Thank you. It was so simple! I changed function return to > return P.isdigit() or (P == "") > and it seems work. > > But it allows empty string not only during editing. I want to make: > when i clear the Entry and switch to another GUI element Entry > rollbacks to last valid value. > > But obvious code to achieve this goal doesnt work: > if P == "" and V == 'focusout': > return False > else: > return (P.isdigit() or P == "") > > I found when "return False" is executed, *s* variable is empty. So i > need to rollback not for last but to *before last* value. Is there a > nice bultin Tkinter way to achieve that or i should declare some > variable with "before last value" by my own? There is no (or at least I don't know of) any built-in way to do this. One possible way to work around this is to store the old value and restore it if required, as in this example: ############################################################## import Tkinter class IntEntry(Tkinter.Entry): def __init__(self, master=None, value=0, **kw): Tkinter.Entry.__init__(self, master, **kw) self._oldvalue = value self.insert('end', value) vcmd = (self.register(self._validate), '%s', '%P') self.configure(validate='all', vcmd=vcmd) self.bind('<FocusOut>', self._focus_out) def _focus_out(self, event): self.get() def _validate(self, old, new): if old != '': self._oldvalue = old if new == '': return True return new.isdigit() def get(self): value = Tkinter.Entry.get(self) if value == '': self.insert('end', self._oldvalue) value = self._oldvalue return int(value) def set(self, value): self.delete(0, 'end') self.insert('end', value) root = Tkinter.Tk() e1 = IntEntry(root, value=111) e1.pack(side='top', padx=100, pady=20) e2 = IntEntry(root, value=222) e2.pack(side='bottom', padx=100, pady=20) def test(event): print 'test' e2.bind('<FocusOut>', test) root.mainloop() ############################################################## This appears to work rather robust, it takes even care that get() will always return a decent value. However you see the weak point of this approach in the second Entry where a new binding to <FocusOut> events stops the validation from working properly. Using the "%V" substitution in the _validate() callback seems not to be exactly an alternative, because calling insert() from within the validation callback will again start validation and the results are hard to predict; sooner or later it may happen that Tk decides to turn off validation at all (at least I never managed to get such setups working). An alternative may (or may not ;) be to use the modified get() as above but to leave the empty Entries alone until some procedure is started by the user that calls get() which will automagically restore the last sane value (that's in fact what I did in one of my programs where I took the above example from). Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Another war ... must it always be so? How many comrades have we lost in this way? ... Obedience. Duty. Death, and more death ... -- Romulan Commander, "Balance of Terror", stardate 1709.2 _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss@python.org http://mail.python.org/mailman/listinfo/tkinter-discuss