Partage
  • Partager sur Facebook
  • Partager sur Twitter

Listbox

    21 octobre 2017 à 3:15:34

    Bonjour,

    Je suis débutant dans le domaine. Je viens de développer ma première appli en Python sur Tkinter.

    Il me reste un dernier point à éclaircir. Je ne sais pas si c'est possible, je n'ai pas réussi à trouver l'information.

    J'utilise une listbox et j'aimerais en sélectionnant un de mes choix, faire apparaitre une image.

    Si je choisis un autre choix, une autre image apparait.

    Pouvez vous m'aider ?

    Merci

    • Partager sur Facebook
    • Partager sur Twitter
      22 octobre 2017 à 2:45:26

      Salut,

      Pour connaître l'élément sélectionner par la Listbox, vous devez utiliser la méthode .curselection(). Elle vous retournera un tuple contenant tous les éléments sélectionnés.

      Ensuite, pour pouvoir sélectionner un élément de la liste, vous devez créer un .bind() et prendre <<ListboxSelect>>, comme événement.

      Voici un exemple, très simple:

      Vous devez COMMENTER la ligne #8 from PIL import Image, ImageTk, si vous avez pas cette bibliothèque.

      import tkinter as tk
      
      ## Chargez une image, avec Tkinter
      def charger_image_tk(filename):
          return tk.PhotoImage(file=filename)
      
      ## Chargez une image avec PIL (Pillow)
      from PIL import Image, ImageTk
      def charger_image_pil(filename, resize=None):
          img = Image.open(filename)
          if resize:
              img = img.resize(resize, Image.ANTIALIAS)
          return ImageTk.PhotoImage(img)
      
      fenetre = tk.Tk()
      
      ### CHARGEMENT DES IMAGES: ###
      ## Nom des images. (et chemin d'accès, si nécessaire)
      images_name = ['balle.jpg', 'balleR.jpg', 'balleV.jpg']
      ## Pillow.
      #images = [load_image_pil(file) for file in images_name]
      ## Tkinter.
      images = [load_image_tk(file) for file in images_name]
      
      
      ## Création du label, qui affichera les images.
      label = tk.Label(fenetre)
      label.pack()
      
      ## Fonction du .bind(), pour la listbox
      def on_select(event):
          widget = event.widget ## le widget de l'événement.
          index = widget.curselection()[0] ## tuple élément 0
          label.config(image=images[index]) ## Modifie le label, selon l'index.
      
      
      ## Création du Listbox.
      listbox = tk.Listbox(fenetre)
      listbox.pack()
      listbox.bind('<<ListboxSelect>>', on_select)
      
      ## Ajouter les éléments, dans la listbox.
      for name in images_name:
          listbox.insert('end', name)
      
      
      fenetre.mainloop()

      J'ai ajouté pillow, au cas où tkinter vous empêches de charger les images (il est capricieux).

      Je vous invites à faire des print(), dans la fonction on_select(), pour comprendre le comportement de curselection().

      Puisque curselection() retourne un tuple, vous devez choisir l'élément 0. (J'ai jamais vue, plusieurs éléments, mais c'est possible)

      J'espère que vous prendrez le temps de comprendre cet exemple :)

      Si vous avez des question, n'hésitez pas.

      Bonne chance

      A+

      -
      Edité par nolimitech 22 octobre 2017 à 2:49:42

      • Partager sur Facebook
      • Partager sur Twitter
        22 octobre 2017 à 17:04:24

        Incroyable !! Merci énormément  !!! Je ne comptais même plus le nombre d'heures de recherche.

        Je souhaiterais avec le même élèment de ma listbox, faire apparaître 2 images différentes , chacunes dans un canvas différent.

        Pour se faire je vais créer :

        images = [load_image_tk(file) for file in images_name]

        et
        images2 = [load_image_tk(file) for file in images_name]
        Puis mettre à jour les canvas en fonction de ces derniers.
        J'ai créer 2 dossiers avec les mêmes photo.png et photo2.png, j'ai juste inversé les noms.
        L'idée est juste de cibler un dossier différent pour images = [load_image_tk(file) for file in images_name] et images2 = [load_image_tk(file) for file in images_name] mais je n'y arrive pas.
        Comment je peux faire ?
        Vous en parlez ici :
         ### CHARGEMENT DES IMAGES: ###
        ## Nom des images. (et chemin d'accès, si nécessaire)
        images_name = ['balle.jpg''balleR.jpg''balleV.jpg']
        ## Pillow.
        #images = [load_image_pil(file) for file in images_name]
        ## Tkinter.
        images = [load_image_tk(filefor file in images_name]
         @+

        -
        Edité par ThomasBerthaud 22 octobre 2017 à 17:06:02

        • Partager sur Facebook
        • Partager sur Twitter
          23 octobre 2017 à 9:51:50

          Salut

          En fait, vous avez pas besoin de charger 2x les images, même si vous utilisez ces images plusieurs fois.

          Vous pouvez chargez vos images qu'une seule fois. (En mettant, tous les noms d'images)

          tous_les_noms_images = [
              'allo.jpg', 'salut.jpg', 'coucou.jpg',
              'dossier/img1.jpg', 'dossier/img2.jpg',
          ]
          
          images = []
          for file in tous_les_noms_images:
              img = chargez_image_tk(file)
              images.append(img)

          Ensuite, puisque TOUTES vos images sont dans UNE SEULE liste (variable images), suffit de choisir l'index, pour choisir une image.

          (Vous pouvez mettre vos images dans un dictionnaire, si vous voulez garder les noms comme référence, à la place d'un index.)

          Vous pouvez donc, choisir deux fois la même images, pour deux situations différentes. (Pas besoin de chargez 2x les images)

          import tkitner as tk
          
          fenetre = tk.Tk()
          
          label = Label(fenetre, image=images[0])
          label.pack()
          
          
          label2 = Label(fenetre, image=images[0])
          label2.pack()
          
          
          fenetre.mainloop()

          Si vous voulez cibler des dossier contenants des images, suffit de parcourir ces dossiers: (Avec os.walk ou os.listdir)

          Il y a tellement de possibilités, j'espère seulement que vous comprenez la base de python.

          Admettons que le dossier contenant tous les images est (Le dossier Images, se trouve dans le répertoire du script.):

          • Images/Dossier1/image1.jpg
          • Images/Dossier2/imageA.jpg
          import os
          
          DOSSIER_IMAGES = 'Images'
          
          for root, dirs, files in os.walk(DOSSIER_IMAGES):
              for r in root:
                  print('ROOT:', r)
              for d in dirs:
                  print('DIR:', d)
          
              for file in files:
                  print('FILE:', file)
          
                  name, ext = os.path.basename(file).split('.')
                  print('NAME:', name, 'EXT:', ext)
          
                  fichier = os.path.join(root, file)
                  print('FICHIER:', fichier)
          
          Ensuite, suffit de sauvegarder ces fichiers, dans une liste ou un dictionnaire (si vous voulez garder les noms comme référence)
          ** Ne pas oublier: Si vous voulez un dictionnaire, il faudra que les noms de fichier soit tous différents. Puisque sinon, vous sauvegardez le dernier fichier ayant le même nom.
          Normalement, avec tout ces exemples, vous devriez y arriver tout seul.
          Essayez de mettre du code, histoire de reproduire vos erreurs. J'aimerais surtout voir ce que vous comprenez pas, à la place de faire des exemples, puisque vous recopier les exemples, sans les comprendres :D
          (Je dis cela, parce que, trouver des répertoires, des fichiers, est la base de python, avec le module os)

          N'hésitez pas pour les questions.

          Bonne chance

          A+

          -
          Edité par nolimitech 23 octobre 2017 à 9:59:07

          • Partager sur Facebook
          • Partager sur Twitter

          Listbox

          × 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