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 :

Synchronisation des paramètres de command de Button


Sujet :

Tkinter Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2022
    Messages : 28
    Points : 27
    Points
    27
    Par défaut Synchronisation des paramètres de command de Button
    Bonjour ou bonsoir,

    Le titre est sûrement très peu clair car je ne sais moi même pas pourquoi cela ne fonctionne pas comme je le voudrais.

    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
    from tkinter import *
     
     
    def afficher_lettre(lettre):
        for c in window.winfo_children():
            c.destroy()
     
        mylabel = Label(window, text=lettre)
        mylabel.pack()
     
        creer_clavier()
     
     
    def creer_clavier():
        for i in range(26):
            Button(window, text=alphabet[i], command=lambda: afficher_lettre(alphabet[i])).pack(side=LEFT)
     
     
    alphabet = "a b c d e f g h i j k l m n o p q r s t u v w x y z".split(" ")
     
    window = Tk()
    creer_clavier()
    window.mainloop()
    Je voudrais créer une sorte de clavier à l'aide de boutons tkinter grâce à une boucle. Ces boutons doivent renvoyer dans une autre fonction la lettre qui leur est associée afin qu'elle soit afficher dans un Label. Le problème est que peu importe les tests et les recherches je ne comprend pas à côté de quoi je passe (j'avoue que taper 26 fois la même chose alors qu'il existe surement une méthode plus propre et moins longue m'arrange pas beaucoup... ^^"""). Je soupçonne que tkinter synchronise les boutons puisqu'ils utilisent la même variable i mais pourtant leur texte n'est pas changé.

    Bref, merci par avance pour les explications que vous pourriez me fournir

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 966
    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 966
    Points : 7 389
    Points
    7 389
    Par défaut
    Bonjour,

    Pourquoi vouloir supprimer l'ensemble des widgets pour les reconstruire ? C'est illogique !

    L'alphabet n'a pas besoin d'être construit manuellement, il existe un module string avec l'ensemble des lettres de l'alphabet soit en minuscules ou en majuscules.

    Il faudra revoir le fonctionnement des lambdas, il y a un problème de référence dans la construction des boutons.

    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
    from tkinter import *
    from string import (
        ascii_lowercase as alphabet,
    )  # pas besoin de créer un alhphabet à la main
     
     
    def afficher_lettre(lettre):
        mylabel["text"] = lettre
     
     
    def creer_clavier():
        for i in range(26):
            lettre = alphabet[i]
            Button(
                window,
                text=lettre,
                command=lambda lettre=lettre: afficher_lettre(lettre),
            ).pack(side=LEFT)
     
     
    window = Tk()
    mylabel = Label(window, text="")
    mylabel.pack()
    creer_clavier()
    window.mainloop()
    EDIT:

    En relisant, je me demande si tu ne souhaites pas créer un clavier AZERTY ou QWERTY, dans ce cas il faudra effectivement une création manuelle.

    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
    from tkinter import *
     
    def afficher_lettre(lettre):
        mylabel["text"] = lettre
     
     
    def creer_clavier(configuration_clavier):
        for ligne in configuration_clavier:
            frame = Frame(window)
            for lettre in ligne:
                bouton = Button(
                    frame,
                    text=lettre,
                    command=lambda lettre=lettre: afficher_lettre(lettre),
                )
                bouton.pack(side=LEFT)
            frame.pack()
     
     
    window = Tk()
    mylabel = Label(window, text="")
    mylabel.pack()
     
    configuration_clavier = [
        ["a", "z", "e", "r", "t", "y", "u", "i", "o", "p"],
        ["q", "s", "d", "f", "g", "h", "j", "k", "l", "m"],
        ["w", "x", "c", "v", "b", "n"],
    ]
     
    creer_clavier(configuration_clavier)
     
    window.mainloop()

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

    Si je fabrique cette fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> def f():
    ...     print(i)
    ...
    l'instruction print(i) affichera la valeur de i lorsque la fonction est appelée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> i = 'aaa'
    >>> f()
    aaa
    Et si je modifie le i:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> i = 'bbb'
    >>> f()
    bbb
    >>>
    Si, à la place d'une fonction "normale", j'utilise lambda (une fonction anonyme), ce sera pareil:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> f = lambda : print(i)
    >>> f()
    bbb
    Et si on fabrique les mêmes fonctions dans une boucle, on affichera la dernière valeur assignée à i.
    La solution est de mémoriser la valeur de i lorsqu'on crée la fonction... l'astuce est de la stocker comme paramètre par défaut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> f = lambda i = i: print(i)
    >>> f()
    bbb
    >>> i = 'zzz'
    >>> f()
    bbb
    >>>
    Une autre façon de mémoriser le i est d'utiliser des fonctions spéciales appelées closure/fermeture:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> def f(i):
    ...     def inner():
    ...         print(i)
    ...     return inner
    ...
    >>> g = f(i)
    >>> g()
    zzz
    >>> i = 'aaa'
    >>> g()
    zzz
    >>>
    - W

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2022
    Messages : 28
    Points : 27
    Points
    27
    Par défaut
    Merci à vous deux pour vos réponses ! Je comprend mieux d'où venait mon problème
    Citation Envoyé par fred1599 Voir le message
    En relisant, je me demande si tu ne souhaites pas créer un clavier AZERTY ou QWERTY
    En effet comme vous l'avez deviner le code n'était qu'un exemple et le but était bien d'avoir un clavier AZERTY grâce à tkinter

    En revanche j'ai une question :
    Le programme tourne très bien et ne produit pas d'erreur pourtant le logiciel que j'utilise (pycharm) m'affiche un problème sur les deux variables lettre dans command= lambda lettre = lettre:La première affiche "shadows name from outer scope" et la deuxième affiche une erreur "unresolved reference lettre"
    Vous auriez une idée de la raison ? Peut-être que cela vient de pycharm ?

    Merci d'avance

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 514
    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 514
    Points : 37 131
    Points
    37 131
    Par défaut
    Citation Envoyé par Zarkoro Voir le message
    Vous auriez une idée de la raison ? Peut-être que cela vient de pycharm ?
    C'est un message de PyCharm qui analyse votre code et n'aime pas une construction où une variable d'un "outer scope" (définie avant) est utilisée comme variable locale (à la fonction).

    - W

  6. #6
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 966
    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 966
    Points : 7 389
    Points
    7 389
    Par défaut
    Peut-être que cela vient de pycharm ?
    Je n'utilise pas pycharm, la raison est sans doute donné par wiztricks, je modifierai donc le nom de variable lettre par lettre_bouton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def creer_clavier():    
        for i in range(26):
            lettre = alphabet[i]
            Button(
                window,
                text=lettre,
                command=lambda lettre_bouton=lettre: afficher_lettre(lettre_bouton).pack(side=LEFT)
            )

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2022
    Messages : 28
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    la raison est sans doute donné par wiztricks, je modifierai donc le nom de variable
    Vous aviez raison cela venait bien de là ! C'était plus visuel qu'autre chose mais c'était stressant d'avoir une erreur marquée dans le code pour rien... ^^""""

    Merci pour vos aides et explications !

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

Discussions similaires

  1. Question sur la synchronisation des threads.
    Par sebastieng dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 07/12/2005, 16h55
  2. J'aimerais créer des boutons de commandes dynamiquement??
    Par STRUFIELD dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 06/12/2005, 21h52
  3. synchroniser des actions
    Par Homer dans le forum Langage
    Réponses: 6
    Dernier message: 03/11/2005, 09h51
  4. [Synchronisation des processus] Problème du boulanger
    Par Giovanny Temgoua dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 26/02/2005, 13h40
  5. Réponses: 2
    Dernier message: 15/02/2005, 15h18

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