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 :

Problème d'affichage d'images [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 34
    Points : 15
    Points
    15
    Par défaut Problème d'affichage d'images
    Bonjour,

    Ca va faire depuis un petit moment que je suis bloqué à cause d'un bug que je n'arrive pas à résoudre. Le but est d'afficher des images.
    J'ai commencé par créer un prototype et ça me donne le code suivant qui marche très bien :
    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
     
    #bibliothèques
    import tkinter as tk
     
    #création de la fenêtre principale
    fen=tk.Tk()
     
    #création du canvas selon les paramètres
    can=tk.Canvas(fen,height=600,width=300)
     
    #images
    image1=tk.PhotoImage(master=fen,file='données\\textures\\chemin_droite1.ppm')
    image2=tk.PhotoImage(master=fen,file='données\\textures\\chemin_hautgauche1.ppm')
     
    #gestion du dictionnaire
    dico={}
    dico[1]=image1
    dico[2]=image2
     
    #matrice
    matrice=[[1,2],
             [2,1]]
     
    #taille de la matrice
    nbLig=len(matrice)
    nbCol=len(matrice[0])
     
    #affichage sous-image par sous-image
    for i in range(0,nbLig):
        for j in range(0,nbCol):
            can.create_image(i*48,j*48,image=dico[matrice[i][j]])
     
    can.update()
    can.grid()
     
    fen.mainloop()
    Je suis donc passé à l'étape suivante et j'ai voulu l'implémenter sur un code mais c'est là que ça coince. Aucune erreur ne se produit, mais l'image ne s'affiche plus.
    J'ai essayé de réduire le code au maximum pour simplifier et j'obtiens le programme suivant :
    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
    48
    49
    50
    51
    52
    53
    54
    55
     
    import tkinter as tk
     
    class FenetrePrincipale(tk.Tk):
        def __init__(self):
            super().__init__()
     
        def boucle(self):
            super().mainloop()
     
        def definition(self,titre):
            super().geometry("1400x700+67+40")
     
            self.update()
            self.caneva = CanvaFenetre(self, self.winfo_width(), self.winfo_height())
     
    class CanvaFenetre(tk.Canvas):
        def __init__(self,fenetre,width,height,parent=None,posX=0,posY=0):
            super().__init__(fenetre,bg="white",width=width,height=height)
            super().place(x=posX,y=posY)
     
            ############################# PARTIE QUI FONCTIONNE ##############################
            #images
            image1=tk.PhotoImage(master=fenetre,file='données\\textures\\chemin_droite1.ppm')
            image2=tk.PhotoImage(master=fenetre,file='données\\textures\\chemin_hautgauche1.ppm')
     
            #gestion du dictionnaire
            dico={}
            dico[1]=image1
            dico[2]=image2
     
            #matrice
            matrice=[[1,2],
                     [2,1]]
     
            #taille de la matrice
            nbLig=len(matrice)
            nbCol=len(matrice[0])
     
            #affichage sous-image par sous-image
            for i in range(0,nbLig):
                for j in range(0,nbCol):
                    self.create_image(i*48,j*48,image=dico[matrice[i][j]])
     
            self.update()
            self.grid() 
            ############################# PARTIE QUI FONCTIONNE ##############################
     
    class Application:
        def __init__(self):
            self.fenetrePrincipale = FenetrePrincipale()
            self.fenetrePrincipale.definition("work")
            self.fenetrePrincipale.boucle()
     
    Application()
    A vue de nez (probablement pas le meilleur nez qui soit cela dit), je dirais que le code est équivalent, du coup je comprend vraiment pas le problème dans la deuxième version...

    Merci d'avance pour la personne qui pourras m'aider

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

    En poussant la création des images et le dictionnaire qui garde une référence aux PhotoImage dans une fonction, les variables globales sont devenues locales.

    Elles sont détruites à la sortie de la fonction et les objets référencés (les images) sont détruits (et on ne les voit plus).

    - W

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 34
    Points : 15
    Points
    15
    Par défaut
    Ah mince , il est vrai que j'avais complètement oublié ce problème.

    Du coup, j'ai rajouté des selfs un peu partout et ça marche :
    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
    48
    49
    50
    51
    52
    53
    54
    55
     
    import tkinter as tk
     
    class FenetrePrincipale(tk.Tk):
        def __init__(self):
            super().__init__()
     
        def boucle(self):
            super().mainloop()
     
        def definition(self,titre):
            super().geometry("1400x700+67+40")
     
            self.update()
            self.caneva = CanvaFenetre(self, self.winfo_width(), self.winfo_height())
     
    class CanvaFenetre(tk.Canvas):
        def __init__(self,fenetre,width,height,parent=None,posX=0,posY=0):
            super().__init__(fenetre,bg="white",width=width,height=height)
            super().place(x=posX,y=posY)
     
            ############################# PARTIE QUI FONCTIONNE ##############################
            #images
            self.image1=tk.PhotoImage(master=fenetre,file='données\\textures\\chemin_droite1.ppm')
            self.image2=tk.PhotoImage(master=fenetre,file='données\\textures\\chemin_hautgauche1.ppm')
     
            #gestion du dictionnaire
            self.dico={}
            self.dico[1]=self.image1
            self.dico[2]=self.image2
     
            #matrice
            self.matrice=[[1,2],
                     [2,1]]
     
            #taille de la matrice
            nbLig=len(self.matrice)
            nbCol=len(self.matrice[0])
     
            #affichage sous-image par sous-image
            for i in range(0,nbLig):
                for j in range(0,nbCol):
                    self.create_image(i*48,j*48,image=self.dico[self.matrice[i][j]])
     
            self.update()
            self.grid() 
            ############################# PARTIE QUI FONCTIONNE ##############################
     
    class Application:
        def __init__(self):
            self.fenetrePrincipale = FenetrePrincipale()
            self.fenetrePrincipale.definition("work")
            self.fenetrePrincipale.boucle()
     
    Application()
    Merci beaucoup du coup de mains

  4. #4
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 895
    Points : 1 572
    Points
    1 572
    Billets dans le blog
    5
    Par défaut
    Bonjour,
    Inutile de mettre des selfs partout... Ce sont juste la référence de tes images que tu dois conserver.
    Sinon, pour l'usage de super() avec tes héritages de classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class FenetrePrincipale(tk.Tk):
        def __init__(self):
            super().__init__()
     
        def boucle(self):
            self.mainloop()
     
        def definition(self,titre):
            self.geometry("1400x700+67+40")
     
            self.update()
            self.caneva = CanvaFenetre(self, self.winfo_width(), self.winfo_height())

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 34
    Points : 15
    Points
    15
    Par défaut
    Oui, dans ce petit exemple, pas besoin de garder en mémoire le dico et la matrice.
    Sinon pour les self à la place de super(), même si a priori ça revient au même tu as je pense raison en disant qu'il vaut mieux utiliser self. C'est plus propre .
    Je crois même (à vérifier) que l'utilisation de super() est dépréciée... à la place de mon super().__init__(), il serait préférable de mettre tk.Tk.__init__() (ce qui là encore revient au même sauf dans le cas où on choisirait d'ajouter une deuxième classe mère)

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 333
    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 333
    Points : 36 853
    Points
    36 853
    Par défaut
    Citation Envoyé par thomas18F Voir le message
    Sinon pour les self à la place de super(), même si a priori ça revient au même tu as je pense raison en disant qu'il vaut mieux utiliser self. C'est plus propre .
    Ce n'est pas plus "propre": çà dépend juste de l'intention que vous avez en choisissant l'un plutôt que l'autre.
    Dans le cas de l' __init__, par exemple, vous n'avez pas trop le choix sauf à boucler dans un appel récursif.
    note: dans votre cas si c'est pour écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class FenetrePrincipale(tk.Tk):
        def __init__(self):
            super().__init__()
    la méthode __init__ ne sert à rien (du moins pour l'instant).

    Citation Envoyé par thomas18F Voir le message
    Je crois même (à vérifier) que l'utilisation de super() est dépréciée... à la place de mon super().__init__(), il serait préférable de mettre tk.Tk.__init__() (ce qui là encore revient au même sauf dans le cas où on choisirait d'ajouter une deuxième classe mère)
    Ce n'est pas déprécié et dans votre réponse vous remarquez vous même que ce n'est pas la même chose...

    Citation Envoyé par thomas18F Voir le message
    Oui, dans ce petit exemple, pas besoin de garder en mémoire le dico et la matrice.
    Et si on part du principe que vous allez avoir plusieurs widgets qui afficheront probablement les mêmes images, faire des images un dictionnaire "global" où on récupère les PhotoImages par leurs noms en les créant à partir d'un répertoire d'images si elles n'existent pas encore serait encore mieux.

    - W

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 34
    Points : 15
    Points
    15
    Par défaut
    Merci pour toutes ces précisions et oui je compte bien faire un dictionnaire pour stocker les photoImages.

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

Discussions similaires

  1. [XML/CSS/XSL] Problème d'affichage des images "dynamiqu
    Par popol55 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 06/04/2006, 16h24
  2. Problème d'affichage d'image...
    Par fabreizhad dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 21/03/2006, 12h43
  3. problème d'affichage d'image avec mozilla
    Par lyon31 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 16/03/2006, 16h27
  4. Problème d'affichage d'image
    Par AurelBUD dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 16/09/2005, 11h56
  5. CSS Probléme d'affichage d'images
    Par tebonb dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 01/06/2005, 18h35

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