1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| import tkinter as tk
import winsound
beep = lambda: winsound.Beep(440, 400)
class _Entry(tk.Entry):
_vcmd = _invcmd = None
_ignore_focusout = False
@classmethod
def register_callbacks(cls, master):
root = master.nametowidget('.')
def on_vcmd(p, w):
entry = root.nametowidget(w)
if entry._ignore_focusout:
entry._ignore_focusout = False
return True
return entry.vcmd(p)
def on_invcmd(w):
current = root.focus_get()
if isinstance(current, _Entry):
current._ignore_focusout = True
entry = root.nametowidget(w)
entry.delete(0, 'end')
entry.focus_set()
beep()
cls._vcmd = (root.register(on_vcmd), '%P', '%W')
cls._invcmd = (root.register(on_invcmd), '%W')
def __init__(self, master):
if self._vcmd is None:
self.register_callbacks(master)
super().__init__(master, validate='focusout',
vcmd=self._vcmd, invcmd=self._invcmd)
def vcmd(self, p):
raise NotImplementedError('pure virtual method')
if __name__ == '__main__':
def is_float(s):
try:
float(s)
except ValueError:
return False
else:
return True
class Entry(_Entry):
def vcmd(self, s):
return is_float(s)
root = tk.Tk()
entries = []
for n in range(3):
e = Entry(root)
e.pack()
entries.append(e)
entries[0].focus_set()
tk.mainloop() |
Partager