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

Python Discussion :

Quel Entry dans une liste


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2017
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 80
    Localisation : France, Corrèze (Limousin)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2017
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Quel Entry dans une liste
    Bouteille à la mer :
    Débutant en Python, utilisant Spyder, pour un logiciel scientifique j'ai besoin d'entrer des valeurs de paramètres, certaines sont liées entre elles. J'ai donc créé une liste de Entry où je peux mettre des valeurs. Je voudrais pour chaque Entry récupérer son rang quand je tape <Entrée> afin de calculer des valeurs dérivées. Voici un logiciel élémentaire qui ne fonctionne pas car je ne maîtrise pas encore l'utilisation des fonctions lambda !

    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
    # -*- coding: utf-8 -*-
    """
    Created on Sat Jan 26 16:31:01 2022
     
    @author: Utilisateur
    """
    import PIL
    import tkinter as tk
     
    fen = tk.Tk()
     
    values = []
    Evalues = []
    row2 = 0
    mpici = 0
     
     
    def evalprint(num1):
        print("In evalprint  num1=", num1)
     
    for i in range(3) :
        row2 = row2 + 1
        values.append(tk.StringVar(fen, value=0.))
        Evalues.append(tk.Entry(fen, text=values[mpici], width=20))  # makes another Entry box appear      
        Evalues[mpici].grid(column=0, row=row2)
     
        Evalues[mpici].bind('<Return>', lambda num1=mpici : evalprint(num1))
        mpici = mpici+1
     
    fen.mainloop()

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Ca marcherait mieux avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Evalues[mpici].bind('<Return>', lambda e, num1=mpici : evalprint(num1))
    Ce qui ne veut pas dire que ce soit un code "génial"... et pour les explications, il y a des tutos.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 876
    Points : 3 721
    Points
    3 721
    Par défaut
    Citation Envoyé par gpepy Voir le message
    Je voudrais pour chaque Entry récupérer son rang quand je tape <Entrée> afin de calculer des valeurs dérivées.
    Je pense qu'il y a plusieurs solutions...

    Tu pourrais donner un nom à chaque Entry (si tu ne donnes pas un nom explicite de ton choix alors un nom sera donné par défaut, "!entry" pour le premier, "!entry1" pour le second et "!entry2" pour le troisième)

    Ensuite dans ta fonction evalprint tu récupères le nom à l'aide de la fonction : widget.winfo_name et le contenu avec la fonction : get

    Exemple :

    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
    import tkinter as tk
     
    fen = tk.Tk()
     
    def evalprint(evt):
        nom = evt.widget.winfo_name()
        valeur = evt.widget.get()
        print(f"Le nom de l'Entry est: {nom} et son contenu est: {valeur}")
     
     
    Evalues = []
    for i in range(3):
        Evalues.append(tk.Entry(fen, width=20))
        Evalues[i].insert(0, '0.0')
        Evalues[i].grid(column=0, row=i)
        Evalues[i].bind('<Return>', evalprint)
     
    fen.mainloop()
    J'ai supprimé certaines variables de ton code car on pouvait s'en passer...

    J'ai laissé les noms donnés par défaut mais si tu veux donné tes propres noms (ce qui serait préférable pour la lisibilité du code) c'est facile à faire...

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    Je pense qu'il y a plusieurs solutions...

    Tu pourrais donner un nom à chaque Entry (si tu ne donnes pas un nom explicite de ton choix alors un nom sera donné par défaut, "!entry" pour le premier, "!entry1" pour le second et "!entry2" pour le troisième)
    La question du PO est claire: j'ai une liste d'entry, je veux passer l'index de l'entry au callback et je ne m'en sort pas côté lambda pour passer cette info. Après on peut changer de sujet... mais autant éviter de mélanger le TCL way avec la Python way (surtout quand çà n'apporte pas grand chose):
    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
    import tkinter as tk
     
    root = tk.Tk()
    def evalprint(event):
        w = event.widget  
        v = w.get()
        i = entries.index(w)
        print(f"entry {i = } contient: /{ v }/")
     
    entries = []
    for i in range(3):
        w = tk.Entry(root, width=20)
        w.insert(0, '0.0')
        # w.grid(column=0, row=i)
        entries.append(w)
     
    root.bind('<Return>', evalprint)
     
    tk.mainloop()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Invité
    Invité(e)
    Par défaut
    Ou bien sans passer par une liste, ajouter un attribut "index" aux entrées...

    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
    import tkinter as tk
     
    root = tk.Tk()
    def evalprint(event):
        w = event.widget  
        v = w.get()
        i = w._index_
        print(f"entry {i = } contient: { v }")
     
    for i in range(3):
        w = tk.Entry(root, width=20)
        w.insert(0, '0.0')
        w._index_ = i
        w.grid(column=0, row=i)
     
    root.bind('<Return>', evalprint)
     
    tk.mainloop()
    Dernière modification par Invité ; 11/01/2023 à 03h15.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Ou bien sans passer par une liste, ajouter un attribut "index" aux entrées...
    L'ajout d'un attribut à la volée à l'instance d'une classe est possible avec Python mais montrer ça à des débutants comme exemple de ce qu'il faut faire n'est pas très sérieux. Et si on veut aider le PO à réaliser son idée de départ (qui n'est pas plus mauvaise qu'une autre), çà donnerait plutôt:
    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
    import tkinter as tk
     
    def evalprint(i):
        w = entries[i]
        v = w.get()
        print(f"entry {i = } contient: { v }")
     
    entries = [] 
     
    for i in range(3):
        w = tk.Entry(width=20)
        w.insert(0, '0.0')
        w.grid(column=0, row=i)
        w.bind('<Return>', lambda e, i=i: evalprint(i))
        entries.append(w)
     
    tk.mainloop()
    note: et on réfléchit aux petites différences entre les codes.



    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Invité
    Invité(e)
    Par défaut
    Aurais-tu l'amabilité de m'expliquer pourquoi ?
    Il me semble que vous m'aviez déjà fait ce reproche avec Sve@r par le passé.
    Le risque d'écraser un attribut/fonction existant.e ?

    S'il y a une autre raison que je ne vois pas, autant utiliser un dictionnaire, non ?
    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
    import tkinter as tk
     
    root = tk.Tk()
    def evalprint(event):
        w = event.widget  
        v = w.get()
        i = dico[w]
        print(f"entry {i = } contient: { v }")
     
    dico = {} 
    for i in range(3):
        w = tk.Entry(root, width=20)
        w.insert(0, '0.0')
        dico[w] = i
        w.grid(column=0, row=i)
     
    root.bind('<Return>', evalprint)
     
    tk.mainloop()

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Aurais-tu l'amabilité de m'expliquer pourquoi ?
    Une instance d'Entry doit être semblable à une autre instance d'Entry (ce qui n'est plus le cas lorsqu'on "patche" certaines à la volée au lieu de s/classer "proprement").

    Une autre raison est que si nous avons inventé les classes c'est pour fabriquer des boites étanches avec des points de passages bien définis. Définir un attribut à la volée, c'est juste entrer par effraction dans cette boite.

    Citation Envoyé par LeNarvalo Voir le message
    S'il y a une autre raison que je ne vois pas, autant utiliser un dictionnaire, non ?
    Le PO était parti à utiliser un lambda (qui est une autre sorte d'objet) et demandait de l'aide à ce sujet... Après on peut turluter avec les noms de widgets ou remplacer la liste par un dictionnaire... Avez vous lu la question? L'avez vous comprise? Est-ce que vous essayez vraiment d'aider ou juste manifester votre ego?


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Invité
    Invité(e)
    Par défaut
    Ben il n'y a pas de __slots__ visiblement donc c'est pas une effraction mais une porte ouverte.

    Est-ce que vous essayez vraiment d'aider ou juste manifester votre ego ?
    L'amabilité n'aura pas durée
    Tu pourrais peut-être lui expliquer comment utiliser lambda dans ce cas de figure, quitte à être cohérent ?

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Ben il n'y a pas de __slots__ visiblement donc c'est pas une effraction mais une porte ouverte.
    Python est un langage pour adultes... au sens où si on veut une protection semblable à celle des langages compilés, on préférera utiliser un langage compilé.

    Citation Envoyé par LeNarvalo Voir le message
    Tu pourrais peut-être lui expliquer comment utiliser lambda dans ce cas de figure, quitte à être cohérent ?
    Pour moi, ce que j'ai posté dans la première réponse suffit... mais rien ne vous empêche d'expliquer cette ligne de code si cela vous paraît utile/nécessaire. De mon côté, j'estime que le PO est un adulte capable de comprendre (même s'il est encore un peu gribouille) et demander des explications complémentaires si ce n'est pas le cas...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Invité
    Invité(e)
    Par défaut
    Bon ben tu ne m'auras pas convaincu de ne pas squatter les instances de classe.


    Je pense qu'il aurait été utile d'expliquer pourquoi il faut rajouter deux arguments à lambda : lambda e, i=i: evalprint(i), c'est l'erreur que le PO semble faire.
    Je serais bien incapable d'expliquer clairement comment fonctionne lambda, je sais simplement que bind renvoie un argument que l'on nomme usuellement event que l'on retrouve ici sous le forme du e. Pour plus de détails demander à quelqu'un de plus instruit !

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Je pense qu'il aurait été utile d'expliquer pourquoi il faut rajouter deux arguments à lambda : lambda e, i=i: evalprint(i), c'est l'erreur que le PO semble faire.
    Je pense que le PO a suffisamment réfléchi à ce qu'il écrivait avant de poster pour qu'il se dise "mais bien sûr" en voyant la solution.

    Citation Envoyé par LeNarvalo Voir le message
    Je serais bien incapable d'expliquer clairement comment fonctionne lambda, je sais simplement que bind renvoie un argument que l'on nomme usuellement event que l'on retrouve ici sous le forme du e.
    Ici, "lambda" pointe juste la ligne de code qui pose soucis mais est sans rapport avec les fonctions anonymes.

    Citation Envoyé par LeNarvalo Voir le message
    Bon ben tu ne m'auras pas convaincu de ne pas squatter les instances de classe
    Mais je n'espérais pas vous convaincre... car ce n'est pas un sujet académique mais de savoir faire, d'expérience.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 125
    Points : 4 495
    Points
    4 495
    Par défaut
    bonjour
    Citation Envoyé par LeNarvalo Voir le message
    je sais simplement que bind renvoie un argument que l'on nomme usuellement event que l'on retrouve ici sous le forme du e
    j'aime la simplicité mais ici c'est un peu trop...
    Bind prend en paramètre un gestionnaire d'événement
    Un gestionnaire d'événement est une fonction avec obligatoirement un premier paramètre de type (classe) Event (et ici il est nommé e )

    Dans l'exemple (de wiztricks) plus haut, on pouvait aussi écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def evalprint(evenement, ordre):
       ...
    w.bind('<Return>', lambda e, i=i: evalprint(e, i))
    Avec le code de wiztricks, on peut voir qu'il est parfois possible de simplifier en utilisant une fonction (utilisée en interne par lambda !) qui ne prend pas de Event en paramètre.
    $moi= ( !== ) ? : ;

  14. #14
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 837
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 837
    Points : 7 142
    Points
    7 142
    Par défaut
    Bon ben tu ne m'auras pas convaincu de ne pas squatter les instances de classe
    C'est certe une question d'expérience comme le dit @wiztricks, mais aussi de bons sens...

    Quand on sait ce qu'on fait il n'y a pas de problème à faire, mais comme tu ne connais pas forcément la classe Entry qui hérite de multiples autres classes, tu n'as sans doute pas été dans le code source pour vérifier que l'attribut index n'existe pas déjà et serait potentiellement utile au bon fonctionnement du widget. Parce-que lorsqu'on hérite à de multiples classes on hérite pas juste des méthodes mais aussi de ses attributs. Dans ton cas ça tombe pas bien, car tu écrase une méthode index déjà existante.

    Alors c'est pas conseillé, car on fait rarement cela professionnellement, pourquoi on proposerait cela à un débutant ?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  15. #15
    Invité
    Invité(e)
    Par défaut
    Effectivement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> e = tk.Entry()
    >>> hasattr(e, "index")
    True
    >>> hasattr(e, "_index_")
    False

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    C'est certe une question d'expérience comme le dit @wiztricks, mais aussi de bons sens...
    Le "bon sens" ne vient qu'avec l'expérience. On peut accélérer cette acquisition en travaillant en équipe avec des "anciens", en discutant à la cantine ou à la machine à café sur le pourquoi de...

    Quand on bricole dans son coin, on découvre plein de techniques qui marchent mais sans règle permettant d'estimer leur pertinence, on peut faire du grand n'importe quoi sans même s'en rendre compte.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 5
    Dernier message: 14/10/2018, 13h18
  2. [LG]suppression dans une liste chainée
    Par mister_dsg dans le forum Langage
    Réponses: 9
    Dernier message: 16/12/2003, 21h20
  3. [langage] Comment rajouter des champs dans une liste
    Par toto_titi dans le forum Langage
    Réponses: 4
    Dernier message: 28/08/2003, 14h09
  4. Réponses: 2
    Dernier message: 17/08/2003, 20h07
  5. Réponses: 4
    Dernier message: 24/04/2003, 22h28

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