La risposta corretta è, usa l' validatecommand
attributo del widget. Sfortunatamente questa caratteristica è gravemente poco documentata nel mondo Tkinter, sebbene sia sufficientemente documentata nel mondo Tk. Anche se non è ben documentato, ha tutto il necessario per eseguire la convalida senza ricorrere a binding o variabili di tracciamento o modificare il widget dall'interno della procedura di convalida.
Il trucco è sapere che puoi fare in modo che Tkinter passi valori speciali al tuo comando di convalida. Questi valori forniscono tutte le informazioni necessarie per decidere se i dati sono validi o meno: il valore prima della modifica, il valore dopo la modifica se la modifica è valida e molti altri bit di informazioni. Per usarli, però, devi fare un po 'di voodoo per far passare queste informazioni al tuo comando di validazione.
Nota: è importante che il comando di convalida restituisca True
o False
. Qualsiasi altra cosa provocherà la disattivazione della convalida per il widget.
Ecco un esempio che consente solo il minuscolo (e stampa tutti quei valori funky):
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()
Per ulteriori informazioni su ciò che accade dietro le quinte quando si chiama il register
metodo, vedere tkinter di convalida dell'input