Библиотека tkinter в Python

Самая простая библиотека для создания интерфейсов на Python

Библиотека tkinter в Python

Для Python написано много расширений, которые делают этот язык полезным и применимым почти в любой сфере: с ним можно строить графики, создавать музыку, работать с 3D-анимацией и даже создавать игры.

Сегодня рассказываем про создание визуального интерфейса и один из самых популярных инструментов для этой задачи — tkinter.

Введение в tkinter

Библиотека tkinter в Python нужна для создания визуального интерфейса программы (graphical user interface, или GUI), чтобы было удобнее пользоваться готовым софтом.

Когда мы пишем программу, мы ждём от неё какой-то результат. Иногда для его получения достаточно запустить код, а иногда в него нужно передать дополнительные данные: ввести ответы на вопросы, выбрать вариант работы, загрузить файлы.

Это можно делать в консоли запуска кода. Например, так работает один из наших проектов — игра в блек-джек на Python:

Библиотека tkinter в Python

Такой вариант может быть удобен для тестирования или использования программы разработчиками, но для более широкого круга пользователей лучше сделать привычный способ управления — графическую оболочку. Вот пример — программа для решения тестов, тоже написанная на Python, но с использованием визуальной библиотеки PyQt5:

Библиотека tkinter в Python

Библиотека tkinter — вторая на сегодня по популярности после PyQt5 для создания графических интерфейсов на Python. При этом она самая простая и не требует дополнительной установки, потому что уже интегрирована в язык.

Вот несколько плюсов и минусов tkinter.

✅ Возможности и достоинства.

  • Встроенность: доступна в Python изначально, не требует установки.
  • Кроссплатформенность: tkinter работает на Windows, macOS и Linux.
  • Широкий набор возможностей, достаточный для большинства несложных задач.
  • Простота: у модуля логичный, лаконичный и читаемый код.
  • Популярность: у tkinter хорошая документация и много понятных примеров.
  • Свободное использование: подходит для любых проектов, включая коммерческие.

❌ Недостатки.

  • Создана для простых задач: плохо подходит для создания сложных интерфейсов из-за ограниченной функциональности.
  • Производительность: tkinter может работать с задержками и ошибками на высоконагруженных интерфейсах.
  • Разница на платформах: инструмент работает на разных операционных системах, но отображение может различаться. Это нужно проверять и находить способы исправления.

Что такое Tcl и при чём здесь tkinter

Чтобы дальше было интереснее и понятнее, вот немного информации о том, что за технологии работают под капотом tkinter. Для этого надо разобрать две вещи: Tcl и Tk.

Tcl (Tool Command Language) — это язык программирования, который изначально создавался для управления другими программами и автоматизации задач. Он простой и часто используется для автоматизации и создания графических интерфейсов.

Tk — это графическая библиотека, набор инструментов именно для графических интерфейсов, которые создаются на Tcl. Сама библиотека Tk написана на C, но адаптирована для работы с другими языками. Ещё Tk кроссплатформенная.

Tkinter основан на Tk. Получается, что это инструмент для другого инструмента, чтобы Питон мог пользоваться C-кодом:

  1. Tcl — это язык программирования.
  2. Tk — это графическая библиотека для Tcl.
  3. Tkinter — это обёртка для Tk в Python.

Поэтому, когда мы используем модуль tkinter на Python, под капотом работают Tcl и Tk. Если мозги ещё не закипели и структурно всё плюс-минус понятно, идём дальше.

Создание первого графического интерфейса

Tkinter не нужно устанавливать дополнительно, это стандартный модуль. Если у вас установлен Python, скорее всего эта библиотека тоже работает. Проверить это можно командами python -m tkinter или python3 -m tkinter в терминале командной строки. Появится вот такое окно:

Библиотека tkinter в Python

Если tkinter не установлен, можно попробовать эти способы:

  • Для Windows единственный путь установить tkinter — переустановить Python с официального сайта python.org. При установке нужно убедиться, что у вас выбрана установка Tcl/Tk.
  • На macOS Python может быть без tkinter, если он установлен через пакетный менеджер Homebrew. В этом случае можно попробовать добавить его такой командой в терминале: brew install python-tk. Если это не поможет, нужно переустановить сам Python командой brew reinstall python.

