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 :

Boucle sur canvas.create_image


Sujet :

Tkinter Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut Boucle sur canvas.create_image
    Bonjour.

    Poursuivant mon appli "Lancer de dés", je tâche de faire une boucle d'affichage des dés dans un canvas.
    Le but est d'afficher n dés de valeur choisie au hasard, alignés en diagonale sur l'écran. Voici la fonction qui réalise cette tâche (je fais d'abord un test avec n=3 dés à lancer) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    def hasard(self):
            for i in range(3) :
                self.image=PhotoImage(file=self.faces[randrange(1,7,1)-1]) #choisit l'image du dé dans la liste des 6 faces)
                self.canvas.create_image(45*(i+1), 45*(i+1), image = self.image) #insère l'image dans le canvas
    L'ennui, c'est que je n'obtiens que le 3ème dé en bas à droite : il semblerait que l'image du dé n-1 disparaisse à l'apparition du dé n .

    Qu'en pensez-vous, svp ?
    Je joins l'intégralité de la classe pour que les bonnes âmes puissent joujouter avec...
    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
     
    #_*_ coding: iso-8859-1 _*_
     
    from Tkinter import*
    from random import randrange
     
    class ApplicationDes(Tk) :
        #constructeur
        def __init__(self,parent):
            Tk.__init__(self,parent)
            self.parent=parent
            self.faces=['1.gif', '2.gif', '3.gif', '4.gif', '5.gif', '6.gif']
            self.initialize()
     
        #fonction qui modifie le texte de bouton en fonction de la valeur du curseur
        def affiche(self,valeur):
            self.bouton.config(text ="Lancez "+str(valeur)+" dés !")
     
        #fonction affiche 1 dé au hasard
        def hasard(self):
            for i in range(3) :
                self.image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
                self.canvas.create_image(45*(i+1), 45*(i+1), image = self.image)
     
     
        #initialisation des widget
        def initialize(self) :
            self.grid()
            #le curseur pour le nombre de dés
            self.curseur=Scale(self, length=500, from_=1, to=20, orient=HORIZONTAL, label ='Nombre de dés à lancer',troughcolor ='dark grey',
                        sliderlength =20, tickinterval =1,command=self.affiche)
            self.curseur.grid(column=0,row=0,sticky='EW')
            #le bouton pour lancer les dés
            self.bouton=Button(self,text="Lancez les dés !",command=self.hasard)
            self.bouton.grid(column=0,row=1)
            #la fenêtre dans laquelle vont s'afficher les dés
            self.canvas=Canvas(self,width="200",height="200")
            self.canvas.grid(column=0,row=2)
            #auto redimensionnement de la fenêtre
            self.resizable(True,True)
     
     
    #création d'une application
    if __name__=="__main__":
        app = ApplicationDes(None)
        app.title("Les dés sont jetés !")
        app.mainloop()
    Merci d'avance !

    Gram'

  2. #2
    Membre expérimenté Avatar de Gaillac
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2008
    Messages : 165
    Par défaut
    et si tu rajoute : "anchor = Tk.NW" à ton create_image?

    En relisant ma phrase, je n'y crois déjà plus.
    Ton canevas fait plus de 145*145 donc supposer que toutes tes images se dessinent les unes sur les autres dans le coins inférieur droit, c'est pas très convaincant.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    Ben toujours rien

    Par contre, j'ai testé de mettre le choix de l'image avant la boucle, et ça marche : j'ai trois dés IDENTIQUES, donc, en diag :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    def hasard(self):
            self.image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
            for i in range(3) :
                self.canvas.create_image(45*(i+1), 45*(i+1), image = self.image)
    Ca n'a aucun intérêt, mais on se rapproche !
    Maintenant, ya plus qu'à faire le choix du dés à chaque tour de boucle... et là, je bloque !

    A+

    Gram'

  4. #4
    Membre expérimenté Avatar de Gaillac
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2008
    Messages : 165
    Par défaut
    Alors déjà vu que tu utilise "image" localement, pas besoin de faire "self.image", "image" sufffirait.

    Sinon, euh...
    je cherche ;-)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    Ah, moi, quand je vire self de self.image, il me met image undefined, ... donc je laisse

    Merci de te creuser : je me sens moins seul !

    A+

    Gram'

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    Ayest, j'ai trouvé !
    Comme la boucle ne foncitonne pas, faisons-la à la main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        def hasard(self):
                self.image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
                self.canvas.create_image(45, 45, image = self.image)
                self.image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
                self.canvas.create_image(90, 90, image = self.image)
    Ca ne fonctionne pas : toujours un seul dé...

    Petite idée (de génie ?) : peut-être qu'il n'aime pas que ce soit deux fois self.image, et qu'il faut changer le nom du contenant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        def hasard(self):
                self.image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
                self.canvas.create_image(45, 45, image = self.image)
                self.autre_image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
                self.canvas.create_image(90, 90, image = self.autre_image)
    Ca maaaaarche !

    Ya pu qu'à prendre ça en compte : mais là, je cale à essayer de modifier le nom de la variable self.image à chaque tour...

    Any idea ?

    Gram'

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    Trouvé (c'est mon côté Diesel...) :

    Je crée une liste qui va recevoir les 3 faces de dé choisies au hasard, et après je boucle sur l'affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        #fonction affiche 3 dés au hasard
        def hasard(self):
            self.liste=[]
            for i in xrange(3) :
                self.liste.append(PhotoImage(file=self.faces[randrange(1,7,1)-1]))
            for j in xrange(3) :
                self.canvas.create_image(45*(j+1),45*(j+1), image = self.liste[j])
    Enfin, je trouve ça plutôt lourdot, et âs très pythonesque...
    Quelqu'un(e) a trouvé quelque chose de plus sioux ?

    Gram'

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    C'est tout terminé ! J'ai intégré aussi le fait que le nombre de dés à tirer est celui indiqué par le curseur, et un peu de mise en page pour que les dés soient bien rangés :

    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
     
        #fonction affiche n dés au hasard, n étant le nombre indiqué par le curseur
        def hasard(self):
            self.liste=[]
            nombre=self.curseur.get()
            for i in xrange(nombre) :
                self.liste.append(PhotoImage(file=self.faces[randrange(1,7,1)-1]))
            for j in xrange(nombre ) :
                if j<5 :
                    self.canvas.create_image(45*(j+1)+20 ,45, image = self.liste[j])
                elif j<10 :
                    self.canvas.create_image(45*(j-5+1)+20 ,100, image = self.liste[j])
                elif j<15 :
                    self.canvas.create_image(45*(j-10+1)+20 ,155, image = self.liste[j])
                else :
                    self.canvas.create_image(45*(j-15+1)+20 ,210, image = self.liste[j])
    Et ça marche trop impec .

    En conclusion pour cette appli, merci à tous ceux qui m'ont répondu, et donc soutenu : j'ai appris plein de trucs, et je suis super fier de mon premier programme !

    Cela dit, j'ai un peu l'impression que le code pourrait être simplifié, parce qu'il ne m'a pas l'air très clean. Y aurait-il un ayatollah de la syntaxe pour critiquer mon appli ? Merci d'avance !

    A bientôt

    Gram'

  9. #9
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    la fonction hasard peut être un peu simplifier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        #fonction affiche n dés au hasard, n étant le nombre indiqué par le curseur
        def hasard(self):
            self.liste=[]
            for i in xrange(self.curseur.get()) :
                self.liste.append(PhotoImage(file=self.faces[randrange(1,7,1)-1]))
                self.canvas.create_image(45*(i-(i // 5) * 5 +1)+20 ,45 + 55 * (i // 5), image = self.liste[i])
    Il me semble aussi que le canvas doit avoir une taille plus grande pour qu'on puisse voir toutes les images:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.canvas=Canvas(self,width="300",height="200")

  10. #10
    Membre expérimenté Avatar de Gaillac
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2008
    Messages : 165
    Par défaut
    toooooooo

    sans le plantage du serveur ici, tu avais ta solution euh...
    en même temps que toi tu l'as trouvé :-)

    Sinon je t'ai dis une connerie, effectivement pour que ton image continue d'exister une fois que tu as fini de la dessiner il ne faut pas qu'elle soit locale à ta fonction de dessin.
    Mea-culpa.

    Et c'est d'ailleurs ce qui t'arrivait, tu te l'auto-écrasais.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    Ahhh, cool ! Ca ressemble plus à du Python.

    Cela dit, si je relis la boucle, il fait ceci :

    i=1 : choisit un dé, le met dans la liste, et place le 1er élément de la liste sur la case 1
    i=2 : choisit un dé, le met dans la liste, et place le 2ème élément de la liste sur la case 2
    ...
    i : choisit un dé, le met dans la liste après i-1, et place ce ième élément sur la case i.

    Ca me fait la bizarre impression que la liste est un artifice complet et ne sert à rien en temps que liste.

    J'aurais aimé pouvoir faire directement, dans create_image :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
    Mais ça ne fonctionne pas...

    En tous les cas, bravo et merci !

    Gram'

  12. #12
    Membre expérimenté Avatar de Gaillac
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2008
    Messages : 165
    Par défaut
    Citation Envoyé par graminou Voir le message
    J'aurais aimé pouvoir faire directement, dans create_image :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    image=PhotoImage(file=self.faces[randrange(1,7,1)-1])
    Mais ça ne fonctionne pas...
    Ca ne fonctionne pas parceque justement ton image est un objet local (tellement que tu ne le déclare même pas explicitement) à ton appel à create_image.
    Dès que le create_image est fini, ton objet disparait (et son affichage aussi).
    => Tu est iobligé de conserver les résultats de PhotoImage, et une liste c'est très bien.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 44
    Par défaut
    Merci : explication limpide !

    A bientôt
    Gram'

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

Discussions similaires

  1. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 12h45
  2. Macro sur Excel/Boucle sur les lettres
    Par life is magic dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 25/11/2005, 11h56
  3. [JDBC]Boucle sur tous les éléments du ResultSet
    Par Terminator dans le forum JDBC
    Réponses: 1
    Dernier message: 22/09/2005, 19h30
  4. L'installation d'XP boucle sur elle-même
    Par pf106 dans le forum Windows XP
    Réponses: 13
    Dernier message: 20/08/2005, 14h55
  5. [MFC] Boucle sur un bouton
    Par karl3i dans le forum MFC
    Réponses: 6
    Dernier message: 17/02/2004, 11h37

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