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