Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tk

Ouvrir un fichier photo et les faire défiler avec un bouton

Sujet résolu
    13 novembre 2019 à 19:06:25

    Bonjour à tous et à toutes,

    Voilà, je suis débutant sur Tkinter, et j'aimerais faire un petit programme pour faire défiler les photos à l'aide d'un bouton suivant et précédent d'un dossier images. Le ic c'est que je ne parviens pas à faire afficher les photos... Attention, comme je l'ai dit, je suis débutant, donc, mon code n'est sans doute pas propre.

    Voici mon code:

    <pre class="brush: python;">

    tkinter as tk
    
    from tkinter import *
    
    from os import *
    
    def suivant():
    
        global photo
    
        global i
    
       i=0
    
        while i<20:
    
           photo=PhotoImage(file='Users/chris/Desktop/Images')
    
            i+=1
    
            label.config(image=photo)
    
    def precedent():
    
        global photo
    
        global j
    
        j=0
    
       while j==20:
    
           photo=PhotoImage(file='Users/chris/Desktop/Images')
    
            j+=1
    
           label.config(image=photo)
    
    fenetre = tk.Tk()
    
    fenetre.title("Vos Images")
    
    photo= PhotoImage()
    
    canevas = Canvas(fenetre, width=500, height=500, bg="silver")
    
    canevas.create_image(0,0, anchor=NW, image=photo)
    
    canevas.pack()
    
    bouton1 = tk.Button(fenetre, text="->",background= "dark grey",command= suivant).pack(side=RIGHT, </>padx=5, pady=5)
    
    bouton2 = tk.Button(fenetre, text="<-", background="dark grey", command= precedent).pack(side=LEFT, </>padx=5, pady=5)
    
    bouton3 = tk.Button(fenetre, text= "Quitter", background="red", command= fenetre.destroy).pack(side=BOTTOM, padx=5, pady=5)
    
    fenetre.mainloop()



    -
    Edité par Ahrakiel 21 novembre 2019 à 13:38:33

    • Partager sur Facebook
    • Partager sur Twitter
      13 novembre 2019 à 21:45:24

      Bonjour, C'est le 32e sujet avec le titre "Tkinter", vous pourriez trouver un titre plus descriptif en fonction de votre problématique. 

      Le message qui suit est une réponse automatique activée par un membre de l'équipe. Les réponses automatiques leur permettent d'éviter d'avoir à répéter de nombreuses fois la même chose, ce qui leur fait gagner du temps et leur permet de s'occuper des sujets qui méritent plus d'attention.
      Nous sommes néanmoins ouverts et si vous avez une question ou une remarque, n'hésitez pas à contacter la personne en question par Message Privé.

      Pour plus d'informations, nous vous invitons à lire les règles générales du forum

      Merci de colorer votre code à l'aide du bouton Code

      Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: python;">Votre code ici</pre>.

      Liens conseillés

      -
      Edité par AbcAbc6 13 novembre 2019 à 21:46:01

      • Partager sur Facebook
      • Partager sur Twitter
        14 novembre 2019 à 14:05:25

        Tu reçoit sûrement une erreur car label n'existe pas il faut créer label avant de faire label.config(image=photo). Ensuite tu devrai utiliser un canvas plutot qu'un label pour afficher les photos. Je ne vais pas te donner la solution pour que tu progresse, mais tu devrai créer une liste avec une PhotoImage pour chaque photos dans ton dossier, puis dans tes fonction tu fait
        canvas.create_image(0, 0, image=photos[ici_numéro_de_la_photo])

        quelques remarques

        • en Python on n'utilise pas while avec une condition du genre i<0 puis une incrémentation de i dans la boucle, on utilise la boucle for
        • pour créer tes boutons (ou n'importe quel autre widget tkinter) on fait soit
          boutton = tk.Button(fenetre, text="->",background= "dark grey", command=lambda: suivant(canvas))
          button.pack(side=RIGHT, padx=5, pady=5)
          soit
          tk.Button(fenetre, text="->",background= "dark grey", command=lambda: suivant(canvas)).pack(side=RIGHT, padx=5, pady=5)
          mais pas
          bouton1 = tk.Button(fenetre, text="->",background= "dark grey", command=lambda: suivant(canvas)).pack(side=RIGHT, padx=5, pady=5)

                       car tu ne stock pas un objet Button mais un objet Button.pack() donc tu ne peut pas manipuler la variable button.

        -
        Edité par Blue_Badger 14 novembre 2019 à 14:19:33

        • Partager sur Facebook
        • Partager sur Twitter
          15 novembre 2019 à 20:56:55

          Bonsoir,

          Bon, j'ai du mal à définir mon suivant et précédent et du coup ça ne marche pas, je suis out of range... J'ouvre un dossier et que j'importe chaque photo dans une liste avec une boucle. Je vais faire mes recherches dans ce sens.

          Voici mon nouveau code:

          import tkinter as tk
          from tkinter import *
          import tkinter.messagebox
          import tkinter.filedialog
          
          
          def Ouvrir():
              filename = tkinter.filedialog.askopenfilename(title="Ouvrir une image",filetypes=[('gif files','.gif')])
              photo = PhotoImage(file=filename)
              
              canevas.create_image(0,0, anchor=NW, image=photo)
              canevas.config(height=photo.height(), width= photo.width())
              photolist.append(photo)
              print(photolist)
              fenetre.title("Image " +str(photo.width())+ " x " + str(photo.height()))
          
          def Fermer():
              canevas.delete(ALL)
              fenetre.title("Image")
          
          def suivant():
              photolist[?]          #Pas sur qu'il faille forcement faire une boucle ici et dans précédent.
                      
          def precedent():
              photolist[?]
                  
          fenetre = tk.Tk()
          fenetre.title("Vos Images")
          photolist=[]
          
          menubar = Menu(fenetre)
          menufichier = Menu(menubar, tearoff=0)
          menufichier.add_command(label="Ouvrir une image", command= Ouvrir)
          menufichier.add_command(label="Fermer l'image", command= Fermer)
          menufichier.add_command(label="Quitter", command=fenetre.destroy)
          menubar.add_cascade(label="Fichier", menu = menufichier)
          fenetre.config(menu=menubar)
          
          cadre=Frame(fenetre, bg="dark grey")
          bouton1 = tk.Button(cadre, text="-->",background= "dark grey",command= suivant)
          bouton2 = tk.Button(cadre, text="<--", background="dark grey", command= precedent)
          bouton3 = tk.Button(cadre, text= "Quitter", background="red", command= fenetre.destroy)
          
          bouton1.pack(side=RIGHT, padx=5, pady=5)
          bouton2.pack(side=LEFT, padx=5, pady=5)
          bouton3.pack(side=BOTTOM, padx=5, pady=5)
          
          canevas = Canvas(fenetre)
          canevas.pack()
          cadre.pack(fill=BOTH, expand=Y)
          
          fenetre.mainloop()
          

          -
          Edité par Ahrakiel 17 novembre 2019 à 15:51:51

          • Partager sur Facebook
          • Partager sur Twitter
            16 novembre 2019 à 15:30:50

            Je n'ai pas réussi a faire fonctionner ton menu, mais bon sur le principe je vois, par contre, il faut que tu soit sur de ce que tu veux faire, soit tu donne un dossier à ton programme, soit directement une image. Si tu lui donne directement une image, l'idée de la liste n'est plus très adaptée. Si c'est un dossier que tu veux parcourir, il faut que dans Ouvrir, tu tu demande la localisation du dossier, puis avec toutes les images qu'il contient tu fait une liste. Ensuite, tu peut la parcourir en utilisant une variable global compteur, et dans suivant tu fait compteur += 1 puis canvas.create_image(0, 0, image=photos[compteur]). (il serait plus propre de ne pas utiliser global, ça peut se faire avec un objet mais je ne veux pas t'embrouiller avec ça). Évidemment il faudra prévoir le cas ou tu arrive au bout de la liste avec try et exept.
            • Partager sur Facebook
            • Partager sur Twitter
              17 novembre 2019 à 15:45:35

              Bonjour,

              j'ai essayé avec un compteur mais je ne parviens toujours pas à faire suivant/précédent. J'ai trouvé une solution, pas forcement au top pour importer les images en une seule fois avec un for(je précise que j'ai m'y 4 car pour l'instant car je ne fais que tester), enfin, si je puis dire ça comme ça car ça les importes pas automatiquement dans ma liste, c'est moi qui choisi lesquelles importer, mais le menu s'affiche tout seul pour importer les images. On va dire que c'est du semi-automatique. J'ai supprimé le menu car effectivement, je n'étais pas partie dans le bon sens avec ça. Mon bouton quitter ne fonctionne plus, je ne sais pas pourquoi mais sur mon pc il ne détruit plus la fenêtre. Mais ça c'est un autre problème que je le réglerais plus tard pour l'instant ce qui me préoccupe le plus c'est mes def suivant/precedent que je ne parviens pas à faire fonctionner. Je n'ai pas encore gérer les exceptions comme pour l'instant, je n'arrive pas à afficher la photo précédente/suivante. Je pense qu'il me manque des connaissances, parce que dans l'idée ce n'est pas complexe comme programme... Peux tu juste me dire si je suis loin du compte ou si je m'approche de la vérité en testant mon code sur ton pc? Sans me donner la réponse, il faut que je trouve par moi-même. Peut-être le mieux serait de tout recommencer? Faire un code plus propre.

              Merci pour ton aide précieuse!

              import tkinter as tk
              from tkinter import *
              import tkinter.filedialog
              from tkinter.filedialog import askopenfilename
              
              def Fermer():
                  canevas.delete(ALL)
                  fenetre.title("Image")
              
              def suivant():
                  global compteur
                  compteur+=1
                  Canvas.create_image(0, 0, image=photo[compteur])
                  print("suivant")
                          
              def precedent():
                  global compteur
                  compteur-=1
                  Canvas.create_image(0, 0, image=photo[compteur])
                  print("precedent")
                     
              
              fenetre = tk.Tk()
              fenetre.title("Vos Images")
              
              compteur=0
              photolist=[]
              
              for i in range(4):
                      filename = askopenfilename(filetypes=[('gif files','.gif')])
                      photo = PhotoImage(file=filename)
                      photolist.append(photo)
                      print(photolist)
              
              menubar = Menu(fenetre)
              menufichier = Menu(menubar, tearoff=0)
              menufichier.add_command(label="Fermer l'image", command= Fermer)
              menufichier.add_command(label="Quitter", command=fenetre.destroy)
              menubar.add_cascade(label="Fichier", menu = menufichier)
              fenetre.config(menu=menubar)
              
              cadre=Frame(fenetre, bg="dark grey")
              bouton1 = tk.Button(cadre, text="-->",background= "silver",command= suivant)
              bouton2 = tk.Button(cadre, text="<--", background="silver", command= precedent)
              bouton3 = tk.Button(cadre, text= "Quitter", background="red", command= fenetre.destroy)
              
              canevas = Canvas(fenetre)
              canevas.pack()
              cadre.pack(fill=BOTH, expand=Y)
                      
              canevas.create_image(0,0, anchor=NW, image=photo)
              canevas.config(height=photo.height(), width= photo.width())
                  
              fenetre.title("Image " +str(photo.width())+ " x " + str(photo.height()))
              
              bouton1.pack(side=RIGHT, padx=5, pady=5)
              bouton2.pack(side=LEFT, padx=5, pady=5)
              bouton3.pack(side=BOTTOM, padx=5, pady=5)
              
              fenetre.mainloop()
              



              -
              Edité par Ahrakiel 17 novembre 2019 à 15:49:10

              • Partager sur Facebook
              • Partager sur Twitter
                17 novembre 2019 à 16:18:15

                Un truc important, tu ne doit pas importer deux fois tkinter une fois avec 'as tk' et une fois avec '*' il faut que tu choisisse l'un ou l'autre (perso je privilégie as tk).

                Bref il me semble que c'est mieux, après je ne suis pas un expert...

                Si ça ne marche pas c'est parce que:

                • tu remet compteur a 0 dans les deux fonction, il ne faut surtout pas faire ça car compteur doit garder l'info d'un appel de la fonction à l'autre.
                • tu ne cré pas de variable compteur, :lol: donc forcément ... il faut que juste après les import tu fasse 'compteur = 0'
                • une fois que tu a fait ça il faut que tu corrige les lignes 14 et 21 c'est photoliste[compteur] qui doit être là pas photo[compteur]

                Rien de grave, des erreurs d'inattention.

                je te donne le code, il n'est pas parfait, les images sont mal placées et la première image reste en permanence, je te laisse régler ça, mais sur le principe ça marche.

                Pour ton système de 'semi-automatique' c'est vrai que c'est pas le top, mais si c'est un projet perso c'est pas très grave.

                import tkinter as tk
                from tkinter.filedialog import askopenfilename
                
                compteur = 0
                
                
                def Fermer():
                    canevas.delete(tk.ALL)
                    fenetre.title("Image")
                
                
                def suivant():
                    global compteur
                    compteur += 1
                    canevas.create_image(0, 0, image=photolist[compteur])
                    print("suivant")
                
                
                def precedent():
                    global compteur
                    compteur -= 1
                    canevas.create_image(0, 0, image=photolist[compteur])
                    print("precedent")
                
                
                fenetre = tk.Tk()
                fenetre.title("Vos Images")
                
                photolist = []
                
                for i in range(4):
                    filename = askopenfilename(filetypes=[('png files', '.png')])
                    photo = tk.PhotoImage(file=filename)
                    photolist.append(photo)
                    print(photolist)
                
                menubar = tk.Menu(fenetre)
                menufichier = tk.Menu(menubar, tearoff=0)
                menufichier.add_command(label="Fermer l'image", command=Fermer)
                menufichier.add_command(label="Quitter", command=fenetre.destroy)
                menubar.add_cascade(label="Fichier", menu = menufichier)
                fenetre.config(menu=menubar)
                
                cadre = tk.Frame(fenetre, bg="dark grey")
                bouton1 = tk.Button(cadre, text="-->",background= "silver",command=suivant)
                bouton2 = tk.Button(cadre, text="<--", background="silver", command=precedent)
                bouton3 = tk.Button(cadre, text="Quitter", background="red", command=fenetre.destroy)
                
                canevas = tk.Canvas(fenetre)
                canevas.pack()
                cadre.pack(fill=tk.BOTH, expand=tk.Y)
                
                canevas.create_image(0, 0, anchor=tk.NW, image=photo)
                canevas.config(height=photo.height(), width=photo.width())
                
                fenetre.title("Image " + str(photo.width()) + " x " + str(photo.height()))
                
                bouton1.pack(side=tk.RIGHT, padx=5, pady=5)
                bouton2.pack(side=tk.LEFT, padx=5, pady=5)
                bouton3.pack(side=tk.BOTTOM, padx=5, pady=5)
                
                fenetre.mainloop()
                

                au passage j'ai fait quelques modification sur les espaces après les égale ou les virgules ce sont les normes utilisées pour avoir un code plus propre.

                • Partager sur Facebook
                • Partager sur Twitter
                  17 novembre 2019 à 17:09:10

                  Bonjour, merci beaucoup!

                  Si je l'avais bien initialisé ma variable compteur mais elle était mal placé...:/ (juste au-dessus de photolist). Je vais check voir pourquoi il ya des problèmes d'images mal placé, mais je pense savoir d'où cela vient. En espérant que je parle pas trop vite.:D Je vais également, corriger le semi-automatique pour le mettre en automatique. Je revient après pour te montrer mon code, voir si c'est correct. Pour les espaces après les égales, j'ai codé ça vite fait et du coup, il est vrai que je n'ai pas mis les espaces, mon but était avant tout que çà fonctionne pour le mettre au propre en suite, pour l'explication.:)

                  Merci en tout cas pour ton coup de main! Je fais le point sur mon code et je te montre çà ensuite! Encore, merci!

                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 novembre 2019 à 13:57:02

                    Bonjour,

                    J'essaie de faire en sorte que le dossier image s'ouvre est s'ajoute à ma liste seulement ça ne fonctionne pas, il me dit que les images n'existent pas... Je n'arrive pas à découvrir pourquoi... J'ai résolu le problème des images qui se mettent les une sur les autres, ainsi que les images mal placés. Par contre, je ne parviens pas à automatiser l'import d'images.

                    import tkinter as tk
                    import os
                    
                    compteur = 0
                    
                    def suivant():
                        global compteur
                        compteur += 1
                        if compteur > 4:
                            compteur = 0
                        canevas.delete('all')
                        canevas.create_image(0, 0, anchor = tk.NW, image=photolist[compteur])
                        print("suivant")
                    
                    def precedent():
                        global compteur
                        compteur -= 1
                        if compteur < 0:
                            compteur = 3
                        canevas.delete('all')
                        canevas.create_image(0, 0, anchor = tk.NW, image=photolist[compteur])
                        print("precedent")
                    
                    fenetre = tk.Tk()
                    fenetre.title("Vos Images")
                    
                    photolist = []
                    
                    for root, dirs, files in os.walk("/Users/chris/Desktop/Images"):
                        for i in files:
                            photolist.append(os.path.join(root, i))
                    
                    cadre = tk.Frame(fenetre, bg="dark grey")
                    bouton1 = tk.Button(cadre, text="-->", background= "silver", command=suivant)
                    bouton2 = tk.Button(cadre, text="<--", background="silver", command=precedent)
                    bouton3 = tk.Button(cadre, text="Quitter", background="red", command=fenetre.destroy)
                    
                    canevas = tk.Canvas(fenetre)
                    canevas.pack()
                    cadre.pack(fill=tk.BOTH, expand=tk.Y)
                    
                    canevas.create_image(0, 0, anchor=tk.NW, image=photolist)
                    canevas.pack(fill=tk.BOTH, expand=tk.TRUE)
                    
                    fenetre.title("Image ")
                    
                    bouton1.pack(side=tk.RIGHT, padx=5, pady=5)
                    bouton2.pack(side=tk.LEFT, padx=5, pady=5)
                    bouton3.pack(side=tk.BOTTOM, padx=5, pady=5)
                    
                    fenetre.mainloop()
                    



                    -
                    Edité par Ahrakiel 19 novembre 2019 à 14:03:12

                    • Partager sur Facebook
                    • Partager sur Twitter
                      23 novembre 2019 à 10:06:24

                      dsl pour la petite absence,

                      Alors, d'abord l.42 c'est pas photolist qu'il faut donner comme image, mais un élément de photoliste, ensuite il y aura une autre erreur car dans photolist il ne faut pas mettre des chemins, mais des PhotImage tkinter directement, donc il faut modifier la liste 31, je pense que tu sais comment:).

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Tk

                      × 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