Tkinter: справочник по виджетам и размещению
Документация Tkinter на русском в одном месте: как создать окно, какие виджеты есть в библиотеке, как размещать их через pack, grid и place и как реагировать на действия пользователя. Каждый раздел сопровождается коротким рабочим примером на Python 3.12, который можно запустить без установки дополнительных пакетов.

Содержание статьи
Что такое Tkinter и как его подключить
Tkinter - стандартный модуль Python для создания графических приложений. Он является оберткой над библиотекой Tcl/Tk и работает в Windows, macOS и Linux. Отдельно ставить его через pip не нужно: модуль входит в состав официального установщика Python для Windows и macOS.
В некоторых дистрибутивах Linux Tk вынесен в отдельный системный пакет. Если при импорте появляется ModuleNotFoundError: No module named '_tkinter', в Debian и Ubuntu поможет команда sudo apt install python3-tk. Проверить, что все работает, можно командой python -m tkinter: она откроет тестовое окно с версией Tk.
import tkinter as tk
from tkinter import ttk
print(tk.TkVersion) # например 8.6Модуль ttk содержит те же виджеты в современном оформлении, которое подстраивается под операционную систему. В новых проектах лучше брать кнопки, поля ввода и списки именно из ttk.
Первое окно приложения
Любая программа на Tkinter строится по одной схеме: создать главное окно Tk(), добавить в него виджеты и запустить цикл обработки событий mainloop(). Пока цикл работает, окно реагирует на клики и нажатия клавиш.
import tkinter as tk
root = tk.Tk()
root.title("Мое приложение")
root.geometry("400x250") # ширина x высота
root.resizable(False, False)
tk.Label(root, text="Привет, Tkinter!").pack(pady=20)
root.mainloop()Код после mainloop() выполнится только после закрытия окна. Метод geometry() принимает и позицию на экране: строка "400x250+100+50" задает отступ 100 пикселей слева и 50 сверху. Пошаговый разбор первой программы есть в уроке первая программа на Tkinter.
Основные виджеты
Виджет - это элемент интерфейса. Первым аргументом при создании всегда передается родитель: главное окно или контейнер Frame. Остальные параметры задают текст, размеры и поведение.
| Виджет | Назначение | Ключевые параметры |
|---|---|---|
Label | Текст или картинка | text, image, font |
Button | Кнопка | text, command |
Entry | Однострочное поле ввода | textvariable, show |
Text | Многострочный текст | width, height, wrap |
Checkbutton, Radiobutton | Флажок и переключатель | variable, value |
Listbox, ttk.Combobox | Список и выпадающий список | values, selectmode |
Frame | Контейнер для группы виджетов | padx, pady, borderwidth |
Canvas | Холст для рисования фигур | width, height, bg |
Параметры можно менять после создания через метод config(): label.config(text="Готово"). Прочитать значение из поля Entry помогает метод get(), очистить его - delete(0, tk.END).
Размещение виджетов: pack, grid и place
Созданный виджет не появится в окне, пока не вызван один из менеджеров геометрии. В одном контейнере нельзя смешивать pack и grid: программа зависнет или выдаст ошибку. Если нужны разные схемы, разнесите виджеты по разным Frame.
pack для простых форм
Менеджер pack ставит виджеты друг за другом сверху вниз или по сторонам окна. Параметр side задает сторону, fill и expand растягивают элемент.
tk.Button(root, text="Верх").pack(side="top", fill="x")
tk.Button(root, text="Лево").pack(side="left", padx=5)grid для таблиц и форм ввода
Менеджер grid раскладывает виджеты по строкам и столбцам. Он удобнее всего для форм с подписями и полями. Параметр sticky прижимает элемент к сторонам ячейки (n, s, e, w), columnspan объединяет ячейки.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
ttk.Label(root, text="Логин").grid(row=0, column=0, sticky="w", padx=5, pady=5)
ttk.Entry(root).grid(row=0, column=1, padx=5)
ttk.Label(root, text="Пароль").grid(row=1, column=0, sticky="w", padx=5)
ttk.Entry(root, show="*").grid(row=1, column=1, padx=5)
ttk.Button(root, text="Войти").grid(row=2, column=0, columnspan=2, pady=10)
root.mainloop()place для точных координат
Менеджер place ставит виджет в заданную точку: place(x=20, y=40) или относительно размера окна place(relx=0.5, rely=0.5, anchor="center"). При изменении размеров окна абсолютные координаты не пересчитываются, поэтому place используют редко.
События и переменные
Самый простой способ отреагировать на действие - параметр command у кнопки. В него передается функция без скобок, иначе она выполнится один раз при создании кнопки. Если функции нужны аргументы, оберните вызов в лямбда-функцию.
Для клавиш, движений мыши и других событий служит метод bind(). Обработчик получает объект события с координатами, кодом клавиши и ссылкой на виджет.
import tkinter as tk
root = tk.Tk()
name = tk.StringVar()
def greet(event=None):
result.config(text=f"Привет, {name.get()}!")
entry = tk.Entry(root, textvariable=name)
entry.pack(pady=5)
entry.bind("<Return>", greet)
tk.Button(root, text="Поздороваться", command=greet).pack()
result = tk.Label(root)
result.pack(pady=5)
root.mainloop()Классы StringVar, IntVar, DoubleVar и BooleanVar связывают значение с виджетом: при изменении переменной через set() обновляется интерфейс, и наоборот. Для периодических действий, например таймера, вызывайте root.after(1000, func) вместо time.sleep(), который заморозит окно.
Диалоговые окна
Готовые окна сообщений находятся в подмодуле messagebox, а выбор файлов в filedialog. Их нужно импортировать отдельно.
from tkinter import messagebox, filedialog
if messagebox.askyesno("Выход", "Закрыть программу?"):
root.destroy()
path = filedialog.askopenfilename(filetypes=[("Текст", "*.txt")])Функции showinfo(), showwarning() и showerror() просто показывают сообщение, а askyesno() и askokcancel() возвращают True или False. Если пользователь закрыл окно выбора файла, askopenfilename() вернет пустую строку. Полный перечень классов и опций приведен в официальной документации tkinter. Другие уроки по теме собраны в разделе Flask и Tkinter.
Частые вопросы
Ответы на вопросы, которые чаще всего возникают при первых шагах в Tkinter.
Почему функция кнопки срабатывает сразу при запуске?
В command передан вызов функции со скобками. Нужно передать саму функцию: command=greet, а для аргументов использовать command=lambda: greet("Анна").
Почему окно зависает во время долгой операции?
Весь интерфейс работает в одном потоке с mainloop(). Долгие вычисления выносите в отдельный поток, а обновление виджетов планируйте через after().
Как вставить картинку в окно?
Класс tk.PhotoImage читает PNG и GIF. Для JPEG нужна библиотека Pillow и класс ImageTk.PhotoImage. Храните ссылку на объект изображения в переменной, иначе сборщик мусора удалит его и картинка исчезнет.
Чем tk.Button отличается от ttk.Button?
Виджеты ttk рисуются в стиле операционной системы и настраиваются через темы и ttk.Style. У классических виджетов tk можно напрямую задать цвет фона и шрифт параметрами bg и font.