Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Tkinter POO] Problème d'image

    28 août 2023 à 15:56:59

    Bonjour,

    J'ai un problème avec la méthode create_image lorsque je l'utilise dans ma classe

    from tkinter import *
    from PIL import Image,ImageTk
    
    class Module(Frame):
        def __init__(self, boss):
            Frame.__init__(self, boss)
            self.bouton=Button(self,text="Test", command=self.active)
            self.bouton.grid()
    
        def active(self):
            self.bouton.configure(command=self.passive)
            self.canvas=Canvas(self,bg="blue")
            self.canvas.grid()
            img=ImageTk.PhotoImage(file="image.png")
            self.canvas.create_image(20,20,anchor=NW,image=img)
    
        def passive(self):
            self.bouton.configure(command=self.active)
            self.canvas.destroy()
    
    fen=Tk()
    
    Module(fen).grid()
    
    can=Canvas(fen, bg="blue")
    can.grid()
    img=ImageTk.PhotoImage(file="image.png")
    can.create_image(20,20,anchor=NW,image=img)
    
    fen.mainloop()

    La classe Module est un Frame et contient un bouton qui lorsqu'on clique dessus, crée un Canvas contenant l'image.

    Problème : l'image ne s'affiche pas.

    Je n'ai aucun message d'erreur.

    J'ai essayé d'afficher l'image directement dans la fenêtre principale, et elle s'affiche bien.

    J'ai essayé d'autres méthodes comme create_rectangle, et pas de problème non plus.

    Du coup je ne comprend pas du tout où est l'erreur ...

    Je code sur EduPython, sous Windows 10.

    Merci d'avance



    • Partager sur Facebook
    • Partager sur Twitter
      28 août 2023 à 16:16:49

      Bonjour,

      J'ai testé ton code avec une image à moi:

      Et quand on appuie sur le bouton, ca donne ceci:

      J'ai mis 2 couleurs différentes pour distinguer ce qui est dans Module

      de ce qui est dans le prog. principal

      C'est bizarre ce truc là : Module(fen).grid()

      en général, on créé un objet à partir d'une classe:

      mon_module = Module(fen)

      Pour que ça marche, il faut supprimer la ligne 14 et laisser la ligne 27

      là où elle est

      -
      Edité par Phil_1857 28 août 2023 à 16:27:35

      • Partager sur Facebook
      • Partager sur Twitter
        28 août 2023 à 16:41:55

        kirq-geb a écrit:

        Du coup je ne comprend pas du tout où est l'erreur ...

        La variable img de la ligne 27 est globale alors que celle de la ligne 14 est locale à la méthode. Du coup, il n'y a plus de référence à l'image à la sortie de la fonction et l'image est détruite.

        Ligne 14 créez une référence qui survive via par exemple: "self.img = img =ImageTk.PhotoImage(file="image.png")"

        Phil_1857 a écrit:

        Pour que ça marche, il faut supprimer la ligne 14 et laisser la ligne 27

        là où elle est

        Utiliser des variables globales dans une classe?

        -
        Edité par mps 28 août 2023 à 16:45:43

        • Partager sur Facebook
        • Partager sur Twitter
          28 août 2023 à 16:55:24

          Merci beaucoup !

          Je me suis fait avoir par une simple variable locale...

          Je pensais que le Canvas gardais en mémoire les items qu'on dessinait dessus ; mais en fait non.

          Du coup, c'est réglé.

          @Phil_1857

          Je n'ai pas mis le Module(fen) dans une variable parce que je n'ai jamais besoin d'y faire référence. Tout est géré par la classe elle-même.

          En réalité, j'ai une quinzaine de Module dans ma fenêtre qui font des choses différentes et que j'active en fonction de mes besoins, mais il n'y a aucune interaction entre les modules, donc je n'ai pas voulu encombrer l'espace des noms de variables avec des noms qui me servent à rien.

          Merci encore à tous les deux !

          -
          Edité par kirq-geb 28 août 2023 à 16:57:40

          • Partager sur Facebook
          • Partager sur Twitter
            28 août 2023 à 17:17:03

            kirq-geb a écrit:

            Je n'ai pas mis le Module(fen) dans une variable parce que je n'ai jamais besoin d'y faire référence. Tout est géré par la classe elle-même.

            La (bonne) raison est que Module hérite de Frame et que tkinter garde (pour nous) une référence de tout widget crée (ils ne sont détruit qu'explicitement via destroy). Image et Variable ne sont pas des widgets et l'utilisateur doit gérer la référence explicitement.
            • Partager sur Facebook
            • Partager sur Twitter
              28 août 2023 à 17:46:29

              Merci pour cette précision.

              • Partager sur Facebook
              • Partager sur Twitter

              [Tkinter POO] Problème d'image

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown