Prawidłowa odpowiedź brzmi: użyj validatecommand
atrybutu widżetu. Niestety ta funkcja jest poważnie niedostatecznie udokumentowana w świecie Tkinter, chociaż jest wystarczająco udokumentowana w świecie Tk. Mimo że nie jest dobrze udokumentowany, zawiera wszystko, co jest potrzebne do walidacji bez uciekania się do powiązań lub zmiennych śledzenia lub modyfikowania widżetu z poziomu procedury walidacji.
Sztuczka polega na tym, aby wiedzieć, że Tkinter może przekazać specjalne wartości do polecenia walidacji. Te wartości zapewniają wszystkie informacje, które musisz znać, aby zdecydować, czy dane są prawidłowe, czy nie: wartość przed edycją, wartość po edycji, jeśli edycja jest prawidłowa, i kilka innych informacji. Aby z nich skorzystać, musisz jednak zrobić małe voodoo, aby przekazać te informacje do polecenia walidacji.
Uwaga: ważne jest, aby polecenie walidacji zwróciło albo True
lubFalse
. Cokolwiek innego spowoduje wyłączenie weryfikacji widgetu.
Oto przykład, który dopuszcza tylko małe litery (i wyświetla wszystkie te funky wartości):
import tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
vcmd = (self.register(self.onValidate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
self.text = tk.Text(self, height=10, width=40)
self.entry.pack(side="top", fill="x")
self.text.pack(side="bottom", fill="both", expand=True)
def onValidate(self, d, i, P, s, S, v, V, W):
self.text.delete("1.0", "end")
self.text.insert("end","OnValidate:\n")
self.text.insert("end","d='%s'\n" % d)
self.text.insert("end","i='%s'\n" % i)
self.text.insert("end","P='%s'\n" % P)
self.text.insert("end","s='%s'\n" % s)
self.text.insert("end","S='%s'\n" % S)
self.text.insert("end","v='%s'\n" % v)
self.text.insert("end","V='%s'\n" % V)
self.text.insert("end","W='%s'\n" % W)
if S == S.lower():
return True
else:
self.bell()
return False
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
Aby uzyskać więcej informacji o tym, co dzieje się pod maską, gdy wywołujesz register
metodę, zobacz tkinter sprawdzania poprawności danych wejściowych