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 :

nommer un widget à partir d'une liste de noms


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Octobre 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2010
    Messages : 24
    Points : 21
    Points
    21
    Par défaut nommer un widget à partir d'une liste de noms
    Bonjour,

    J'essaie de reconstituer un tableur
    je place 10x10 widget Entry
    je voudrais attribuer à chacun, comme nom, son adresse
    bien sûr, je peux faire 100 fois cela:
    L1C1 = Entry(fenetre, ...)

    mais je voudrais attribuer le nom à partir d'une liste:
    noms = ["L1C1", "L1C2",...]

    ceci ne fonctionne pas ("L1C1 is not defined"):
    noms[0] = Entry(fenetre,...)

    je comprends qu'à gauche de '=' devrait se trouver un nom, pas une variable,
    ou bien existe-t-il un moyen de faire ce que je veux?

    Merci d'avance

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 302
    Points : 6 782
    Points
    6 782
    Par défaut
    Salut,

    Et si tu mets dans ta liste les instances de tes entry, ça ne te convient pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    entries = []
    for i in range(10):
        entries[i] = Entry(....
    L'ordre de ta liste te permettra toujours de retrouver la bonne entry.

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

    A la base, vous voulez associer un couple (i, j) à un objet.

    mais je voudrais attribuer le nom à partir d'une liste:
    noms = ["L1C1", "L1C2",...]
    Cette liste est une représentation de l'ensemble des couples (i, j) pour i, j dans [1..10] et les fonctions pour passer de (i, j) à "LiCj" sont simples.

    Dans la pratique, associer (i, j) à un objet, passe par choisir la collection qui permettra de récupérer l'objet associé à (i, j).
    Une liste (tableau) permet de faire cela de façon simple: (i, j) => v = 10*i + j.
    Mais vous devez explicitez les fonctions.

    Un dictionnaire (un dict) permet d'écrire map[(i, j)] = objet.
    La fonction d'accès sera moins performante que pour la liste mais le code sera plus proche de ce que vous voulez exprimer.
    Et rien n'empêche d'écrire map['L1C2'] = objet.

    Ce sont des principes.
    Comment les appliquer dans le contexte tkinter?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    noms = ["L1C1", "L1C2",...]
    for name in noms:
         Entry(fenetre, name=name,...)
    En fait "fenêtre" contient déjà un dict dans lequel seront rangés les "fils" avec pour nom par défaut ce que retourne id(instance d'entry). name=... permet de changer ce défaut.
    Pour récupérer l'entry suivant "name", çà passe par fenetre.children[name].

    Ceci dit, si vous voulez réaliser un tableur, le module TkTable mérite d'être regardé, utilisé,...
    Détail: il n'est pas inclus, par défaut, dans la distribution de Python
    - W

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Plus 'globalement' et avec modération svp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> root = tk.Tk()
    >>> for names in ("L1C1", "L1C2"):
    ...     globals()[names] = tk.Entry(root)
    ...     globals()[names].pack()
    ... 
    >>> root.mainloop()
    Tournez vous plus vers un dictionnaire 'a part' comme vous l'indique wiztricks.

    @+

  5. #5
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Octobre 2010
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2010
    Messages : 24
    Points : 21
    Points
    21
    Par défaut
    Merci à tous pour cette solution:

    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
     
    from tkinter import *
     
    fenetre = Tk()
     
    for ligne in range(1,11):
        for colonne in range(1,11):
            nom = "L" + str(ligne)+ "C" + str(colonne)
            globals()[nom] = Entry(fenetre,width = 10,justify = "center")
            globals()[nom].grid(row = ligne,column = colonne)
     
    # test
    print(L5C5["width"])
    ##print(globals())
     
    fenetre.mainloop()

  6. #6
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 923
    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 923
    Points : 7 322
    Points
    7 322
    Par défaut
    Autant vous dire tout de suite que ce n'est pas la bonne manière de faire, d'où la phrase de PauseKawa

    avec modération
    Un Entry comme le reste des widgets Tkinter (et le fonctionnement est le même pour n'importe quel framework), sont des objets que l'on peut insérer et gérer facilement à l'aide d'un conteneur tel que tuple ou liste.

    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
    >>> from tkinter import *
     
    >>> 
    >>> fenetre = Tk()
    >>> 
    >>> 
    >>> LC = []
    >>> 
    >>> for ligne in range(1, 11):
    ...     for colonne in range(1, 11):
    ...         ent = Entry(fenetre, width=10, justify="center")
    ...         ent.grid(row=ligne, column=colonne)
    ...         LC.append(ent)
    ... 
    >>> print(LC[5]["width"])
    10
    >>> 
    >>> fenetre.mainloop()

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 379
    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 379
    Points : 36 923
    Points
    36 923
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Autant vous dire tout de suite que ce n'est pas la bonne manière de faire, d'où la phrase de PauseKawa
    C'est quoi "la bonne manière de faire"?
    Le PO a choisi la solution la plus adaptée à ses besoins et à son niveau pour réaliser un code fonctionnel. Réaliser rapidement des codes qui fonctionnent "est une bonne manière" pour se motiver à écrire des codes de plus en plus compliqués.

    Eviter de polluer "globals()", créer des "classes",... seront des méthodes qui s'imposeront alors plus naturellement.

    D'ici là quel intérêt sinon "scolaire"? Leur intérêt "pratique" est d'autant moins évident qu'on peut coder raisonnablement en les ignorant.

    - W

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 923
    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 923
    Points : 7 322
    Points
    7 322
    Par défaut
    Le PO a choisi la solution la plus adaptée à ses besoins et à son niveau pour réaliser un code fonctionnel.
    Non pas d'accord, car ma solution n'avait pas été proposée

    Réaliser rapidement des codes qui fonctionnent "est une bonne manière" pour se motiver à écrire des codes de plus en plus compliqués.
    Oui je suis d'accord, mais en quoi la solution que je propose est plus complexe?

    D'ici là quel intérêt sinon "scolaire"?
    N'étant pas enseignant en informatique, je ne peux affirmer qu'en milieu scolaire on demande ce genre de chose, et affirmer que l'enseignant apprendra une manière "propre" serait généraliser.

    Leur intérêt "pratique" est d'autant moins évident qu'on peut coder raisonnablement en les ignorant.
    Pas d'accord, dans le sens où il y a un intérêt hyper pratique, tant dans l'organisation du code que dans sa maintenance.

  9. #9
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    Toujours difficile de donner une réponse 'simple' sur le sujet sans tomber dans le 'piège' exec/eval que je voulais éviter et sans avoir des 'grincheux'. Perdu pour cette fois .
    La réponse globals() me semble la plus simple, au sens simple de la question, pour le PO et il a le temps de se frotter aux scopes et autre joyeusetés vu qu'il reste sur du code 'simple'.

    Ceci dit vu le code du PO tout cela ne vas pas servir à grand chose... Il n'as rien a faire de savoir que c'est "L5C5" mais souhaite juste repérer des Entry.
    Comme ceci par 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
    from tkinter import *
     
    Cases = 10*[10]
    for i in range(len(Cases)): Cases[i] = 10*[0]
     
    fenetre = Tk()
     
    for ligne in range(0, 10):
        for colonne in range(0, 10):
            Cases[ligne][colonne] = Entry(fenetre, width=10, justify="center")
            Cases[ligne][colonne].insert("end", "%s.%s" % (ligne, colonne))
            Cases[ligne][colonne].grid(row=ligne, column=colonne)
     
    L = 1
    C = 5
    print("Valeur pour la colonne 5 ligne 1 : %s" % Cases[L][C].get())
    print("Valeur pour la colonne 2 ligne 1 : %s" % Cases[1][2].get())
    fenetre.mainloop()
    Utiliser un hypothétique print(L5C5["width"]) sans savoir que "L5C5" existe ou pas n'est qu'une source à erreur.

    @+

  10. #10
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par PauseKawa Voir le message
    Ceci dit vu le code du PO tout cela ne vas pas servir à grand chose... Il n'as rien a faire de savoir que c'est "L5C5" mais souhaite juste repérer des Entry.
    Avec le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for ligne in range(1,11):
        for colonne in range(1,11):
            nom = "L" + str(ligne)+ "C" + str(colonne)
    Nous ne sommes plus dans une assignation telle que demander avec (en gros)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    noms = ["L1C1", "L1C2",...]
    for nom in noms:
        nom = Entry(fenetre,...)
    Ce n'est qu'un simple tableau ou nous pouvons identifier l'Entry par x/y. Si c'est un tableau autant en utiliser un.

    Citation Envoyé par PauseKawa Voir le message
    Utiliser un hypothétique print(L5C5["width"]) sans savoir que "L5C5" existe ou pas n'est qu'une source à erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> def Foo(): pass
    ... 
    >>> globals().keys()
    dict_keys(['__builtins__', '__name__', 'Foo', '__doc__', '__package__'])
    >>> 'Foo' in globals().keys()  # in globals()
    True
    >>> 'L5C5' in globals().keys()  # in globals()
    False
    >>> Foo()
    >>> globals()["Foo"]()
    >>> L5C5
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'L5C5' is not defined
    Maintenant si nous avons vraiment une liste de nom.
    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
    from tkinter import *
     
    noms = ["L1C1", "L1C2", "L2C1", "L2C2"]
     
    fenetre = Tk()
     
    for nom in noms:
        x = int(nom[1])
        y = int(nom[3])
        globals()[nom] = Entry(fenetre, width=10, justify="center")
        globals()[nom].grid(row=x, column=y)
     
    if "L1C2" in globals():
        print(L1C2["width"])
    if "L5C5" in globals():
        print(L5C5["width"])
    else:
        print("L5C5 n'existe pas")
     
    fenetre.mainloop()
    A noter qu'a ce niveau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if "L1C2" in locals():
        print(L1C2["width"])
    if "L5C5" in locals():
        print(L5C5["width"])
    else:
        print("N'existe pas")
    fonctionne aussi ce qui légitime l'utilisation de globals() avec du code aussi simple.

    Note:
    Pour le in globals() c'est pour poursuivre sur le sujet mais je précise que je préfère cela à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        print(L5C5["width"])
    except NameError:
        pass
    qui est encore plus 'douteux' dans ce genre d'utilisation : On dois 'suivre' ses variables à ce niveau de discussion.
    hasattr(obj, 'name') viendras plus tard.

    @+

  11. #11
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par PauseKawa Voir le message
    Maintenant si nous avons vraiment une liste de nom.
    J'allais oublier : if "L5C5" in noms (liste plutôt que in globals())

    @++

  12. #12
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par jabal64 Voir le message
    je place 10x10 widget Entry
    Bien qu'un tableau de 10x10 commence à l'index 0 (et fini donc à l'index 9), de même que row/column un petit supplément :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> v = "L10C11"
    >>> v.split("C")
    ['L10', '11']
    >>> y = v.split("C")[1]
    >>> x = v.split("C")[0][1:]
    >>> x
    '10'
    >>> y
    '11'
    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
    from tkinter import *
     
    # Vous remarquerez que tkinter travaille avec du texte (row=x, column=y)
    noms = ["L1C1", "L1C2", "L2C1", "L2C2"]
     
    fenetre = Tk()
     
    for nom in noms:
        x = nom.split("C")[0][1:]
        y = nom.split("C")[1]
        globals()[nom] = Entry(fenetre, width=10, justify="center")
        globals()[nom].insert(END, nom)
        globals()[nom].grid(row=x, column=y)
     
    if "L1C2" in noms:
        print(L1C2["width"])
     
    fenetre.mainloop()

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

Discussions similaires

  1. [XL-2010] Macro pour renommer des fichiers à partir d'une liste de nom de fichiers
    Par thomahh dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 25/01/2013, 17h03
  2. Placement image à partir d'une liste de noms
    Par roukgreg dans le forum Langage
    Réponses: 3
    Dernier message: 17/02/2010, 13h59
  3. Réponses: 3
    Dernier message: 19/05/2005, 17h52
  4. Réponses: 3
    Dernier message: 25/04/2005, 15h26
  5. Trouver equation à partir d'une liste de points
    Par scarabee dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 27/05/2004, 17h05

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