Вы уже умеете пользоваться виджетами Tkinter для того, чтобы создавать такой графический интерфейс, который будет подходить под конкретные задачи. Тем не менее, у них есть недостаток – слишком специфичный внешний вид. Из-за этого некоторые кнопки и элементы выглядят несколько устаревшими. Они хорошо подходят для новичков, но иногда их использование – не очень хорошая идея.
Конечно, они вполне достойны. Опытные разработчики также используют стандартную библиотеку. Тем не менее, давайте сегодня рассмотрим еще одну библиотеку, которая может использоваться одновременно со стандартной – Ttk. Помимо более современного интерфейса, в ней содержатся дополнительные элементы.
Что такое «тематические виджеты»?
Тематические виджеты Tk – это отдельная категория элементов интерфейса, которая очень похожа на нативные. Тем не менее, их можно кастомизировать с использованием специализированных API.
Эти классы обозначены в модуле tkinter.ttk, который и нужно подключать, чтобы ими воспользоваться. Кроме новых виджетов, таких как Treeview и Notebook, этот модуль предусматривает альтернативные кнопки, рамки и надписи.
Сегодня рассмотрим особенности применения этих классов Tkinter более подробно. Также разберемся, как их правильно выполнять стилизацию и какие основные особенности применения этих виджетов.
Набор тематических виджетов Tk входит в комплектацию библиотеки Tk 8.5. Тем не менее, это не должно вызвать каких-бы то ни было сложностей, так как этот интерпретатор содержится в Python 3.6. Если же у вас установлена на компьютере более старая версия языка, то необходимо будет обновиться на новую.
Настоятельно рекомендуется проверять обновления языка перед тем, как начинать программировать.
Как же проверить, какая версия установлена на компьютере? Очень просто. Это делается путем набора в командной строке python -mtkinter. После этого появится программа, содержащая метку, в которой указана текущая установленная версия Tk.
Как заменять классы базовых виджетов
Итак, давайте более подробно разберемся, как применять уже знакомые виджеты, но которые реализуются в другом модуле. Нам же надо не только понять, как их вызывать, но и научиться ими пользоваться, верно?
Конечно, это не обеспечит те же возможности настройки стилей, но эти виджеты ощущаются несколько по-другому. Вы поймете, о чем идет речь, когда посмотрите на этот скриншот.
Давайте создадим программу, которая будет хорошо показывать, как осуществляется переключение между различными стилями.
Необходимо отметить, что все зависит от платформы. В данном случае тематический виджет выглядит так же, как стандартные виджеты Windows 10.
Сначала нам необходимо импортировать соответствующий модуль, а потом использовать виджеты, находящиеся в этом комплекте, уже в программе. Делается это так же, как и со стандартными элементами Tkinter.
import tkinter as tk import tkinter as ttk class App(tk.Tk): greetings = ("Привет", "Ciao", "Hola") def __init__(self): super().__init__() self.title("Тематические виджеты Tk") var = tk.StringVar() var.set(self.greetings[0]) label_frame = ttk.LabelFrame(self, text="Выберите приветствие") for greeting in self.greetings: radio = ttk.Radiobutton(label_frame, text=greeting, variable=var, value=greeting) radio.pack() frame = ttk.Frame(self) label = ttk.Label(frame, text="Введите ваше имя") entry = ttk.Entry(frame) command = lambda: print("{}, {}!".format(var.get(), entry.get())) button = ttk.Button(frame, text="Приветствовать", command=command) label.grid(row=0, column=0, padx=5, pady=5) entry.grid(row=0, column=1, padx=5, pady=5) button.grid(row=1, column=0, columnspan=2, pady=5) label_frame.pack(side=tk.LEFT, padx=10, pady=10) frame.pack(side=tk.LEFT, padx=10, pady=10) if __name__ == "__main__": app = App() app.mainloop()
Если же понадобится воспользоваться стандартными виджетами, то заменить тематические на классические очень просто. Достаточно заменить ttk в коде на tk. Такая простота позволит попробовать разные варианты, и выбрать тот, который подходит больше всего.
Принципы замены виджетов
Итак, мы начинаем с импорта модуля Python tkinter.ttk. Для этого используется уже привычный синтаксис import … as, который использовался для импортирования модулей с другим функционалом. Как же нам быстро отличать тематические и классические виджеты. Все просто. Первые будут иметь имя ttk. Посмотрите на эти две строки и сравните.
import tkinter as tk
import tkinter as ttk
Разница видна невооруженным глазом, не так ли?
В нашем примере используются виджеты ttk.Frame, ttk.Label, ttk.Entry, ttk.LabelFrame и ttk.Radiobutton. Их параметры почти такие же самые, что и у привычных нам виджетов Tkinter. Тем не менее, есть несколько существенных отличий. Например, цвет фона и букв задается с помощью класса ttk.Style. Впрочем, это может быть неудобным в определенных моментах.
Как сделать выпадающий список
Давайте попробуем создать такое приложение.
Эта программа создает объект класса ttk.Combobox во время инициализации. Разработчики задают последовательность значений заблаговременно, и она затем передается в список. Далее пользователь уже может выбирать из имеющихся вариантов.
import tkinter as tk import tkinter.ttk as ttk class App(tk.Tk): def __init__(self): super().__init__() self.title("Ttk Combobox") colors = ("Purple", "Yellow", "Red", "Blue") self.label = ttk.Label(self, text="Пожалуйста, выберите цвет") self.combo = ttk.Combobox(self, values=colors) btn_submit = ttk.Button(self, text="Разместить", command=self.display_color) btn_clear = ttk.Button(self, text="Очистить", command=self.clear_color) self.combo.bind("<>", self.display_color) self.label.pack(pady=10) self.combo.pack(side=tk.LEFT, padx=10, pady=5) btn_submit.pack(side=tk.TOP, padx=10, pady=5) btn_clear.pack(padx=10, pady=5) def display_color(self, *args): color = self.combo.get() print("Ваш выбор", color) def clear_color(self): self.combo.set("") if __name__ == "__main__": app = App() app.mainloop()
Принцип работы виджета Combobox
Точно так же, как и во всех остальных случаях, виджет ttk.Combobox добавляется путем передачи экземпляра Tk в качестве первого параметра в конструктор. С помощью параметра values интерпретатор понимать, какие варианты предлагать в списке после того, как пользователь нажмет по нему.
Кроме этого, виртуальное событие <<ComboboxSelected>> связывается после того, как пользователь выбирает одно из значений перечня.
self.label = ttk.Label(self, text="Пожалуйста, выберите цвет") self.combo = ttk.Combobox(self, values=colors) btn_submit = ttk.Button(self, text="Разместить", command=self.display_color) btn_clear = ttk.Button(self, text="Очистить", command=self.clear_color) self.combo.bind("<<ComboboxSelected>>", self.display_color)
Если пользователь нажимает по кнопке «Submit», вызывается такой же самый метод. Поэтому она получает то значение, которое было введено пользователем.
С помощью функции display_color() мы получили список аргументов. Это дает возможность повысить безопасность обработки дополнительных аргументов. Так происходит, потому что передача события осуществляется через связывание.
Правда, эта функция не работает с кнопками.
С помощью этой функции мы получаем текущее значение, которое находится в поле ввода списка. Для этого используется метод get().
def display_color(self, *args):
color = self.combo.get()
print(«Ваш выбор», color)
В конце используется функция clear_color(), с помощью которой осуществляется очистка содержимого Combobox. Для этого используется метод set, в качестве аргумента которого используется пустая строка.
def clear_color(self):
self.combo.set(«»)
С помощью класса ttk.Combobox происходит расширение ttk.Entry, который также осуществляет расширение класса Entry, который содержится в модуле tkinter.
Проще говоря, можно пользоваться теми же самыми методами, что и в классе Entry, если они будут нужны.
combobox.insert(0, «Добавьте это в начало: «)
Согласитесь, что этот код значительно более понятный по сравнению с использованием выражения combobox.set(«Добавьте это в начало: » + combobox.get()).
В чем разница между классическими и тематическими виджетами?
В целом, оба типа виджетов являются взаимозаменяемыми. Программист может самостоятельно выбирать, каким из них пользоваться. Тем не менее, разница между ними есть.
Настройка классических виджетов Tkinter осуществляется непосредственно через параметры. Разработчик свободно настраивает ширину границ, шрифты, изображения, и так далее. В случае с виджетами ttk, используются стили. Это значительно расширяет возможности в случаях, если, например, нужно реализовать нестандартную кнопку.
Какой же тип выбрать? Все зависит от конечной цели. Если требуется, чтобы приложение выглядело более «родным» и современным, необходимо использовать тематические виджеты. Если же требуется программа, которая будет более конфигурируемая, то тогда больше подойдут классические виджеты.
Если вы – новичок, то лучше использовать классическую библиотеку Tkinter, поскольку она предусматривает более простую кастомизацию по сравнению с Ttk.
Таким образом, мы рассмотрели альтернативную библиотеку, реализующую элементы окна в разных операционных системах. К сожалению, не получится в одной небольшой статье рассмотреть все нюансы использования этой библиотеки. Тем не менее, мы дали азы, с которых можно начинать.