Création de boutons dans une boucle

Résolu/Fermé
fred13330 Messages postés 8 Date d'inscription mercredi 21 décembre 2022 Statut Membre Dernière intervention 13 janvier 2023 - 21 déc. 2022 à 10:40
fred13330 Messages postés 8 Date d'inscription mercredi 21 décembre 2022 Statut Membre Dernière intervention 13 janvier 2023 - 22 déc. 2022 à 09:53

Bonjour,

Lorsque je veux créer mes boutons depuis une boucle, le paramètre command ne fonctionne pas.

Merci de votre aide

Fred

# Import des librairies

import tkinter
import random

# Liste des possibilités de jeu
liste_objet = ["Pierre", "Ciseau", "Feuille"]
# Dictionnaire contenant les différents coups possibles ( PC/joueur)
dico_coup = {"PP": (0, 0), "PC": (1, 0), "PF": (0, 1),
             "CC": (0 ,0), "CF": (1, 0), "CP": (0, 1),
             "FF": (0, 0), "FP": (1, 0), "FC": (0, 1)
            }
game = True


def quitter():
    fenetre.quit()

# Création des boutons
def creation_bouton(i, texte, fonction):
    print(i, texte, fonction)
    bouton = tkinter.Button(fenetre, text=texte, command=fonction)
    bouton.place(x=i, y=300)


def pierre():
    print("pierre")


def ciseau():
    print("ciseau")


def feuille():
    print("Feuille")


# Création de la fenêtre de jeu
def fenetre_principale():
    global fenetre
    fenetre = tkinter.Tk()
    fenetre.geometry("450x400")
    fenetre.title("Shifumi")
    bouton_quitte = tkinter.Button(fenetre,text="Quitter", command=quitter)
    bouton_quitte.place(x=380, y=350)
    j = 0
    for i in [80, 180, 280]:
        creation_bouton(i, liste_objet[j], liste_objet[j].lower())
        j += 1


# On gère le tirage du PC
def tirage_pc():
    coup = random.randrange(3)
    coup_pc = liste_objet[coup]
    coup_pc_abrege = coup_pc[0]


# Boucle principale

fenetre_principale()
tirage_pc()

fenetre.mainloop()




Windows / Firefox 102.0

A voir également:

6 réponses

Phil_1857 Messages postés 1872 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 168
Modifié le 22 déc. 2022 à 09:43

Bonjour,

lorsque tu fais:

label_test = tkinter.Label

label_test est l'identifiant du label, et sa valeur est initialisée par tkinter

donc tu peux faire

label_test["text"] = n

lorsque tu fais

nom = tkinter.Label dans ta boucle, tu écrase la valeur de nom à chaque tour

et donc nom identifie le dernier label créé

ce qui fait que tout clic sur un bouton s'écrit ici:

Il faut donner un nom différent à chaque label, du genre lab[k] par exemple 

1
fred13330 Messages postés 8 Date d'inscription mercredi 21 décembre 2022 Statut Membre Dernière intervention 13 janvier 2023
21 déc. 2022 à 11:19

Je viens de trouver avec la modif suivante :

def creation_bouton(i, texte, fonction):
    bouton = tkinter.Button(fenetre, text=texte, command=eval(fonction))
    bouton.place(x=i, y=300)

Bonne journée à tous

0
Phil_1857 Messages postés 1872 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 168
Modifié le 21 déc. 2022 à 13:48

Bonjour,

Tu peux simplifier en faisant comme ceci (seule fonction coup() au lieu de 3 pierre() feuille() ciseau()):

En supprimant global qui n'est pas recommandé, et en remettant tout ça dans l'ordre:

import tkinter
import random

def quitter():
    fenetre.quit()

def creation_bouton(i, texte, fonction):
    bouton = tkinter.Button(fenetre, text=texte, command=lambda k=texte : coup(k))
    bouton.place(x=i, y=300)

def coup(n):
    print(n)

def tirage_pc():
    ''' Tirage ordi'''
    n = random.randrange(3)
    coup_pc = liste_objet[n]
    coup_pc_abrege = coup_pc[0]

liste_objet = ["Pierre", "Ciseau", "Feuille"]

dico_coup = {"PP": (0, 0), "PC": (1, 0), "PF": (0, 1),
             "CC": (0 ,0), "CF": (1, 0), "CP": (0, 1),
             "FF": (0, 0), "FP": (1, 0), "FC": (0, 1)
            }
game = True

#Programme principal
fenetre = tkinter.Tk()
fenetre.geometry("450x400")
fenetre.title("Shifumi")

bouton_quitte = tkinter.Button(fenetre,text="Quitter", command=quitter)
bouton_quitte.place(x=380, y=350)

j = 0
for i in [80, 180, 280]:
    creation_bouton(i, liste_objet[j], liste_objet[j].lower())
    j += 1

tirage_pc()

fenetre.mainloop()
0
fred13330 Messages postés 8 Date d'inscription mercredi 21 décembre 2022 Statut Membre Dernière intervention 13 janvier 2023
22 déc. 2022 à 08:35

Merci Phil

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fred13330 Messages postés 8 Date d'inscription mercredi 21 décembre 2022 Statut Membre Dernière intervention 13 janvier 2023
22 déc. 2022 à 09:03

Bonjour à tous,

Je reviens vers vous. J'ai tenté d'optimiser mon code. La fenêtre correspond à mes attentes (enfin pas encore esthétiquement :) ).

Par contre, dans la routine "coup",  si je veux modifier le contenu d'un label créé depuis le dictionnaire : impossible. Par contre cela est possible pour le label "test" qui a été créé manuellement.

Qu'ai-je loupé ?

Merci de votre aide

Fred

import tkinter
import random


def coup(n):
    label_test["text"] = n


def tirage_pc():
    """ Tirage ordi"""
    n = random.randrange(3)
    coup_pc = liste_objet[n]
    coup_pc_abrege = coup_pc[0]


liste_objet = ["Pierre", "Ciseau", "Feuille"]

dico_coup = {"PP": (0, 0), "PC": (1, 0), "PF": (0, 1),
             "CC": (0, 0), "CF": (1, 0), "CP": (0, 1),
             "FF": (0, 0), "FP": (1, 0), "FC": (0, 1)}

dico_bouton = {"bouton_pierre": ("Pierre", 110, 300, "pierre"),
               "bouton_ciseau": ("Ciseau", 210, 300, "ciseau"),
               "bouteau_feuille": ("Feuille", 310, 300, "feuille")}

dico_label = {"label_pc": ("Ordinateur", 100, 100, "light grey"),
              "label_joueur": ("Joueur", 300, 100, "light grey"),
              "label_pc_jeu": ("", 100, 120, "white"),
              "label_joueur_jeu": ("", 300, 120, "white"),
              "label-pc_score": ("", 100, 160, "white"),
              "label_joueur_score": ("", 300, 160, "white")}

game = True

# Programme principal
fenetre = tkinter.Tk()
fenetre.geometry("450x400")
fenetre.title("Shifumi")
fenetre.configure(bg="light grey")

# Création des boutons
bouton_quitte = tkinter.Button(fenetre, text="Quitter", command=fenetre.quit)
bouton_quitte.place(x=380, y=350)
for nom in dico_bouton:
    valeur = dico_bouton[nom]
    nom = tkinter.Button(fenetre, text=valeur[0], command=lambda k=valeur[3]: coup(k))
    nom.place(x=valeur[1], y=valeur[2])

# Création des labels
for nom in dico_label:
    valeur = dico_label[nom]
    nom = tkinter.Label(fenetre, text=valeur[0], width=10, bg=valeur[3])
    nom.place(x=valeur[1], y=valeur[2])
    
label_test = tkinter.Label(fenetre, text="test")
label_test.place(x=10, y=10)

fenetre.mainloop()
0
fred13330 Messages postés 8 Date d'inscription mercredi 21 décembre 2022 Statut Membre Dernière intervention 13 janvier 2023
22 déc. 2022 à 09:53

Bonjour,

Compris. En créant mes label manuellement cela fonctionne.

Donc ne pas cherche a optimiser au maximum ;)

0