Класс PhotoImage в Tkinter. Добавление изображений на виджеты

Иногда бывает необходимо, чтобы на кнопку, холст или другой элемент интерфейса была наложена уже имеющаяся картинка (которая хранится на диске).

В Python для работы с изображениями часто используют библиотеку Pillow. Однако, если ничего сложного не требуется, в самом Tkinter есть средства, позволяющие добавлять готовые картинки на виджеты. Одним из таковых является класс PhotoImage, который поддерживает графические форматы PNG, GIF, PGM, PPM.

При создании экземпляра в конструктор можно передать адрес/имя файла (это не единственный вариант использования PhotoImage):

img = PhotoImage(file='hello.png')

После этого объект img присваивается свойству image таких виджетов как кнопка, метка и др. Также его можно передать в метод create_image холста:

from tkinter import *

root = Tk()

img1 = PhotoImage(file='stefan.png')
img2 = PhotoImage(file='AlphaEdge.png')
img3 = PhotoImage(file='smile.gif')

b = Label(width=216, height=50, image=img3,
          borderwidth=2, relief=GROOVE)

c = Canvas(width=256, height=256, bg='white',)
c.create_image(1, 1, anchor=NW, image=img2)
c.create_image(128, 128, image=img1)

b.pack(padx=20, pady=20)
c.pack()
root.mainloop()

По умолчанию метод create_image принимает координаты точки холста, в которой будет размещен центр изображения. Однако с помощью параметра anchor можно изменить точку, для которой указывается координата. Так в примере выше для img2 указано, что координата (1, 1) применяется для верхнего левого угла (north-west).

Когда в конструктор метки передается image, то ее ширина и высота измеряются уже не в знакоместах, а в пикселях.

Если мы захотим разместить в метке текст с картинкой, просто добавить свойство text не получится. Картинка "победит", и надписи вы не увидите. Чтобы и то, и то отображались одновременно, надо использовать опцию compound, присвоив ей место, где должна появляться картинка: CENTER (изображение будет подложено под текст), TOP, BOTTOM, LEFT, RIGHT.

from tkinter import *

root = Tk()
img = PhotoImage(file='basn.png')

a = Label(image=img, text='Hello World',
          compound=TOP, bg='lightyellow')

b = Button(image=img, text='Hello World',
           compound=LEFT, height=50)

a.pack(padx=20, pady=20)
b.pack(padx=20, pady=20)
root.mainloop()

Если надо, чтобы виджет подстраивался под размеры изображения, не обязательно указывать для него параметры ширины и высоты. Они будут сконфигурированы соответственно размеру картинки.

from tkinter import *

root = Tk()

img2 = PhotoImage(file='basn.png')
Button(image=img2).pack()

img = PhotoImage(file='Spock.svg.png')
Label(image=img, bg='lightyellow',
      text='Hello Land and Ocean and Sky',
      compound=TOP).pack(ipadx=10)

root.mainloop()

Для холста подобное не работает. Без указания размера, последний будет иметь значения по-умолчанию (380x267 пикселей). Однако с помощью методов width и height экземпляра PhotoImage мы можем получить размер картинки и использовать эти значения при конфигурации холста.

from tkinter import *

root = Tk()

img = PhotoImage(file='Spock.svg.png')
w = img.width()
h = img.height()

c = Canvas(width=w+50, height=h+50, bg='gray')
c.create_image(w//2+25, h//2+5, image=img)
c.pack(padx=10, pady=10)

root.mainloop()

Здесь, создавая холст, к ширине и высоте изображения мы добавляем по 50 пикселей, картинка устанавливается по центру по горизонтали и ближе к верхнему краю по вертикали.

Если требуется изменить размер изображения, то следует обратить внимание на библиотеку Pillow, так как с объектом PhotoImage подобные операции выполнить затруднительно. Так с помощью метода zoom можно увеличивать только на кратную величину (целочисленную).

Практическая работа

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

Курс с примерами решений практических работ: pdf-версия


Tkinter. Программирование GUI на Python




Все разделы сайта