Comment contrôler la saisie du texte dans un widget Entry ?
Il existe deux manières de procéder: La validation ou la trace. La première interviens avant la modification du texte du Widget et la seconde solution permet d'en vérifier la saisie.
La validation:
Le Widget Entry dispose des options
validate et
validatecommand (ou
vcmd, ce qui est exactement la même chose) permettant le contrôle de la saisie du texte.
L'option
validatecommand (
vcmd) indique la fonction qui doit être utilisée pour valider le texte. Cette fonction doit impérativement retourner une valeur booléenne.
True valideras la saisie et
False la refuseras.
La difficulté est ici que si la fonction ne retourne pas une valeur booléenne
validate passe à
None et la validation ne se fait plus, le seul moyen de réactiver celle ci étant de redonner sa valeur à l'option
validate (
widget.config(validate=valeur) par exemple).
Il est possible de passer les paramètres suivants à la fonction:
%d Type de l'action: 1 pour insert, 0 pour delete, ou -1 pour une validation "focus", "forced" ou "textvariable". Attention, c'est un string.
%i Index du caractère à insérer/effacer, sinon -1.
%P La valeur que l'entrée de texte doit modifier. Si vous configurez une nouvelle textvariable pour le widget , ce sera la valeur de cette textvariable.
%s La valeur avant l'édition.
%S La chaîne insérée/effacée, sinon {}
%v Le type de validation actuel.
%V Le type de validation qui a déclenché l'appel (key, focusin, focusout, forced).
%W Le nom tcl/tk du widget.
L'option
validate détermine le type d’événement pour lequel on dois utiliser la fonction indiquée par
validatecommand.
Les événements possible sont:
none jamais
all tous
key une touche
focus le widget prend ou perd le focus
focusin le widget prend le focus
focusout le widget perd le focus
L'exemple simple suivant montre un Widget Entry ne prenant en compte que la saisie de chiffres pour un événement de type 'key', soit l'appui sur une touche donc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| try:
import Tkinter as Tk
except:
import tkinter as Tk
def OnValidate(S):
if S.isdigit():
return True
return False
root = Tk.Tk()
validatecmd = (root.register(OnValidate), '%S')
e = Tk.Entry(root, validate="key", vcmd=validatecmd)
e.pack()
root.mainloop() |
Outre le fait que vous pouvez spécifier une action dans la fonction de validation si votre condition n'est pas remplie le Widget Entry propose une option
invalidcommand (ou
invcmd) permettant de spécifier une fonction qui seras évaluée si la fonction de
vcmd retourne
False. La fonction de
invcmd accepte les mêmes paramètres que celle de
vcmd.
Un exemple avec le code précédent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| try:
import Tkinter as Tk
except:
import tkinter as Tk
def OnValidate(S):
if S.isdigit():
return True
return False
def OnError(S):
t = Tk.Toplevel(root)
Tk.Label(t, text="Error: Invalid input %s" % S).pack(padx=5, pady=5)
Tk.Button(t, text="Ok", command=t.destroy).pack(padx=5, pady=5)
root = Tk.Tk()
validatecmd = (root.register(OnValidate), '%S')
errorcmd = (root.register(OnError), '%S')
e = Tk.Entry(root, validate="key", invcmd=errorcmd, vcmd=validatecmd)
e.pack()
root.mainloop() |
La trace:
Pour tracer le contenu de l'Entry nous utilisons la classe Variable Tkinter, et plus précisément la classe
StringVar puisque le contenu du Widget Entry est du texte.
La classe Variable permet d’exécuter une fonction lorsque la valeur change (Merci de vous reporter à la documentation) et est utilisable avec l'option
textvariable du Widget Entry.
Un exemple simple de son utilisation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| try:
import Tkinter as Tk
except:
import tkinter as Tk
def OnValidate(*args):
for c in s.get():
if c.isdigit():
continue
t = Tk.Toplevel(root)
Tk.Label(t, text="Only numbers please").pack(padx=5, pady=5)
Tk.Button(t, text="Ok", command=t.destroy).pack(padx=5, pady=5)
root = Tk.Tk()
s = Tk.StringVar()
s.trace_variable("w", OnValidate)
e = Tk.Entry(root, textvariable=s)
e.pack()
root.mainloop() |
Ici nous n'affichons qu'un Widget Toplevel pour rester poli avec l'utilisateur mais rien n’empêche de désactiver momentanément la trace pour modifier la valeur de
s.
Attention: Il est maladroit de mélanger les deux solutions sous peine de voir les deux événements entrer en interaction.
Partager