В этой части обучения Tkinter мы расскажем о базовых виджетах. В рамках урока мы будем работать с виджетами: Checkbutton, Label, Scale и Listbox.
Виджеты – это базовые блоки для создания графического интерфейса программы. За годы развития программирования некоторые из виджетов стали стандартными во всех языках и на всех платформах.
Например, это виджеты кнопок, флажки или полоса прокрутки. Некоторые из виджетов могут иметь другие названия в Tkinter. Например, классические флажки (check box) называются check button. В Tkinter реализован небольшой набор виджетов, который покрывает базовые нужды программирования. Дополнительные виджеты могут быть созданы как пользовательские виджеты.
Checkbutton
Checkbutton – это виджет, который имеет два состояния: «включен» и «выключен». Состояние «включен» визуально символизируется соответствующей отметкой (Некоторые темы могут иметь разные визуальные отметки). Виджет используется для обозначения каких-либо логических свойств. Виджет Checkbutton имеет флажок и текстовый ярлык.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#!/usr/bin/python # -*- coding: utf-8 -*- from Tkinter import Tk, Frame, Checkbutton from Tkinter import BooleanVar, BOTH class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Checkbutton") self.pack(fill=BOTH, expand=True) self.var = BooleanVar() cb = Checkbutton(self, text="Show title", variable=self.var, command=self.onClick) cb.select() cb.place(x=50, y=50) def onClick(self): if self.var.get() == True: self.master.title("Checkbutton") else: self.master.title("") def main(): root = Tk() root.geometry("250x150+300+300") app = Example(root) root.mainloop() if __name__ == '__main__': main() |
В нашем примере мы поместили флажок в окно. Использование этого флажка позволяет скрыть или отобразить название окна.
1 |
self.var = BooleanVar() |
Мы создали BooleanVar объект. Данные объекты позволяют хранить логические значения виджетов в Tkinter.
1 |
cb = Checkbutton(self, text="Show title", variable=self.var, command=self.onClick) |
Создается экземпляр Checkbutton. Объект, хранящий значение, соединяется с виджетом посредством параметра variable. Когда мы нажимаем на флажок, вызывается метод onClick(). Для этого также используется параметр command.
1 |
cb.select() |
Изначально, название отображается в заголовке окна. Поэтому, изначально мы делаем флажок включенным с помощью метода select().
1 2 3 4 |
if self.var.get() == True: self.master.title("Checkbutton") else: self.master.title("") |
Внутри метода onClick() мы отображаем или скрываем заголовок окна, основываясь на значении переменной self.var.
Ярлыки
Виджет Label используется для того, чтобы отображать текст или изображения. С этим виджетом пользователи никак не могут взаимодействовать.
1 |
sudo apt-get install python-imaging-tk |
Чтобы запустить этот пример, необходимо установить модуль python-imaging-tk.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#!/usr/bin/python # -*- coding: utf-8 -*- from PIL import Image, ImageTk from Tkinter import Tk, Frame, Label class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Label") self.img = Image.open("tatras.jpg") tatras = ImageTk.PhotoImage(self.img) label = Label(self, image=tatras) # reference must be stored label.image = tatras label.pack() self.pack() def setGeometry(self): w, h = self.img.size self.parent.geometry(("%dx%d+300+300") % (w, h)) def main(): root = Tk() ex = Example(root) ex.setGeometry() root.mainloop() if __name__ == '__main__': main() |
Наш пример показывает изображение в окне.
1 |
from PIL import Image, ImageTk |
По умолчанию, виджет Label может отображать ограниченное количество форматов изображений. Чтобы отобразить JPG изображение, необходимо использовать PIL (Python Imaging Library модуль).
1 2 |
self.img = Image.open("tatras.jpg") tatras = ImageTk.PhotoImage(self.img) |
Мы создаем изображение из файла изображения в текущей рабочей директории. После этого мы создаем фото изображение из изображения.
1 |
label = Label(self, image=tatras) |
Фотоизображению присваивается параметр image виджета ярлыка.
1 |
label.image = tatras |
Чтобы не смешать изображение с разным мусором, необходимо сохранить ссылку на него.
1 2 |
w, h = self.img.size self.parent.geometry(("%dx%d+300+300") % (w, h)) |
Мы устанавливаем размер окна таким образом, чтобы максимально точно подобрать его под размеры изображения.
Шкала
Scale – это виджет, который позволяет пользователю графически выбирать значение, перемещая определенный ползунок по ограниченной линии. В нашем примере выбранное значение ползунком будет отображено виджетом ярлыка в формате текста.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#!/usr/bin/python # -*- coding: utf-8 -*- from ttk import Frame, Label, Scale, Style from Tkinter import Tk, BOTH, IntVar, LEFT class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Scale") self.style = Style() self.style.theme_use("default") self.pack(fill=BOTH, expand=1) scale = Scale(self, from_=0, to=100, command=self.onScale) scale.pack(side=LEFT, padx=15) self.var = IntVar() self.label = Label(self, text=0, textvariable=self.var) self.label.pack(side=LEFT) def onScale(self, val): v = int(float(val)) self.var.set(v) def main(): root = Tk() ex = Example(root) root.geometry("250x100+300+300") root.mainloop() if __name__ == '__main__': main() |
В нашем скрипте присутствует два виджета: scale и label. Значение из виджета шкалы отображается в виджете ярлыка.
1 2 |
scale = Scale(self, from_=0, to=100, command=self.onScale) |
Мы создаем виджет Scale. Также мы указываем нижнюю и верхнюю рамки значений. From – это регулярное ключевое слово в Python, поэтому необходимо прописывать символ подчеркивание (Underscope) после параметра. Когда мы двигаем ползунок по шкале, вызывается метод onScale().
1 2 |
self.var = IntVar() self.label = Label(self, text=0, textvariable=self.var) |
Создаются держатель целого значения и виджет ярлык. Значение из держателя будет отображаться в виджете ярлыке.
1 2 3 |
def onScale(self, val): v = int(float(val)) self.var.set(v) |
Метод onScale() получает текущее выбранное значение из виджета шкалы как параметр. Значение сначала конвертируется в значение с плавающей точкой, после чего конвертируется в целое. В результате, значение передается держателю и отображается на виджете ярлыке.
Списки
Виджет Listbox позволяет отображать список объектов. Он позволяет пользователю выбирать один или несколько объектов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#!/usr/bin/python # -*- coding: utf-8 -*- from ttk import Frame, Label from Tkinter import Tk, BOTH, Listbox, StringVar, END class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Listbox") self.pack(fill=BOTH, expand=1) acts = ['Scarlett Johansson', 'Rachel Weiss', 'Natalie Portman', 'Jessica Alba'] lb = Listbox(self) for i in acts: lb.insert(END, i) lb.bind("<<ListboxSelect>>", self.onSelect) lb.pack(pady=15) self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) self.label.pack() def onSelect(self, val): sender = val.widget idx = sender.curselection() value = sender.get(idx) self.var.set(value) def main(): root = Tk() ex = Example(root) root.geometry("300x250+300+300") root.mainloop() if __name__ == '__main__': main() |
В нашем примере мы покажем список актрис, используя Listbox. Выбранная актриса на текущий момент отображается в виджете ярлыка.
1 2 |
acts = ['Scarlett Johansson', 'Rachel Weiss', 'Natalie Portman', 'Jessica Alba'] |
Это весь список актрис, которые будут показаны в списке.
1 2 3 |
lb = Listbox(self) for i in acts: lb.insert(END, i) |
Мы создаем экземпляр Listbox и включаем в него все объекты из указанного выше списка.
1 |
lb.bind("<<ListboxSelect>>", self.onSelect) |
Когда мы выбираем объект в списке, генерируется событие <>. Мы присваиваем метод onSelect() этому событию.
1 2 |
self.var = StringVar() self.label = Label(self, text=0, textvariable=self.var) |
Мы создаем ярлык и держатель его значения. С помощью этого ярлыка мы будем отображать выбранный на текущий момент объект.
1 |
sender = val.widget |
Мы получаем отправителя события – это наш виджет списка.
1 |
idx = sender.curselection() |
Мы узнаем индекс выбранного элемента при помощи метода curselection().
1 |
value = sender.get(idx) |
Фактическое значение извлекается при помощи метода get(), который получает индекс объекта.
1 |
self.var.set(value) |
В результате, ярлык обновляется.
В этой части обучения Tkinter мы рассказали о базовых виджетах.