Чтобы создать первый графический интерфейс, мы сделаем такие шаги:

  1. Импортируем tkinter.
  2. Создадим главное окно GUI.
  3. Придумаем заголовок окна (это важный шаг, в программировании нужно придумывать много разных штук :)
  4. Зададим размер окна.
  5. Создадим надпись «Привет, Мир!». При этом указываем окно, в котором она будет размещена, текст, шрифт и размер.
  6. Установим для надписи отступ сверху.
  7. Запустим главный цикл. Без этого окно откроется и сразу закроется.

И теперь код, который всё это делает:

# импортируем tkinter
import tkinter as tk

# создаём главное окно
window = tk.Tk()
# устанавливаем заголовок окна
window.title("Главное окно tkinter")
# задаём размер окна
window.geometry("300x200")

# создаём и размещаем надпись, указываем шрифт и размер
create = tk.Label(window, text="Привет, Мир!", font=("Arial", 16))
# задаём отступ сверху
create.pack(pady=40)

# запускаем главный цикл, чтобы окно не закрывалось
window.mainloop()

Запускаем и проверяем работу:

Библиотека tkinter в Python

Основные виджеты

В tkinter существует много разных инструментов-виджетов. Это готовые фрагменты кода, которые объединены в методы-функции. Их можно вызвать одной командой, задать доступные настройки и получить какой-то результат на видимом интерфейсе: текст, кнопку, вычисление, графический элемент.

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

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

Label нужен для вывода текстовых данных. В нашем примере с «Привет, Мир!» с его помощью мы выводим основную надпись:

label = tk.Label(root, text="Привет, Мир!", font=("Arial", 16))

Button — кнопка, на которую можно нажать, чтобы выполнить какое-то действие. Для обработки нажатий используется метод .bind() или аргумент command. Про эти приёмы мы подробнее расскажем в конце.

Пока что код, который добавит кнопку:

# создаём функцию для нажатия на кнопку
def on_button_click():
   # после нажатия изменяем текст в виджете label
   label.config(text="Кнопка нажата!")

# создаём кнопку, название для кнопки и привязываем
# функцию, которая будет выполняться при нажатии
button = tk.Button(root, text="Нажми меня", command=on_button_click)
# задаём отступы сверху и снизу
button.pack(pady=10)

Что получается:

Библиотека tkinter в Python

Обратите внимание, как кнопка расположилась под объектом Label. Так вышло потому, что метод отрисовки объектов pack располагает элементы один под другим. Про него и другие способы расположения элементов в окне мы расскажем в отдельном разделе в конце статьи.

Entry — однострочное поле ввода текста для получения данных от пользователя.

Для создания нужно сделать несколько вещей:

  • создать поле, куда можно вводить текст;
  • добавить функцию, которая этот текст забирает и выводит;
  • подключить кнопку с командой запуска функции вывода текста. 

Получается такой код:

# создаём поле entry, указываем шрифт и размер
entry = tk.Entry(root, font=("Arial", 14))
# задаём отступы сверху и снизу
entry.pack(pady=10)

# создаём функцию, чтобы видеть, что именно ввёл пользователь
def show_input():
   # получаем данные из поля
   user_input = entry.get()
   # изменяем текст в объекте label
   label.config(text=f"Введено: {user_input}")

# добавляем кнопку, чтобы можно было посмотреть введённую информацию
button = tk.Button(root, text="Показать введённое", command=show_input)
# задаём отступы сверху и снизу
button.pack(pady=10)

Запускаем:

Библиотека tkinter в Python

Text — многострочное поле для ввода текста. Удобно для больших блоков текста.

Что понадобится:

  • основной объект tk.Text;
  • функция, которая будет получать и выводить введённые символы;
  • кнопка, которая будет включать функцию для показа текста.

Код для вставки (не забывайте, что отступы считаются от последнего добавленного элемента):

# создаём объект text и указываем root как объект,
# на котором будет отрисован text.
# задаём высоту и ширину поля, шрифт и размер шрифта
text = tk.Text(root, height=5, width=30, font=("Arial", 12))
# задаём отступы сверху и снизу
text.pack(pady=10)

# создаём функцию, чтобы видеть, что именно ввёл пользователь
def show_text():
   # получаем текст с 1-й строки до конца
   installed = text.get("1.0", "end-1c")
   # изменяем текст в объекте label
   label.config(text=f"Текст: {installed}")

# добавляем кнопку, чтобы можно было посмотреть введённую информацию
button = tk.Button(root, text="Показать текст", command=show_text)
# задаём отступы сверху и снизу
button.pack(pady=10)

Что получается при запуске:

Библиотека tkinter в Python
# импортируем tkinter
import tkinter as tk

