Как отображать изображения из каталога в виде ярлыков в Tkinter?

Я новичок в графическом интерфейсе Python с использованием Tkinter, и я застрял со следующим:

Я пытаюсь прочитать некоторые файлы изображений в определенном каталоге с помощью Python osмодуль и отображать их как метки Tkinter в одном окне. Изображения имеют средний размер 1990 x 1200. Итак, я изменил их размер с помощью библиотеки Pillow, а затем упаковал каждое изображение в окно с помощью цикла for.

Но вместо изображений отображается пустое окно. Я написал следующий код:

      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()

Это скриншот пустого окна:

Примечание: я использую Python 3.6.3 и Pillow 8.2.0.

1 ответ

Решение

РЕДАКТИРОВАТЬ: Включив подсказку из комментария acw1668 (спасибо за это!), Исправление может быть еще проще:

      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()

Я полагаю, это проблема, связанная со сборкой мусора изображений, ср. этот Q&amp;amp;A . Просто сохраняя ссылки на сингл photo переменные помогли мне:

      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)                            # <--

Это какой-то вывод:

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

Другие вопросы по тегам