Python
Tkinter Python: окно с кнопкой и обработчиком
Tkinter позволяет быстро сделать простое окно на Python без установки отдельного GUI-фреймворка. Первый полезный шаг — не просто вывести кнопку, а связать ее с обработчиком: функцией, которая выполняется после клика
На этом примере удобно понять главную идею интерфейса: пользователь нажимает кнопку, программа меняет состояние, окно сразу показывает результат
По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы
Минимальное окно
import tkinter as tk
root = tk.Tk()
root.title('Первое окно')
root.geometry('300x160')
label = tk.Label(root, text='Нажмите кнопку')
label.pack(pady=20)
root.mainloop()
root = tk.Tk() создает главное окно, Label показывает текст, pack() размещает элемент, а mainloop() запускает цикл обработки событий
Без mainloop() окно может открыться и сразу закрыться, потому что программе нечего будет ждать
Кнопка с обработчиком
Теперь добавим кнопку и функцию, которая меняет текст
import tkinter as tk
root = tk.Tk()
root.title('Кнопка Tkinter')
root.geometry('320x180')
label = tk.Label(root, text='Нажмите кнопку')
label.pack(pady=20)
def on_click():
label.config(text='Кнопка нажата')
button = tk.Button(root, text='Нажать', command=on_click)
button.pack(pady=10)
root.mainloop()
Главная строка здесь — command=on_click
Мы передаем функцию без скобок. Если написать command=on_click(), функция выполнится сразу при создании кнопки, а не после клика
Как читать этот код
В примере есть четыре роли:
rootхранит главное окноlabelпоказывает текстon_click()описывает действие после кликаbuttonсвязывает кнопку с обработчиком
Когда пользователь нажимает кнопку, Tkinter вызывает on_click(). Внутри функции строка label.config(...) меняет уже созданный виджет
Это нормальная модель для маленьких интерфейсов: создать элементы, описать обработчики, запустить окно
Счетчик кликов
Следующий полезный пример — счетчик. Он показывает, как хранить состояние между кликами
import tkinter as tk
root = tk.Tk()
root.title('Счетчик')
root.geometry('320x180')
count = 0
label = tk.Label(root, text='Кликов: 0', font=('Arial', 16))
label.pack(pady=20)
def add_click():
global count
count += 1
label.config(text=f'Кликов: {count}')
button = tk.Button(root, text='Добавить', command=add_click)
button.pack(pady=10)
root.mainloop()
count хранит число кликов. После каждого нажатия функция увеличивает значение и обновляет текст в label
Для учебного примера global допустим. В более крупном интерфейсе состояние обычно переносят в класс, чтобы не держать много глобальных переменных
Кнопка сброса
Добавим вторую кнопку, чтобы счетчик можно было вернуть к нулю
import tkinter as tk
root = tk.Tk()
root.title('Счетчик с кнопками')
root.geometry('340x220')
count = 0
label = tk.Label(root, text='Кликов: 0', font=('Arial', 16))
label.pack(pady=20)
def refresh_label():
label.config(text=f'Кликов: {count}')
def add_click():
global count
count += 1
refresh_label()
def reset_clicks():
global count
count = 0
refresh_label()
tk.Button(root, text='Добавить', command=add_click).pack(pady=5)
tk.Button(root, text='Сбросить', command=reset_clicks).pack(pady=5)
root.mainloop()
Здесь уже видно маленькую структуру: отдельная функция refresh_label() отвечает только за обновление текста. Так меньше повторов и проще менять интерфейс
Поле ввода и кнопка
Частый сценарий Tkinter — пользователь вводит текст, нажимает кнопку, программа показывает результат
import tkinter as tk
root = tk.Tk()
root.title('Приветствие')
root.geometry('360x200')
entry = tk.Entry(root)
entry.pack(pady=10)
result = tk.Label(root, text='Введите имя')
result.pack(pady=10)
def say_hello():
name = entry.get().strip()
if not name:
result.config(text='Имя не введено')
return
result.config(text=f'Привет, {name}')
button = tk.Button(root, text='Показать приветствие', command=say_hello)
button.pack(pady=10)
root.mainloop()
entry.get() читает текст из поля. strip() убирает лишние пробелы, а проверка if not name защищает от пустого ввода
Это уже маленькая форма, а не просто демонстрация кнопки
Почему окно зависает
Новички часто запускают тяжелый код прямо внутри обработчика кнопки. Пока функция выполняется, Tkinter не может перерисовать окно и обработать новые события
Плохая идея:
def on_click():
while True:
pass
Для долгих задач используют отдельный поток, очередь, after() или выносят тяжелую работу за пределы интерфейса. В первом учебном окне лучше держать обработчики короткими: прочитать значение, изменить текст, выполнить простую проверку
Частые ошибки
- писать
command=on_click()вместоcommand=on_click - вызывать
mainloop()до создания кнопок - менять виджет, который еще не создан
- забывать
global, если учебный счетчик меняет внешнюю переменную - ожидать, что
print()заменит обновление текста в окне - запускать бесконечный цикл внутри обработчика
- смешивать
pack()иgrid()в одном контейнере без понимания раскладки
Практика
Сделайте три маленьких улучшения
- Добавьте кнопку, которая меняет цвет текста
- Добавьте поле ввода и выводите длину введенной строки
- Сделайте кнопку очистки поля
После каждого шага запускайте окно заново и проверяйте только одно изменение. Так проще понять, какая строка сломала интерфейс, если появится ошибка
Окно Tkinter с кнопкой строится из простых частей: главное окно, виджеты, функция-обработчик и mainloop()
Самое важное правило: в command передается имя функции без скобок
Если кнопка должна менять текст, счетчик или результат формы, создайте отдельную функцию и обновляйте нужный виджет через .config()