Partage
  • Partager sur Facebook
  • Partager sur Twitter

je n'arrive pas à afficher une image

Sujet résolu
    5 août 2015 à 12:28:51

    Bonjour à tous,

    Je vous explique mon problème.

    J'ai acheté un livre de programmation sur Python ("apprendre la programmation par le jeu" de Vincent Maille").

    Je suis arrivé aux chapitre des images et je n'arrive pas à l'afficher.

    Sur mon bureau, j'ai une image GIF en 1024x1024 que je souhaite afficher.

    En fait lorsque j'éxecute le code python me renvoie 

    AttributeError: 'PhotoImage' object has no attribute '_create'

    Voici le code :

    from tkinter import *

    fichierimg = Tk()

    fichierimg = PhotoImage(file="image.gif")

    C = Canvas

    img = Canvas.create_image(fichierimg)

    Merci d'avance.

    • Partager sur Facebook
    • Partager sur Twitter
      5 août 2015 à 13:40:02

      Salut,

      Plusieurs erreurs dans ton code. La première c'est de nommer la fenêtre Tk et l'objet PhotoImage avec le même nom. Ensuite, l'objet Canvas à besoin de paramètres (où du moins de lui mettre au minimum des parenthèses) pour exister. Il faut aussi penser à le placer dans ta fenêtre avec l'une des méthodes de placement (pack, grid ou place) et enfin mettre les coordonnées du centre en argument de la méthode create_image:

      #Vaut mieux éviter de charger le module dans l'espace principal
      #Garder un alias permet de comprendre ce qu'on manipule
      import tkinter as tk
      
      #Création de la fenêtre et du canevas
      fen = tk.Tk()
      can = tk.Canvas(fen, width=500, height=500)
      
      #Chargement de l'image
      im = tk.PhotoImage(file="My_beautiful_image.gif")
      
      #Placement de l'image dans le canevas (les coordonnées correspondent au centre)
      can.create_image(250, 250, image=im)
      
      #Enfin placement du canevas
      can.pack()
      • Partager sur Facebook
      • Partager sur Twitter
      Précepte: Le mieux est l'ennemi du bien
        6 août 2015 à 15:16:38

        Olygrim a écrit:

        Salut,

        Plusieurs erreurs dans ton code. La première c'est de nommer la fenêtre Tk et l'objet PhotoImage avec le même nom. Ensuite, l'objet Canvas à besoin de paramètres (où du moins de lui mettre au minimum des parenthèses) pour exister. Il faut aussi penser à le placer dans ta fenêtre avec l'une des méthodes de placement (pack, grid ou place) et enfin mettre les coordonnées du centre en argument de la méthode create_image:

        #Vaut mieux éviter de charger le module dans l'espace principal
        #Garder un alias permet de comprendre ce qu'on manipule
        import tkinter as tk
        
        #Création de la fenêtre et du canevas
        fen = tk.Tk()
        can = tk.Canvas(fen, width=500, height=500)
        
        #Chargement de l'image
        im = tk.PhotoImage(file="My_beautiful_image.gif")
        
        #Placement de l'image dans le canevas (les coordonnées correspondent au centre)
        can.create_image(250, 250, image=im)
        
        #Enfin placement du canevas
        can.pack()


        Salut, tout d'abord merci pour ta réponse rapide,

        Ensuite, je n'ai pas bien compris la méthode pack, car pour apprendre Python j'ai acheté un livre à 20 euros et il n'y avait pas cette méthode de placement.

        Voici le nouveau code que j'ai construit à partir du votre :

        from tkinter import *
        image = Tk()
        img = Tk.PhotoImage(file="image.gif")
        C = Canvas()
        img = C.create_image("img")
        C.pack()

        Python me renvoie l'erreur "AttributeError: type object 'Tk' has no attribute 'PhotoImage' "

        Je n'ai pas tout compris.

        -
        Edité par GuekoGreen 6 août 2015 à 15:18:40

        • Partager sur Facebook
        • Partager sur Twitter
          6 août 2015 à 15:47:03

          Ok. Quand tu fais from tkinter import * tu importe tout ce que contient tkinter dans l'espace principal. Ce n'est pas une bonne pratique car souvent sources d'erreurs. Néanmoins, on utilise cette syntaxe pour de rare exception.

          Pour importer proprement un module, on utilise un espace des noms dédié qui correspond au nom que tu aura choisi pour l'importation. Par exemple:

          #L'importation la plus simple possible
          #on importe le module dans son nom
          import tkinter
          
          #Et pour utiliser les objets, il faut à chaque fois utiliser le nom
          canvas = tkinter.Canvas()
          
          
          #Sinon on peut utiliser un alias (plus court)
          #Ici le module tkinter est dans l'espace de nom tk
          import tkinter as tk
          
          #Et pour utiliser les objets:
          canvas = tk.Canvas()


          Tk, PhotoImage et Canvas sont des objets de tkinter. Donc si tu veux les utiliser il faudra utiliser le nom associé (parce qu'à partir de maintenant, tu importera proprement tes modules ;)). Donc ton code devient:

          import tkinter as tk
          fen = tk.Tk()
          can = tk.Canvas()
          can.pack()
          
          img = tk.PhotoImage(file="image.gif")
          img = can.create_image(x, y, image="img")


          Il faut aussi essayé d'avoir des noms de variables cohérent. Tk() n'est pas une image mais est un objet qui créé une fenêtre. Pour le Canvas, on évite d'utiliser une seule lettre comme nom de variable. can est plus parlant que C :). Et n'oublie pas, de rajouter en argument de la méthode create_image les coordonnées du centre où tu veux positionner ton image. Ici j'ai mis x et y, mais à toi de remplacé par les valeurs que tu souhaites.

          La méthode pack() est une méthode de placement. Si tu n'utilise pas cette méthode sur certains objets (comme les Canvas, les Label, Les Entry, ...) il ne seront pas s'afficher dans ta fenêtre.

          Pour débuter en pyhon, commencer avec tkinter c'est ..... courageux :lol:

          • Partager sur Facebook
          • Partager sur Twitter
          Précepte: Le mieux est l'ennemi du bien
            6 août 2015 à 18:15:53

            Pourquoi c'est courageux ?
            • Partager sur Facebook
            • Partager sur Twitter
              6 août 2015 à 18:18:37

              J'ai mis ce bout de code 
              import tkinter as tk
              fen = tk.Tk()
              can = tk.Canvas()
              can.pack()
              
              img = tk.PhotoImage(file="image.gif")
              img = can.create_image(x=1, y=1, image="img")
              Et python me renvoie "IndexError: tuple index out of range"
              • Partager sur Facebook
              • Partager sur Twitter
                6 août 2015 à 18:30:17

                C'est courageux car il faut quand même avoir un minimum de connaissances pour aborder sereinement tkinter ^^. Par exemple ici, il ne faut pas mettre x= et y=, mais juste la valeur de x et de y (et n'oublie pas que je t'ai dit que c'était les coordonnées du centre de ton image. Donc si tu met (1,1) une partie de ton image sera à l'extérieur de ton canevas.

                Et pour le paramètre image, c'est l'instance que tu dois donner en argument (l'instance c'est la variable) et non une chaîne de caractères (les chaînes de caractères sont caractérisée par " " ou ' ' ou """ """):

                import tkinter as tk
                fen = tk.Tk()
                can = tk.Canvas()
                can.pack()
                 
                img = tk.PhotoImage(file="image.gif")
                #Evite de donner le même nom à tes variables
                id_img = can.create_image(30, 30, image=img)



                -
                Edité par Olygrim 6 août 2015 à 18:30:52

                • Partager sur Facebook
                • Partager sur Twitter
                Précepte: Le mieux est l'ennemi du bien
                  6 août 2015 à 19:02:28

                  D'accord, je n'avais pas bien compris ce que tu voulais dire par centre de l'image.

                  Je viens d'essayer ton bout de code, Python ne me renvoie aucune erreur mais par contre l'image ne s'affiche pas alors qu'elle est sur mon bureau et que le programme aussi y est.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 août 2015 à 20:03:12

                    Est-ce que la fenêtre tkinter s'affiche? Essaie de dimensionner le canevas pour lui donner une taille fixe:

                    import tkinter as tk
                    fen = tk.Tk()
                    
                    #Le premier argument de Canvas est la fenêtre dans laquelle il va apparaître
                    #On peux attribuer une multitude d'options au canevas (taille, couleur, ...)
                    can = tk.Canvas(fen, width=400, height=600)
                    can.pack()
                      
                    img = tk.PhotoImage(file="image.gif")
                    
                    #On va mettre l'image au milieu du canevas. Donc le centre de l'image va
                    #correspondre au centre du canevas
                    id_img = can.create_image(200, 300, image=img)
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Précepte: Le mieux est l'ennemi du bien
                      6 août 2015 à 22:33:19

                      En fait, je ne sais pas ce que c'est que le Canvas, peux-tu me l'expliquer s'il te plait ?

                      En tout cas, avec ce code, aucune fenêtre ne s'affiche.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        6 août 2015 à 22:40:31

                        Le Canvas c'est juste un cadre. On pourrait le comparer à une toile pour une peinture. Dessus tu vas afficher des choses (des images, des formes, ...). C'est dans le Canvas qu'on fait également les animations. Par exemple tu dessines un rectangle et tu le fait bouger, ....

                        Pour ton code qui ne fonctionne pas, essaie de rajouter cette ligne à la fin:

                        import tkinter as tk
                        fen = tk.Tk()
                        
                        can = tk.Canvas(fen, width=400, height=600)
                        can.pack()
                        
                        img = tk.PhotoImage(file="image.gif")
                        id_img = can.create_image(200, 300, image=img)
                        
                        #la méthode mainloop permet de créer la boucle événementielle
                        fen.mainloop()


                        Et si ça ne fonctionne pas, je ne comprends pas. Peut-être n'es-tu pas dans le bon répertoire.

                        -
                        Edité par Olygrim 6 août 2015 à 23:04:43

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Précepte: Le mieux est l'ennemi du bien
                          8 août 2015 à 17:40:36

                          Merci pour ton aide précieuse, maintenant ça fonctionne !!!!!!!!!!!

                          Mais, au fait, c'est quoi une boucle évènementielle ?

                          Dans ton code je n'ai pas compris pourquoi à la ligne 8 tu as mis "id" avant la variable "img".

                          • Partager sur Facebook
                          • Partager sur Twitter
                            8 août 2015 à 19:02:51

                            Les interfaces graphiques sont gérées par des événements. Ça signifie que ce sont les événements qui vont déterminer la partie de code qui va s'exécuter. La boucle événementielle met l'interface en attente d'une action de l'utilisateur. Dans le code que tu as écrit il n'y a pratiquement pas d'interactions avec l'utilisateur (pour l'instant toi tu n'en as pas créées), mais il y en a quand même (fermer la fenêtre avec la croix, dimensionner la fenêtre, la bouger de place, ....).

                            "Dans ton code je n'ai pas compris pourquoi à la ligne 8 tu as mis "id" avant la variable "img"."

                            Comme je te l'ai dit, il faut toujours essayer de donner des noms de variables explicites (pour gagner en cohérence), mais ça permet également de savoir si on comprend ce qu'on manipule. Ici, tu utilises la méthode create_image() du Canvas. Or cette méthode (comme un grand nombre des méthodes de Canvas) ne renvoie pas un objet, mais simplement un entier (un identifiant).

                            Je pense que pour bien comprendre la programmation et pour avancer rapidement, il faut se poser la question: Quel objet ai-je en sortie lorsque j'applique une fonction/méthode/classe/calcul/.... Car chacune de ses actions renvoient FORCÉMENT quelque chose (un entier, une chaîne de caractère, une liste, un objet Canvas, None, ....). Et même lorsqu'on dit qu'une fonction ne renvoie rien, c'est faux. C'et un abus de langage. En fait elle renvoie None. Comprendre ce que tu as en sortie te permettra de bien construire ton code.

                            La seconde question à se poser, qui découle de la première et qui permet de distinguer les personnes qui comprennent ce qu'elles font des autres, c'est: OK, j'ai compris ce que j'ai en sortie de la fonction. Mais est-ce que j ai besoin de récupérer cette sortie? Autrement dit, est-ce que je vais devoir m'en servir ou pas de cette sortie? Prenons un exemple: Si tu regardes sur internet (forum, cours, ...) ou dans des bouquins, tu ne verra JAMAIS personne mettre la fonction print() dans une variable:

                            txt = print("Hello World!")

                            Pourtant comme je te l'ai dit, chaque action renvoie quelque chose, et la fonction print() ne fait pas exception: elle renvoie None. Mais ce qui nous intéresse qu'en on utilise print() ce n'est pas ce qu'elle renvoie mais son action (ici afficher du texte dans la console), et donc on s'en fout de ce qu'elle renvoie.

                            C'est la même chose dans le code que je t'ai montré. J'enregistre le Canvas dans une variable car par la suite je m'en sers (pour créer mon image en l'occurence). J'enregistre l'importation de mon image car je m'en sers également lors de la création de l'image. Par contre pourquoi enregistrer l'identifiant de l'image? Et bien en l'état ça sert effectivement à rien. Tu peux donc retirer le id_img = . Mais si tu souhaites agir sur ton image (pour permettre à l'utilisateur de la déplacer, ou pour faire une petite animation par exemple) alors là il faudra enregistrer la sortie (c'est-à-dire l'entier) dans une variable pour pouvoir la manipuler.

                            -
                            Edité par Olygrim 8 août 2015 à 19:07:46

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Précepte: Le mieux est l'ennemi du bien
                              8 août 2015 à 21:26:33

                              Ok j'ai compris, donc en fait c'était juste pour donner un nom explicite à la variable ?

                              Et dis moi tu as quel niveau de Python ? Qu'est-ce que tu sais faire comme application ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                                8 août 2015 à 22:26:16

                                Oui c'était juste pour donner un nom explicite :lol:.

                                Pour l'instant je suis encore débutant, car avoir un bon niveau en python ce n'est pas juste savoir écrire du code mais c'est également savoir chercher l'information et notamment en passant du temps dans la documentation. Or pour l'instant je n'ai pas trop touché à celle-ci et donc il me manque toutes les petites subtilités qui font la richesse de ce langage ;)

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Précepte: Le mieux est l'ennemi du bien
                                  8 août 2015 à 23:40:22

                                  Comment ça chercher l'information ?

                                  Le plus étonnant dans tout ça c'est que tu es débutant et tu m'apprend à afficher une image alors que moi mon livre sur Python je l'ai fini et normalement je devrais être capable à l'heure actuelle de faire bouger des images et même mettre une musique de fond !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    9 août 2015 à 2:10:06

                                    Il y a une différence entre lire un livre et s'approprier les connaissances qui y figurent :lol:. Prenons l'exemple du tutoriel sur le site d'OpenClassroom (OC). C'est un tuto très large qui traite de nombreux sujets (les objets de bases, l'interface graphique, la programmation orienté objet, le réseau, ...). Selon OC, il faut 1mois (40h) pour faire ce tutoriel. Tu comprends bien que c'est ABSOLUMENT IMPOSSIBLE si tu veux réellement maîtriser ce que tu fais (surtout en considérant que ce cours est à l'intention des débutants).

                                    Ceci est aussi vrai pour le livre que tu as acheté. Il ne suffit pas de recopier les exemples, il faut d'une part essayer de les faire soit même (en comprenant ce que tu veux faire et ce dont tu auras besoin pour y parvenir) et une fois que ton code est créé, le comparé avec celui de l'auteur et essayer de comprendre pourquoi il a fait des choses différentes (en gardant toujours à l'esprit que la solution de l'auteur n'est pas forcément la meilleure ;)).

                                    Le code que je t'ai donné est très basique. Mais ça n'empêche que je sais EXACTEMENT ce que j'ai fait et pourquoi je l'ai fait (ça ne veut pas dire pour autant qu'il est parfait, juste que j'ai compris ce que je faisais). Si tu ne penses pas t'être approprié les connaissances de ton livre (je parle d'avoir réellement compris et de pouvoir refaire sans le livre des exercices similaires) alors refait-le et essaie de comprendre le pourquoi de chaque ligne. Et n'hésite pas non plus à multiplier les sources pour améliorer tes connaissances et avoir un esprit critique sur les codes que tu regardes. Lis par exemple les tutos d'OC (c'est gratuit ^^) et procure toi le livre de Swinnen (livre de référence pour débuter en python). Je pense que tu peux le trouver gratuitement en PDF sur le net (par contre je ne sais pas si c'est légal). Et puis n'hésite pas à participer au forum :)

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Précepte: Le mieux est l'ennemi du bien
                                      9 août 2015 à 17:06:32

                                      Est-ce qu'il est possible de rendre ses programmes Python compatibles avec des appareils Android ?

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      je n'arrive pas à afficher une image

                                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                      • Editeur
                                      • Markdown