# создаём главное окно
root = tk.Tk()
# устанавливаем заголовок окна
root.title("Главное окно tkinter")
# задаём размер окна
root.geometry("400x400")

# создаём и размещаем надпись, указываем шрифт и размер
label = tk.Label(root, text="Привет, Мир!", font=("Arial", 16))
# задаём отступы сверху и снизу
label.pack(pady=40)

# создаём функцию для нажатия на кнопку
def on_button_click():
   # после нажатия изменяем текст в виджете label
   label.config(text="Кнопка нажата!")

# создаём кнопку, название для кнопки и привязываем
# функцию, которая будет выполняться при нажатии
button = tk.Button(root, text="Нажми меня", command=on_button_click)
# задаём отступы сверху и снизу
button.pack(pady=10)

# создаём поле entry, указываем шрифт и размер
entry = tk.Entry(root, font=("Arial", 14))
# задаём отступы сверху и снизу
entry.pack(pady=10)

# создаём функцию, чтобы видеть, что именно ввёл пользователь
def show_input():
   # получаем данные из поля
   user_input = entry.get()
   # изменяем текст в объекте label
   label.config(text=f"Введено: {user_input}")

# добавляем кнопку, чтобы можно было посмотреть введённую информацию
button = tk.Button(root, text="Показать введённое", command=show_input)
# задаём отступы сверху и снизу
button.pack(pady=10)

# создаём объект text и указываем root как объект,
# на котором будет отрисован text.
# задаём высоту и ширину поля, шрифт и размер шрифта
text = tk.Text(root, height=5, width=30, font=("Arial", 12))
# задаём отступы сверху и снизу
text.pack(pady=10)

# создаём функцию, чтобы видеть, что именно ввёл пользователь
def show_text():
   # получаем текст с 1-й строки до конца
   applications = text.get("1.0", "end-1c")
   # изменяем текст в объекте label
   label.config(text=f"Текст: {applications}")

# добавляем кнопку, чтобы можно было посмотреть введённую информацию
button = tk.Button(root, text="Показать текст", command=show_text)
# задаём отступы сверху и снизу
button.pack(pady=10)

# запускаем главный цикл, чтобы окно не закрывалось
root.mainloop()

Дополнительные виджеты

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

Checkbutton. Это виджет для создания флажков, которые могут быть включены или выключены. Так пользователь может выбрать между двумя состояниями — например, согласиться на рассылку или не соглашаться.

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

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

Spinbox. Позволяет выбрать значение из числового диапазона с помощью стрелочек вверх и вниз. Это бывает удобно, если нужно задать конкретное число, например возраст или количество.

Progressbar. Индикатор прогресса, который визуально отображает ход выполнения задачи. Он может заполняться до определённого уровня или двигаться непрерывно. Если ваша программа иногда долго думает или что-то считает — добавляйте прогресс-бар: так пользователь поймёт, что она не зависла.

Для работы с некоторыми виджетами мы подключим ещё один модуль — ttk. Это часть библиотеки tkinter, но с улучшенными версиями виджетов.

# импортируем tkinter
import tkinter as tk
from tkinter import ttk

# создаём главное окно
root = tk.Tk()
# устанавливаем заголовок окна
root.title("Главное окно tkinter")
# задаём размер окна
root.geometry("400x400")

# создаём переменную, которая будет хранить целочисленное
# значение и использоваться для связи с виджетами,
var = tk.IntVar()
# создаём объект Checkbutton: указываем родительский
# объект для размещения, текст для кнопки и указываем
# переменную для сохранения
checkbutton = tk.Checkbutton(root, text="Выбери меня", variable=var)
# задаём отступы сверху и снизу
checkbutton.pack(pady=10)

# создаём переменную, которая будет хранить строки
# и использоваться для связи с виджетами,
var2 = tk.StringVar()
# создаём объект Radiobutton
radiobutton1 = tk.Radiobutton(root, text="Опция 1", variable=var2, value="1")
radiobutton2 = tk.Radiobutton(root, text="Опция 2", variable=var2, value="2")
# задаём отступы сверху и снизу для первой радиокнопки
radiobutton1.pack(pady=10)
# задаём отступы сверху и снизу для второй радиокнопки
radiobutton2.pack(pady=10)

# создаём объект Combobox: указываем родительский
# объект для размещения и список значений, которые можно будет выбрать
combo = ttk.Combobox(root, values=["Яблоко", "Банан", "Груша"])
# задаём отступы сверху и снизу
combo.pack(pady=10)

