Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut [FAQ Tkinter] Comment contrôler la saisie du texte dans un widget Entry ?

    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:
    %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.
    Code :
    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:
    Code :
    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:
    Code :
    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.
    ---

    Votre avis ?
    Merci d'utiliser le forum pour les questions techniques.

  2. #2
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Question sur la présentation:
    FAQ Python
    - vous devez proposer la question ainsi que la réponse avec le tag [FAQ]
    - placez la Q/R complète dans une balises [quote]


    Comme ceci ?

    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.
    Code :
    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:
    Code :
    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:
    Code :
    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.
    Merci d'utiliser le forum pour les questions techniques.

  3. #3
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    La classe Variable permet d’exécuter une fonction lorsque la valeur change
    Pas très heureux ceci

    Le sujet étant le Widget Entry je ne pense pas que la classe Variable soit a expliquer.
    Une idée pour ce passage ?
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    La première interviens avant l’insertion dans le Widget
    Que pensez vous de ceci ?
    La première interviens avant la modification du texte du Widget
    ?
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Pas mal d'edit en fait : Je vais attendre vos réactions.
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Modérateur

    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2008
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2008
    Messages : 5 322
    Points : 7 423
    Points
    7 423

    Par défaut

    Salut,

    J'ai deux remarques de "fond".

    Plutôt que de parler de "Comment contrôler la saisie du texte dans un widget Entry ?", il serait plus sage de se restreindre à "Comment utiliser la validation du widget Entry?".

    Car, l'usage des variables est "plus large" que... et, après tout, la grosse difficulté est dans la mise en œuvre de "validate".

    Je voulais ensuite parler de "forme" mais à la rédaction, je m'aperçois que ce qui est "brouillardeux" n'est pas tant validateCommand que la création de fonction appelables par Tcl (en général).

    Pour le coup, c'est quelque chose de vraiment spécifique à tkinter mais je n'ai pas trouvé de documentation satisfaisante ailleurs que dans les sources (et quelques exemples qui traînent ici ou là.)


    "idéalement", ce serait peut être pas mal d'avoir 2/3 pages sur cela avec des explications / recommandations. Une fois cela écrit, il sera certainement plus simple de raconter la validation du widget Entry.

    - W
    Architectures Post-Modernes

  7. #7
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Bonsoir wiztricks,

    Dans un premier temps merci de votre réponse.

    A vrais dire je viens de me faire mon 'bas à sable' avec trois propositions:
    Une modification de la FAQ
    Un ajout 'simple' à la FAQ
    Un Ajout 'piège pour moi' à la FAQ: Ce post. Piège ? Le sujet l'est en effet. La validation de l'Entry l'est.
    Piège aussi car je teste ma capacité a expliquer.

    Plutôt que de parler de "Comment contrôler la saisie du texte dans un widget Entry ?", il serait plus sage de se restreindre à "Comment utiliser la validation du widget Entry?".

    Car, l'usage des variables est "plus large" que... et, après tout, la grosse difficulté est dans la mise en œuvre de "validate".
    Comme dit plus haut "validate" est plein de pièges (que j'ai essayer d'éviter dans le texte) et mérite sans doute
    "idéalement", ce serait peut être pas mal d'avoir 2/3 pages sur cela avec des explications / recommandations.
    C'est pour cela que j'ai proposé la solution textvariable (qui est aussi une option du Widget, je reste donc sur celui-ci) pour avoir une 'solution plus simple'

    Car, l'usage des variables est "plus large" que...
    C'est ici pour l'option "textvariable"
    A noter ():
    et est utilisable avec l'option textvariable du Widget Entry.
    Je voulais ensuite parler de "forme" mais à la rédaction, je m'aperçois que ce qui est "brouillardeux" n'est pas tant validateCommand que la création de fonction appelables par Tcl (en général).
    register... Votre avis sur une proposition de code ?

    Je voulais ensuite parler de "forme"
    N'hésitez pas ! C'est mon but en fait.

    @+
    Merci d'utiliser le forum pour les questions techniques.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •