La réponse correcte est d'utiliser l'attribut validatecommand
du widget. Malheureusement, cette fonctionnalité est très peu documentée dans le monde de Tkinter, bien qu'elle soit assez bien documentée dans le monde de Tk. Même si ce n'est pas bien documenté, cela vous donne tout ce dont vous avez besoin pour faire une validation sans recourir à des liaisons ou au suivi des variables, ou en modifiant le widget depuis la procédure de validation.
Le truc est de savoir que vous pouvez faire passer à Tkinter des valeurs spéciales à votre commande de validation. Ces valeurs vous fournissent toutes les informations nécessaires pour décider si les données sont valides ou non : la valeur avant l'édition, la valeur après l'édition si l'édition est valide, et plusieurs autres informations. Pour les utiliser, cependant, vous devez faire un peu de magie pour que ces informations soient transmises à votre commande de validation.
Remarque : il est important que la commande de validation renvoie soit True
soit False
. Tout autre chose désactivera la validation pour le widget.
Voici un exemple qui ne permet que les minuscules. Il affiche également les valeurs de toutes les valeurs spéciales à des fins illustratives. Elles ne sont pas toutes nécessaires ; vous avez rarement besoin de plus d'une ou deux.
import tkinter as tk # python 3.x
# import Tkinter as tk # python 2.x
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# valid percent substitutions (from the Tk entry man page)
# note: you only have to register the ones you need; this
# example registers them all for illustrative purposes
#
# %d = Type d'action (1=insertion, 0=suppression, -1 pour les autres)
# %i = indice de la chaîne de caractères à insérer/supprimer, ou -1
# %P = valeur de l'entrée si l'édition est autorisée
# %s = valeur de l'entrée avant l'édition
# %S = la chaîne de texte en cours d'insertion ou de suppression, le cas échéant
# %v = le type de validation actuellement défini
# %V = le type de validation qui a déclenché le rappel
# (key, focusin, focusout, forced)
# %W = le nom tk du widget
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)
# Interdire tout sauf les lettres minuscules
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()
Pour plus d'informations sur ce qui se passe en interne lorsque vous appelez la méthode register
, consultez Pourquoi appeler register() est-il nécessaire pour la validation de saisie tkinter ?
Pour la documentation canonique, consultez la section Validation de la page man de Tk/Tcl Entry