# создаём объект Spinbox: указываем родительский
# объект для размещения и диапазон выбора
spinbox = tk.Spinbox(root, from_=1, to=10)
# задаём отступы сверху и снизу
spinbox.pack(pady=10)

# создаём объект Progressbar: указываем родительский
# объект для размещения, длину полосы и тип индикатора
progress = ttk.Progressbar(root, length=200, mode="indeterminate")
# задаём отступы сверху и снизу
progress.pack(pady=20)
# запускаем Progressbar
progress.start()

# запускаем главный цикл, чтобы окно не закрывалось
root.mainloop()

Так это выглядит в окне нашего интерфейса:

Библиотека tkinter в Python

Создание виджета Frame и его использование

Frame — это контейнер, который помогает организовывать другие виджеты внутри окна. У него нет своих функций, но фреймы используются для группировки элементов интерфейса и управления их расположением.

Например, можно создать два фрейма: для кнопок и для текстовых элементов. При запуске они будут являться на одном главном экране, но их можно разделить визуально.

# импортируем tkinter
import tkinter as tk
from tkinter import ttk

# создаём главное окно
root = tk.Tk()
# устанавливаем заголовок окна
root.title("Пример использования Frame")
# задаём размер окна
root.geometry("300x200")

# создаём первый фрейм и размещаем в окне, задаём фон для фрейма
# и отступы между родительским фреймом и фреймом-наследником
frame1 = tk.Frame(root, bg="lightgray", padx=10, pady=10)
# указываем, как фрейм будет расширяться при добавлении элементов.
# both указывает, что он будет растягиваться по ширине и высоте.
# expand=True заставляет фрейм заполнять всё доступное пространство
frame1.pack(fill="both", expand=True)

# добавляем текстовый виджет в первый фрейм
label = tk.Label(frame1, text="Привет, Мир!", font=("Arial", 14))
label.pack()

# создаём второй фрейм для кнопок
frame2 = tk.Frame(root, bg="white", padx=5, pady=5)
# # указываем, как фрейм будет расширяться при добавлении элементов.
# fill="x" указывает, что он будет растягиваться по ширине.
frame2.pack(fill="x")

# добавляем кнопки в нижний фрейм
btn1 = tk.Button(frame2, text="Кнопка 1")
btn2 = tk.Button(frame2, text="Кнопка 2")

# добавляем кнопкам горизонтальные отступы от фрейма
btn1.pack(side="left", padx=5)
btn2.pack(side="right", padx=5)

# запускаем главный цикл, чтобы окно не закрывалось
root.mainloop()

При запуске верхний фрейм для текста будет выделен фоном со светло-серым цветом:

Библиотека tkinter в Python

Настройка интерфейса и менеджеры геометрии

Элементы интерфейса нужно не только создать, но и правильно разместить в окне. Для этого используются менеджеры геометрии, которые определяют расположение и размеры элементов.

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

Мы в коде использовали этот вариант, но есть и другие способы.

Grid() организует элементы в таблицу строк и столбцов. Это удобно, если нужно разместить виджеты в структурированном порядке, например в формах или таблицах. 

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

Обработка событий и взаимодействие с пользователем

Чтобы приложение было интерактивным, оно должно предоставлять возможность реагировать на действия пользователя: нажатия кнопок, ввод текста, перемещение мыши.

Вот два виджета, которые дают такую возможность.

Метод .bind() для виджетов позволяет привязывать действия пользователя к определённым функциям, например клик мыши или нажатие кнопки на клавиатуре. С его помощью можно создать горячие клавиши и динамическое изменение интерфейса.

Атрибут command для кнопок нужен для привязки кнопок к определённой функции. Это самый простой способ обработки действий в tkinter. Когда пользователь нажимает кнопку, вызывается функция без необходимости передавать дополнительные параметры.

Создание интерактивных приложений

Вот несколько примеров того, что можно делать на tkinter:

  • калькулятор для расчёта индекса массы тела;
  • текстовый редактор;
  • конвертер единиц;
  • таймер и секундомер;
  • файловый менеджер;
  • генератор паролей.

В следующий раз возьмём одну из этих идей и реализуем её на Python. Подпишитесь, чтобы не пропустить (и чтобы стать создателем крутых интерфейсов, хе-хе).

Вам слово

Приходите к нам в соцсети поделиться своим мнением о библиотеке tkinter и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте: шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!

Обложка:

Алексей Сухов

Корректор:

Елена Грицун

Вёрстка:

Мария Климентьева

Соцсети:

Юлия Зубарева

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
А вы читали это?
hard