0

I want to create (runtime) multiple moveable label objects showing an image with Tkinter. The following code does work when the label is not showing an image, but only a background color for example. When I want to load images from a list of images, it only loads one label instead of all labels showing all the images. So no error occurs, neither does the wanted result.

images_files_list = self.get_images()

        self.dynamic_labels = []

        for image in images_files_list:
            self.img = ImageTk.PhotoImage(Image.open(images_path + image).resize((100, 100)))
            self.label = tk.Label(self, image=self.img, width=100, height=100)
            self.label.place(x=0, y=0)
            self.label.bind("<Button-1>", drag_start)
            self.label.bind("<B1-Motion>", drag_motion)
            self.dynamic_labels.append(self.label)

What am I doing wrong?

furas
  • 134,197
  • 12
  • 106
  • 148
Lawrence
  • 25
  • 5
  • 1
    Does this answer your question? https://stackoverflow.com/questions/16424091 – Bryan Oakley Dec 14 '21 at 22:37
  • 1
    you have to keep every `PhotoImage` in separated variable or keep all on `list` or assign to `label.img`. There is bug in `PhotoImage` which removes image when it is not assigned to global or class variable. When you assing new `PhotoImage` to the same `self.img` then bug removes previous image from memory. – furas Dec 14 '21 at 22:47
  • Thank you for your answers, however, I know about the garbage collection. THis code works for a single label object, but not for the loop creating multiple label objects showing each a different image from the list. – Lawrence Dec 15 '21 at 08:10
  • assigning to label.img does not do the trick, otherwise I end up having the troubles Bryan Oakley is referring to and then it does not show any image at all. – Lawrence Dec 15 '21 at 08:13
  • The aim is that each time a run of the loop is executed , the must be a different variable the image is assigned to. But how to do this, since the loop was already created to separete each image file in a list... – Lawrence Dec 15 '21 at 08:20
  • 1
    `self.label.img = self.img` does the trick and show all images. Without it, you can only see the last image. However you have put all the labels (with images) in same position (x=0, y=0), so how can you see all the images? Also instance variable is not necessary in a for loop. – acw1668 Dec 15 '21 at 09:22
  • I can see them, because they are moveable objects. I tried to assign self.label.img = self.img, but now it does not show any image.... – Lawrence Dec 15 '21 at 10:17
  • This is what I have now: ' for image in images_files_list: self.img = ImageTk.PhotoImage(Image.open(images_path + image).resize((100, 100))) self.label = tk.Label(self, bg="red", width=100, height=100) self.label.img = self.img self.label.bind("", drag_start) self.label.bind("", drag_motion) self.dynamic_labels.append(self.label) ' – Lawrence Dec 15 '21 at 10:28
  • Your code in comment does not set the `image` option in `tk.Label(...)`. Why do you remove it because it is there in the code in the question? – acw1668 Dec 16 '21 at 03:26
  • Because it was not necessary anymore, since I assign it to 'self.label.img' already. However, when I recover it, it does not work. As far as I know, I do exactly what everybodies advises, but I still cannot get it working... – Lawrence Dec 16 '21 at 20:37
  • if code `self.label.img = self.img ` doesn't work then you have to create list to keep all images on list. Before `for`-loop: `self.image = []`, and inside `for`-loop: `self.image.append( self.ing )` – furas Dec 17 '21 at 00:42
  • `self.label.image` does the trick after all. By accident I deleted the `self.label.place()`. Problem solved. – Lawrence Dec 18 '21 at 06:55

0 Answers0