Tkinter - Entry box - formatted for date
Thanks to @Bryan Oakley's major hint, I have come up with this working code.
(Update: threw a few years of programming experience and some recent readers' sharp eyes at improving the code.)
from __future__ import print_functiontry: import Tkinter as tkexcept ImportError: import tkinter as tkclass DateEntry(tk.Frame): def __init__(self, master, frame_look={}, **look): args = dict(relief=tk.SUNKEN, border=1) args.update(frame_look) tk.Frame.__init__(self, master, **args) args = {'relief': tk.FLAT} args.update(look) self.entry_1 = tk.Entry(self, width=2, **args) self.label_1 = tk.Label(self, text='/', **args) self.entry_2 = tk.Entry(self, width=2, **args) self.label_2 = tk.Label(self, text='/', **args) self.entry_3 = tk.Entry(self, width=4, **args) self.entry_1.pack(side=tk.LEFT) self.label_1.pack(side=tk.LEFT) self.entry_2.pack(side=tk.LEFT) self.label_2.pack(side=tk.LEFT) self.entry_3.pack(side=tk.LEFT) self.entries = [self.entry_1, self.entry_2, self.entry_3] self.entry_1.bind('<KeyRelease>', lambda e: self._check(0, 2)) self.entry_2.bind('<KeyRelease>', lambda e: self._check(1, 2)) self.entry_3.bind('<KeyRelease>', lambda e: self._check(2, 4)) def _backspace(self, entry): cont = entry.get() entry.delete(0, tk.END) entry.insert(0, cont[:-1]) def _check(self, index, size): entry = self.entries[index] next_index = index + 1 next_entry = self.entries[next_index] if next_index < len(self.entries) else None data = entry.get() if len(data) > size or not data.isdigit(): self._backspace(entry) if len(data) >= size and next_entry: next_entry.focus() def get(self): return [e.get() for e in self.entries]if __name__ == '__main__': win = tk.Tk() win.title('DateEntry demo') dentry = DateEntry(win, font=('Helvetica', 40, tk.NORMAL), border=0) dentry.pack() win.bind('<Return>', lambda e: print(dentry.get())) win.mainloop()
I have discovered a very simple solution. I hope someone can find it useful.
self.entry1=tk.Entry(self)self.entry1.insert(END, " / / ")self.entry1.config(fg="grey")def datemask(self, event):if len(self.entry1.get()) is 2: self.entry1.insert(END,"/")elif len(self.entry1.get()) is 5: self.entry1.insert(END,"/")elif len(self.entry1.get()) is 11: self.entry1.delete(10, END)
Bind the entry widget
self.entry1.bind('<KeyRelease>', self.datemask)