How to display images from a directory as labels in Tkinter?

2.1k Views Asked by At

I'm new to Python GUI using Tkinter, and I'm stuck with the following:

I'm trying to read some image files in a particular directory using Python's os module, and show them as labels of Tkinter in a single window. The images have an average size of 1990 x 1200. So, I resized them using the Pillow library, and then packed every image to the window using a for loop.

But instead of showing the images, it's showing a blank window. I wrote the following code:

from PIL import Image, ImageTk
import tkinter as tk
import os

root = tk.Tk()
root.title("Photo Gallery")
root.geometry("655x350")

for (root_, dirs, files) in os.walk("Wallpaper"):
    if files:
        for file_ in files:
            path = os.path.join("Wallpaper", file_)
            image_ = Image.open(path)
            n_image = image_.resize((100, 100))
            photo = ImageTk.PhotoImage(n_image)
            img_label = tk.Label(root, image=photo)
            img_label.pack()


root.mainloop()

That's a screenshot of the blank window:

The image of the blank window.

Note: I use Python 3.6.3 and Pillow 8.2.0.

1

There are 1 best solutions below

2
On BEST ANSWER

EDIT: Incorporating the hint from the comment of acw1668 (thanks for that!), the fix can be even more easier:

for (root_, dirs, files) in os.walk("path/to/your/images"):
    if files:
        for file_ in files:
            path = os.path.join("path/to/your/images", file_)
            image_ = Image.open(path)
            n_image = image_.resize((100, 100))
            photo = ImageTk.PhotoImage(n_image)
            img_label = tk.Label(root, image=photo)
            img_label.photo = photo                             # <--
            img_label.pack()

I suppose it's an issue regarding the garbage collection of the images, cf. this Q&A. Simply keeping some references to the single photo variables did the trick for me:

references = []                                                 # <--
for (root_, dirs, files) in os.walk("path/to/your/images"):
    if files:
        for file_ in files:
            path = os.path.join("path/to/your/images", file_)
            image_ = Image.open(path)
            n_image = image_.resize((100, 100))
            photo = ImageTk.PhotoImage(n_image)
            img_label = tk.Label(root, image=photo)
            img_label.pack()
            references.append(photo)                            # <--

That's some output:

Output

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1
Pillow:        8.2.0
----------------------------------------