IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

comment obtenir le NOM du widget qui a le focus ?


Sujet :

Tkinter Python

  1. #1
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 102
    Points : 71
    Points
    71
    Par défaut comment obtenir le NOM du widget qui a le focus ?
    Bonsoir à tous,

    Dans l'exercice ci-après, je souhaiterais obtenir le NOM du Widget qui a le focus mais je ne réussis à avoir que ce qui semble être une adresse.

    L'idée est de pouvoir vérifier la réalité d'un 'float' aprés avoir autorisé le point et le signe moins en plus de 'isdigit'.

    Est-il possible d'obtenir le NOM directement sans passer par l'index.

    L.P.
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    from tkinter import *
     
    def tabul(event):
        w=event.widget
        fen.event_generate('<Tab>')
     
    def OnValidate(S):
        print(fen.focus_get()) # donne l'adresse mais pas le nom
        print( )
        if S.isdigit() :
            return True
        return False
     
    # --------    
    fen= Tk()
    fen.title("validation FLOAT des Entry")
    fen.protocol("WM_DELETE_WINDOW", fen.quit)
    maFonte = "Comic_Sans_MS -14 bold"
     
    # ---------------------------
    validate_cmd = (fen.register(OnValidate), '%S')
     
    e1 = Entry(fen, validate="key", vcmd=validate_cmd )
    e1.bind("<Return>", tabul)
    e1.pack()
     
    e2 = Entry(fen, validate="key", vcmd=validate_cmd)
    e2.bind("<Return>", tabul)
    e2.pack()
     
    e3 = Entry(fen, validate="key", vcmd=validate_cmd)
    e3.bind("<Return>", tabul)
    e3.pack()
     
    e1.focus_set()
     
    # ----------
    etq1=Label(fen, width=20, text='', bg='light blue'); etq1.pack(pady=10)
    # ----------
    Button(fen, font=maFonte, text="QUITTER",
    command=fen.quit).pack(pady=20)
    # ------------ boucle 
    fen.mainloop()
    fen.destroy() 
    # fichier valid_isdigit_00.py

  2. #2
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 102
    Points : 71
    Points
    71
    Par défaut
    re,

    Je viens juste de trouver.. et par hasard...

    il faut ajouter name='le nom_du_widget' dans la ligne de création.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    e1 = Entry(fen, validate="key", name='e1', vcmd=validate_cmd )
    et le 'focus.get()' renvoie le nom au lieu de l'adresse.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Salut,

    Lorsqu'on écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> import tkinter as tk
    >>> app = tk.Tk()
    >>> entry = tk.Entry()
    >>> print(entry)
    .42878848
    '.42878848' est le nom du widget créé, par défaut, à partir de la valeur retournée par 'id(entry)'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> print (id(entry))
    42878848
    tkinter est obligé de créer un nom unique pour fabriquer la variable TCL/Tk qui correspondra au widget.
    l'unicité est assurée par la fabrication du nom à partir de l'id(...) qui est unique.

    Avec name=..., on change ce "défaut":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> entry = tk.Entry(name='entry')
    >>> print(entry)
    .entry
    >>> print (id(entry))
    42826104
    et on prend la responsabilité de fabriquer soit même des noms "uniques".

    Pour ce qui est de valider un float, je ne comprend pas pourquoi vous faites aussi compliqué.
    Vous pourriez définir une fonction isfloat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def isfloat(s):
         try:
              float(s)
              return True
         except:
              return False
    En première approximation, le contenu (non vide) d'une Entry sera un float si isfloat retourne True:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def validate_float(s):
         return isfloat(s)
    Après on fabrique l'Entry:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import tkinter as tk
    app = tk.Tk()
    vcmd = (app.register(validate_float), '%P')
    entry = tk.Entry(validate='key', vcmd=vcmd)
    entry.pack()
    tk.mainloop()
    '%P' étant ce que sera le contenu de la chaîne si on accepte le dernier caractère tapé par l'utilisateur.
    note: reste à traiter le cas "chaîne vide"

    - W

  4. #4
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 102
    Points : 71
    Points
    71
    Par défaut
    Bonjour,

    Bien plus simple en effet mais en fait, je cherchais à comprendre l'utlisation de 'isdigit' suite à la lecture du post de 'Pausekawa' sur ce sujet pour y introduire le point et le signe moins.

    Le code ci-aprés fonctionne ok au moins une fois.
    Dés une erreur de saisie, la fonction 'validate='key' reste à 'none' et je n'arrive pas à la réarmer.

    Sur un tuto tkinter (tkinter-ref5.pdf) il est écrit que :

    "par une curiosité non documentée du gestionnaire vcmd() dans l'exécution du gestionnaire invcmd() remet l'attribut validate à 'none'. Ce qui explique la nécessité de reformuler le validate='key'. "

    Dans le deuxieme bout de code ci-après, l'approche est differente et le validate "key" se réactive.

    Comment réactiver le validate dans le premier bout de code ?

    L.P.

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    from tkinter import *
     
    def tabul(event):
        w=event.widget
        fen.event_generate('<Tab>')
     
    def touche(event):
        w=event.widget
        w.config(validate="key")
        w.car=event.char ; print('w',w.car, event.char)
        print(w.get())
     
    def OnValidate(S):
        w=fen.focus_get() ; print(fen.focus_get()) # donne le nom
    #    w.config(validate="key")
        print(w.get()+ S ) # donne le contenu de l'Entry
    #    print()
        if S.isdigit() or S in ".-" :
            if len(w.get()) == 0 and S == '-':
                print('len w:',len(w.get()))
                return True
            else:
                try:
                    float(w.get() + S)
                    return True
                except:
                    return False
            return False
     
    # --------    
    fen= Tk()
    fen.title("validation FLOAT des Entry")
    fen.protocol("WM_DELETE_WINDOW", fen.quit)
    maFonte = "Comic_Sans_MS -14 bold"
    # --------
    ve1, ve2, ve3 = StringVar(),StringVar(),StringVar()
    # ---------------------------
    validate_cmd = (fen.register(OnValidate), '%S')
     
    e1 = Entry(fen, textvariable=ve1, validate="key", name='e1', vcmd=validate_cmd )
    e1.bind("<Return>", tabul)
    e1.bind("<Key>", touche)
    e1.car=''
    e1.pack()
     
    e2 = Entry(fen, textvariable=ve2, validate="key", name='e2', vcmd=validate_cmd)
    e2.bind("<Return>", tabul)
    e2.bind("<Key>", touche)
    e2.car=''
    e2.pack()
     
    e3 = Entry(fen, textvariable=ve3, validate="key", name='e3', vcmd=validate_cmd)
    e3.bind("<Return>", tabul)
    e3.bind("<Key>", touche)
    e3.car=''
    e3.pack()
     
    e1.focus_set()
     
    # ----------
    etq1=Label(fen, width=20, text='', bg='light blue'); etq1.pack(pady=10)
    # ----------
    Button(fen, font=maFonte, text="QUITTER",
    command=fen.quit).pack(pady=20)
    # ------------ boucle 
    fen.mainloop()
    fen.destroy() 
    # fichier valid_isdigit_01.py
    Dans ce deuxième exo ci-aprés le validate se reformule correctement
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    from tkinter import *
     
    NUM = "-1234567890." # filtrage nécessaire à cause du point et -
     
    def tabul(event):
        w=event.widget
        fen.event_generate('<Tab>')
     
    def affiche(event):
        etq3['text']=''# ; print('e1:',e1,'  e2:',e2)
        w=event.widget # ; print(event.widget, w.get())
    ###    print(txtV1.get())
        global e1, e2 # ; print(e1, e2)
     
        if w == entries[0] and w.get() != '':
            e1 = float(w.get()) # ; print('Saisie.e1',e1)
     
        if w == entries[1] and w.get() != '':
            e2 = float(w.get()) # ; print('Saisie.e2',e2)
     
        if (entries[0].get() !='' and entries[0].get() !='0' )\
            and entries[1].get() !='':
            r = e1 + e2        
    #        r = (e2 / e1 - 1) * 100 # delta en % entre s1 et s2
    #        etq3['text']=str("delta:  {:8.4f} %".format(r))
            etq3['text']=str("Somme:  {:8.4f}".format(r))
    # --------        
    def touche(event):
        w=event.widget # ; print(event.widget)
        w.config(validate="key")
        w.car = event.char
    # --------    
    def chiffres(e):
    #    print(e) # -- trace
    #    if (e.get() + e.car)[0] == '-' and (len(e.get()) + len(e.car))==1:
    #    if (len(e.get()) + len(e.car))==1 and e.car=='-':
        if len(e.get()) ==0 and e.car=='-':
            return 1
        else:
            try:
                float(e.get() + e. car)
                return e.car in NUM
            except:
                return 0
    # --------    
    fen= Tk()
    fen.title("validation FLOAT des Entry")
    fen.protocol("WM_DELETE_WINDOW", fen.quit)
    maFonte = "Comic_Sans_MS -14 bold"
     
    # ---------------------------
    ###txtV1=StringVar() ; txtV=StringVar()
    entries = []
    for z in range(2):
        s=Entry(fen, font=maFonte, name="s%d" %(z+1))
        s.config(vcmd=lambda e=s:chiffres(e), validate = "key")
    ###    s.config(textvariable="txtV%d" %(z+1)) ## o--o--o--o--o--o--o
        s.car=""
        s.bind("<Return>", tabul)
        s.bind("<Key>", touche)
        s.bind("<FocusOut>", affiche)
        s.pack(pady=20, padx=20)
        entries.append(s)
    entries[0].focus_set()
    #e1=1 ; e2=0
    # ----------
    etq3=Label(fen, width=20, text='', bg='light blue'); etq3.pack(pady=10)
    # ----------
    Button(fen, font=maFonte, text="QUITTER",
    command=fen.quit).pack(pady=20)
    # ------------ boucle 
    fen.mainloop()
    fen.destroy() 
    # fichier validation_float_neg_key_ok_00.py

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Salut,

    Citation Envoyé par luc pic Voir le message
    Bien plus simple en effet mais en fait, je cherchais à comprendre l'utlisation de 'isdigit' suite à la lecture du post de 'Pausekawa' sur ce sujet pour y introduire le point et le signe moins.
    C'est une bonne idée. Cependant, je ne vois pas pourquoi il est utile de mélanger des cas d'utilisation de .isdigit avec la validation d'une entrée. Normalement vous pourriez écrire une fonction isfloat qui utilise isdigit ou autre pour retourner un booléen et lui passer différents arguments pour vous assurez que çà fait ce que vous voulez. Mélanger ces essais là avec Tk, c'est un moyen pour se perdre et si nous avons inventé les fonctions c'est justement pour éviter çà.

    Le code ci-aprés fonctionne ok au moins une fois.
    Dés une erreur de saisie, la fonction 'validate='key' reste à 'none' et je n'arrive pas à la réarmer.
    Relisez votre code:
    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
    def OnValidate(S):
        w=fen.focus_get() ; print(fen.focus_get()) # donne le nom
    #    w.config(validate="key")
        print(w.get()+ S ) # donne le contenu de l'Entry
    #    print()
        if S.isdigit() or S in ".-" :
            if len(w.get()) == 0 and S == '-':
                print('len w:',len(w.get()))
                return True
            else:
                try:
                    float(w.get() + S)
                    return True
                except:
                    return False
            return False
    Etes vous sur qu'il retournera True ou False dans tous les cas?

    - W

  6. #6
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Septembre 2010
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : retraité
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Septembre 2010
    Messages : 102
    Points : 71
    Points
    71
    Par défaut
    Bonjour,

    A rester trop longtemps sur le même sujet, j'en ai oublié le B.A BA
    Effectivement il manquait un 'return False'.

    Reste à regler le 'moins' et le 'point' en début de saisie (pour le plaisir)
    Merci pour le coup de main.

    L.P.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/06/2005, 15h11
  2. Comment obtenir le nom complet d'un lecteur réseau ?
    Par Speed41 dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 26/08/2004, 07h55
  3. Comment obtenir le nom d'un pc sur un réseau?
    Par Depteam1 dans le forum MFC
    Réponses: 2
    Dernier message: 19/02/2004, 10h17
  4. Obtenir le nom des services qui tournent ...
    Par vbcasimir dans le forum Administration système
    Réponses: 4
    Dernier message: 21/01/2004, 17h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo