Tkinter PhotoImage в Python — изображения в виджетах

В Tkinter некоторые виджеты могут отображать изображение, например Label и Button. Эти виджеты принимают аргумент image, который позволяет им отображать изображение.

Однако вы не можете просто передать путь к файлу изображения в аргумент image. Вместо этого вам нужно создать объект класса PhotoImage в Python и передать ему аргумент image.

Знакомство с Tkinter PhotoImage

Чтобы создать новый объект PhotoImage, используйте следующий синтаксис:

photo_image = tk.PhotoImage(file=path_to_image)

В этом синтаксисе вы передаете путь к изображению в аргумент файла для создания нового объекта PhotoImage. В качестве альтернативы вы передаете объект bytes, содержащий данные изображения, в аргумент data.

После создания объекта PhotoImage вы можете использовать его в других виджетах, которые принимают аргумент изображения:

label = ttk.Label(root, image=photo_image)

Важно отметить, что вы сохраняете ссылку на объект PhotoImage в области видимости до тех пор, пока будет показано изображение. В противном случае изображение не появится.

В следующем примере предпринимается попытка отобразить изображение с путем «./assets/python.png» в корневом окне:

import tkinter as tk
from tkinter import ttk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        python_image = tk.PhotoImage(file='./assets/python.png')
        ttk.Label(self, image=python_image).pack()


if __name__ == "__main__":
    app = App()
    app.mainloop()

Если вы запустите программу, вы заметите, что в окне не отображается изображение. Почему?

Это потому, что python_image уничтожается сразу после завершения __init__(). Поскольку программа не ссылается на объект PhotoImage, изображение исчезает, даже если вы упаковали его в макет.

Чтобы исправить эту проблему, вам нужно убедиться, что python_image не выходит из области действия после завершения метода __init__(). Вы можете сохранить его в экземпляре класса App, например self.python_image:

import tkinter as tk
from tkinter import ttk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Tkinter PhotoImage Demo')
        self.geometry('320x150')

        self.python_image = tk.PhotoImage(file='./assets/python.png')
        ttk.Label(self, image=self.python_image).pack()


if __name__ == "__main__":
    app = App()
    app.mainloop()

Форматы файлов Tkinter PhotoImage

В настоящее время PhotoImage поддерживает форматы файлов GIF, PGM, PPM и PNG, начиная с версии Tkinter 8.6.

Для поддержки других форматов файлов, таких как JPG, JPEG или BMP, вы можете использовать библиотеку изображений, например Pillow, чтобы преобразовать их в формат, понятный виджету PhotoImage.

На самом деле, библиотека Pillow имеет совместимый с Tkinter PhotoImage, расположенный в модуле PIL.ImageTk.

Следующая команда pip устанавливает библиотеку Pillow:

pip install Pillow

Чтобы использовать библиотеку Pillow, выполните следующие действия:

  • Сначала импортируйте классы Image и ImageTk:
from PIL import Image, ImageTk
  • Во-вторых, откройте файл изображения и создайте новый объект PhotoImage:
image = Image.open('./assets/python.jpg')
python_image = ImageTk.PhotoImage(image)
  • В-третьих, назначьте объект ImageTk.PhotoImage параметру image:
image_label = ttk.Label(root, image=python_image)

Следующая программа иллюстрирует, как использовать виджет PhotoImage из библиотеки Pillow:

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


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Tkinter PhotoImage Demo')

        self.image = Image.open('./assets/python.jpg')
        self.python_image = ImageTk.PhotoImage(self.image)

        ttk.Label(self, image=self.python_image).pack()


if __name__ == '__main__':
    app = App()
    app.mainloop()
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *