Bonjour,
Comme je trouve que la partie de la FAQ sur le Widget Entry un peut légère je vous propose de rajouter du piment avec ce qui suit:
---
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:
L'option validate détermine le type d’événement pour lequel on dois utiliser la fonction indiquée par validatecommand.%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.
Les événements possible sont:
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.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
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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()
Un exemple avec le code précédent:
La trace:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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()
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:
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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()
Attention: Il est maladroit de mélanger les deux solutions sous peine de voir les deux événements entrer en interaction.
---
Votre avis ?
Partager