Python: уроки, справочник и задачи

Первая программа с графическим интерфейсом на Tkinter

Раздел: Flask и Tkinter · Обновлено 31.10.2026

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

Первая программа с графическим интерфейсом на Tkinter
Фото: René Fischer / Public domain, Wikimedia Commons
Содержание статьи
  1. Проверка установки tkinter
  2. Минимальная программа с пустым окном
  3. Надпись и кнопка с обработчиком
    1. Почему command пишется без скобок
  4. Поле ввода и проверка данных
  5. Размещение виджетов: pack, grid и place
  6. Современный вид через ttk
  7. Частые вопросы
    1. Как убрать черное окно консоли при запуске?
    2. Как запретить изменение размера окна?
    3. Почему интерфейс зависает во время долгой операции?
    4. Как закрыть окно из кода?

Проверка установки tkinter

Tkinter входит в стандартную библиотеку Python и использует набор Tcl/Tk. В официальных установщиках для Windows и macOS он включен по умолчанию. Проверить, что все работает, можно одной командой в терминале:

python -m tkinter

Должно открыться маленькое тестовое окно с версией Tk и двумя кнопками. Если появилась ошибка ModuleNotFoundError: No module named 'tkinter', модуль придется доустановить:

Внутри программы модуль принято импортировать с коротким псевдонимом: import tkinter as tk. Так видно, какие имена пришли из библиотеки, и не засоряется пространство имен.

Минимальная программа с пустым окном

Любое приложение начинается с главного окна и заканчивается запуском цикла обработки событий.

import tkinter as tk

root = tk.Tk()
root.title("Мое первое приложение")
root.geometry("400x300")
root.mainloop()

Что делает каждая строка:

Если забыть mainloop() и запустить файл двойным щелчком, окно мелькнет и сразу исчезнет. В интерактивной оболочке IDLE окно может появиться и без этого вызова, что сбивает с толку.

Надпись и кнопка с обработчиком

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

import tkinter as tk

clicks = 0

def on_click():
    global clicks
    clicks += 1
    label.config(text=f"Нажатий: {clicks}")

root = tk.Tk()
root.title("Счетчик")
root.geometry("300x150")

label = tk.Label(root, text="Нажмите кнопку", font=("Arial", 14))
label.pack(pady=20)

button = tk.Button(root, text="Нажать", command=on_click)
button.pack()

root.mainloop()

Label выводит текст, Button рисует кнопку, а метод config() меняет свойства виджета на лету. Параметр pady добавляет отступ сверху и снизу. Функции, которые реагируют на действия пользователя, называют обработчиками; о том, как их объявлять, рассказано в статье про функции Python.

Почему command пишется без скобок

В command передается сама функция, а не результат ее вызова. Запись command=on_click() выполнит функцию один раз при создании кнопки, а нажатия потом ничего делать не будут. Если обработчику нужны аргументы, оберните вызов в lambda: command=lambda: greet("Анна").

Поле ввода и проверка данных

Для ввода текста служит виджет Entry. Его содержимое читается методом get() и всегда приходит строкой, поэтому числа нужно преобразовать самостоятельно. Ниже небольшой конвертер температуры с обработкой неверного ввода.

import tkinter as tk
from tkinter import messagebox

def convert():
    try:
        celsius = float(entry.get().replace(",", "."))
    except ValueError:
        messagebox.showerror("Ошибка", "Введите число")
        return
    fahrenheit = celsius * 9 / 5 + 32
    result.config(text=f"{fahrenheit:.1f} °F")

root = tk.Tk()
root.title("Конвертер")

tk.Label(root, text="Градусы Цельсия:").grid(row=0, column=0, padx=10, pady=10)
entry = tk.Entry(root, width=10)
entry.grid(row=0, column=1, padx=10)
tk.Button(root, text="Перевести", command=convert).grid(row=1, column=0, columnspan=2)
result = tk.Label(root, text="")
result.grid(row=2, column=0, columnspan=2, pady=10)

root.mainloop()

Модуль messagebox показывает стандартные диалоги: showinfo, showwarning, showerror, askyesno. Обратите внимание, что надпись слева создана и размещена в одну строку: ссылка на нее дальше не нужна. С полем ввода так делать нельзя: метод grid() возвращает None, и переменная потеряла бы виджет.

Размещение виджетов: pack, grid и place

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

МенеджерПринципКогда подходит
pack()Складывает виджеты друг за другом сверху вниз или по сторонам (side="left")Простые окна, панели кнопок
grid()Таблица из строк и столбцов, row и columnФормы с подписями и полями
place()Точные координаты x, y или доли размера окнаРедкие случаи с ручной разметкой

Главное правило: внутри одного контейнера нельзя смешивать pack() и grid(). Tkinter выбросит TclError. Если нужны разные схемы, разбейте окно на несколько tk.Frame и в каждом используйте свой менеджер.

Современный вид через ttk

Классические виджеты выглядят старомодно, особенно на Windows. Подмодуль tkinter.ttk содержит тематические версии тех же элементов, которые рисуются в стиле операционной системы.

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("ttk")
ttk.Label(root, text="Имя:").pack(padx=20, pady=(20, 5))
ttk.Entry(root).pack(padx=20)
ttk.Button(root, text="OK", command=root.destroy).pack(pady=20)
root.mainloop()

У виджетов ttk часть параметров отличается: например, цвет фона и шрифт задаются через стили ttk.Style(), а не аргументами bg и font. Справку по всем виджетам и их опциям удобно держать под рукой; ссылки собраны на странице документации Tkinter, а исходное описание модуля есть на docs.python.org.

Частые вопросы

Ответы на вопросы, которые возникают после запуска первого окна.

Как убрать черное окно консоли при запуске?

На Windows сохраните файл с расширением .pyw или запускайте его через pythonw.exe. При сборке в исполняемый файл добавьте флаг --noconsole; как это сделать, описано в статье про PyInstaller.

Как запретить изменение размера окна?

Вызовите root.resizable(False, False). Первый аргумент отвечает за ширину, второй за высоту. Минимальный размер задается методом minsize().

Почему интерфейс зависает во время долгой операции?

Обработчик выполняется в том же потоке, что и mainloop(), и пока он работает, окно не перерисовывается. Долгие задачи выносят в отдельный поток или разбивают на части через root.after().

Как закрыть окно из кода?

Метод root.destroy() закрывает окно и завершает mainloop(). Его можно передать в command кнопки без скобок, как в примере с ttk.