Практические примеры Tkinter: от окон до сложных виджетов и анимации
Основные примеры Tkinter приложений
Как создать минимальное окно с кнопкой и обработать нажатие?
Самый эффективный способ запустить Tkinter приложение - использовать класс Tk для создания главного окна, добавить виджеты и запустить главный цикл. Ниже представлен пример программы, которая выводит сообщение при нажатии кнопки.
import tkinter as tk
def say_hello():
print("Привет, мир!")
root = tk.Tk()
root.title("Пример окна")
btn = tk.Button(root, text="Нажми меня", command=say_hello)
btn.pack()
root.mainloop()
Python self tkinter (использование self в tkinter)
После запуска откроется окно с кнопкой. При нажатии в консоль выводится Привет, мир!. Этот подход подходит для любого простого приложения, где требуется одна функция-обработчик.
Типичные ошибки и их решение
- Забыли импортировать модуль tkinter - возникает ImportError. Решение: проверьте импорт и наличие установленной библиотеки (pip install tk).
- Метод pack() не вызван - виджет не отображается. Всегда завершайте настройку вызовом геометрии.
- Использование root.mainloop() не в конце - окно не будет отвечать. Помещайте вызов после добавления всех виджетов.
Как создать окно с меткой и полем ввода?
Используйте виджеты Label и Entry. Пример выводит введённый текст при нажатии кнопки.
import tkinter as tk
def show_text():
text = entry.get()
label_result.config(text=f"Вы ввели: {text}")
root = tk.Tk()
root.geometry("300x200")
label_prompt = tk.Label(root, text="Введите что-нибудь:")
label_prompt.pack()
entry = tk.Entry(root)
entry.pack()
btn = tk.Button(root, text="Показать", command=show_text)
btn.pack()
label_result = tk.Label(root, text="")
label_result.pack()
root.mainloop()
Tkinter python buttons (кнопки в tkinter (англ.))
Этот вариант полезен для форм ввода или чатов. Обратите внимание на метод config() для обновления текста метки.
Проблема: при вводе пустой строки или пробелов обработка не отличается. Решение - добавить проверку if entry.get(): ....
Как сделать окно с выпадающим списком (Combobox)?
Виджет ttk.Combobox предоставляет раскрывающийся список. Пример выбора города.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Выбор города")
label = tk.Label(root, text="Выберите город:")
label.pack()
cities = ["Москва", "Санкт-Петербург", "Казань", "Новосибирск"]
combo = ttk.Combobox(root, values=cities)
combo.set(cities[0])
combo.pack()
def on_select(event):
selected = combo.get()
tk.messagebox.showinfo("Выбор", f"Вы выбрали {selected}")
combo.bind("<>", on_select)
root.mainloop()
Python tkinter label (метка (label) в tkinter)
Этот код удобен для анкет или настроек. Обработка события <
Ошибка: если не задать values, список будет пуст. Также нужно импортировать ttk отдельно.
Как создать простое диалоговое окно с сообщением?
Используйте модуль tkinter.messagebox. Пример подтверждения выхода.
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.geometry("200x100")
def close_app():
answer = messagebox.askyesno("Выход", "Вы действительно хотите выйти?")
if answer:
root.destroy()
btn = tk.Button(root, text="Закрыть", command=close_app)
btn.pack(pady=20)
root.mainloop()
Python tkinter entry (поле ввода (entry) в tkinter)
Диалоговые окна - стандартный способ взаимодействия с пользователем. Доступны showinfo, askyesno, askopenfilename и другие.
Проблема: при импорте модуля messagebox нужно не забыть его указать, иначе возникает AttributeError.
Как организовать расположение виджетов с помощью сетки (grid)?
Метод grid() размещает элементы в строках и столбцах. Пример калькулятора (только интерфейс).
import tkinter as tk
root = tk.Tk()
root.title("Калькулятор")
display = tk.Entry(root, width=20, justify="right")
display.grid(row=0, column=0, columnspan=4)
buttons = [
["7", "8", "9", "/"],
["4", "5", "6", "*"],
["1", "2", "3", "-"],
["0", ".", "=", "+"]
]
for i, row in enumerate(buttons, start=1):
for j, text in enumerate(row):
btn = tk.Button(root, text=text, width=5, height=2)
btn.grid(row=i, column=j)
root.mainloop()
Python tkinter приложение (создание приложения на tkinter)
Сетка идеально подходит для табличных интерфейсов и форм. Параметры columnspan позволяют объединять ячейки.
Ошибка: если не указать sticky, виджеты не прижимаются к краям. Для выравнивания используйте sticky="nsew".
Как добавить изображение в окно?
Для отображения картинок используйте PhotoImage (поддерживает PNG, GIF). Пример загрузки изображения.
import tkinter as tk
from tkinter import PhotoImage
root = tk.Tk()
root.title("Изображение")
img = PhotoImage(file="example.png")
label = tk.Label(root, image=img)
label.pack()
root.mainloop()
Python tkinter programs (примеры программ на tkinter)
Этот способ работает только с файлами форматов, поддерживаемых PhotoImage (GIF, PNG, PGM, PPM). Для JPG используйте библиотеку Pillow.
Проблема: ссылка на PhotoImage может быть удалена сборщиком мусора, если не хранить её в глобальной переменной. Решение - присвоить объект изображения атрибуту окна root.img = img.
Как использовать таймер для периодических действий?
Метод after() позволяет выполнять функцию через заданный интервал. Пример часов.
import tkinter as tk
from datetime import datetime
def update_time():
now = datetime.now().strftime("%H:%M:%S")
label.config(text=now)
root.after(1000, update_time)
root = tk.Tk()
root.title("Часы")
label = tk.Label(root, font=("Arial", 30))
label.pack()
update_time()
root.mainloop()
Таймеры полезны для анимации, обновления данных, игр. Обратите внимание на рекурсию after(): она не создаёт бесконечную вложенность, а планирует следующий вызов.
Ошибка: если не использовать after_cancel() при закрытии окна, программа может упасть. В данном примере это не критично, но для сложных приложений лучше отменить таймер.
Расширенные примеры программ на Tkinter
Многопоточность с Tkinter (асинхронные задачи)
Долгие операции блокируют интерфейс. Используйте threading с очередью. Пример симуляции загрузки.
import tkinter as tk
from threading import Thread
import time
from queue import Queue
def long_task(q):
for i in range(10):
time.sleep(0.5)
q.put(i) # передаём прогресс
def check_queue():
while not q.empty():
val = q.get()
progress["value"] = (val + 1) * 10
root.after(100, check_queue)
root = tk.Tk()
root.title("Многопоточность")
progress = ttk.Progressbar(root, length=200, mode="determinate")
progress.pack(pady=20)
q = Queue()
thread = Thread(target=long_task, args=(q,))
thread.start()
check_queue()
root.mainloop()
Программа запускает поток, обновляет ProgressBar каждые 0.5 секунды, интерфейс не зависает.
Рисование на Canvas (графика)
Виджет Canvas позволяет рисовать фигуры, текст и обрабатывать события мыши.
import tkinter as tk
root = tk.Tk()
root.title("Canvas рисунок")
canvas = tk.Canvas(root, width=400, height=300, bg="white")
canvas.pack()
# Рисуем прямоугольник
canvas.create_rectangle(50, 50, 150, 100, fill="blue", outline="black")
# Рисуем овал
canvas.create_oval(200, 50, 300, 150, fill="red")
# Текст
canvas.create_text(200, 200, text="Привет, Canvas!", font=("Arial",16))
root.mainloop()
Открывается окно с синим прямоугольником, красным овалом и текстом. Canvas поддерживает также линии и дуги.
Вкладки с помощью Notebook (ttk.Notebook)
Интерфейс с вкладками - удобно для сложных приложений.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Вкладки")
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)
# Вкладка 1
frame1 = ttk.Frame(notebook, padding=10)
notebook.add(frame1, text="Первая")
ttk.Label(frame1, text="Содержимое вкладки 1").pack()
# Вкладка 2
frame2 = ttk.Frame(notebook, padding=10)
notebook.add(frame2, text="Вторая")
ttk.Label(frame2, text="Содержимое вкладки 2").pack()
root.mainloop()
Окно отображает две вкладки, переключение между ними работает без задержек.
Работа с таблицей через Treeview
Treeview - мощный виджет для табличных данных и деревьев.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title("Таблица")
columns = ("Имя", "Возраст", "Город")
tree = ttk.Treeview(root, columns=columns, show="headings")
tree.heading("Имя", text="Имя")
tree.heading("Возраст", text="Возраст")
tree.heading("Город", text="Город")
data = [("Анна", 25, "Москва"), ("Иван", 30, "СПб"), ("Мария", 22, "Казань")]
for row in data:
tree.insert("", "end", values=row)
tree.pack(fill="both", expand=True)
root.mainloop()
Отображается таблица с тремя столбцами и тремя строками данных. Поддерживается сортировка и редактирование.
Обработка клавиш и мыши
Привязывайте события с помощью метода bind().
import tkinter as tk
root = tk.Tk()
root.title("События")
label = tk.Label(root, text="Нажмите любую клавишу")
label.pack(pady=20)
def key_press(event):
label.config(text=f"Нажата клавиша: {event.char} (код {event.keysym})")
def mouse_click(event):
label.config(text=f"Клик мыши в ({event.x},{event.y})")
root.bind("", key_press)
root.bind("", mouse_click)
root.mainloop()
При нажатии любой клавиши или клике мыши текст метки обновляется. События можно привязывать к любым виджетам.
Использование фотографий с Pillow (JPG, advanced)
Библиотека Pillow позволяет работать с JPG и другими форматами.
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
root.title("Pillow JPG")
img = Image.open("photo.jpg")
photo = ImageTk.PhotoImage(img)
label = tk.Label(root, image=photo)
label.pack()
root.mainloop()
Окно отображает фотографию в формате JPG. Необходимо предварительно установить Pillow (pip install Pillow).
Создание скроллируемого текста (ScrolledText)
Виджет с полосой прокрутки для больших текстов.
import tkinter as tk
from tkinter import scrolledtext
root = tk.Tk()
root.title("Текстовый редактор")
text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=40, height=10)
text_area.pack(fill="both", expand=True)
root.mainloop()
Открывается окно с многострочным текстовым полем и полосой прокрутки. Поддерживает вставку, выделение, форматирование.
Сохранение состояния приложения с помощью pickle
Пример сохранения текста из Entry в файл и загрузка при запуске.
import tkinter as tk
import pickle
import os
root = tk.Tk()
root.title("Сохранение состояния")
entry = tk.Entry(root)
entry.pack(padx=10, pady=10)
FILE_NAME = "data.pkl"
if os.path.exists(FILE_NAME):
with open(FILE_NAME, "rb") as f:
saved_text = pickle.load(f)
entry.insert(0, saved_text)
def save():
with open(FILE_NAME, "wb") as f:
pickle.dump(entry.get(), f)
label_status.config(text="Сохранено")
btn_save = tk.Button(root, text="Сохранить", command=save)
btn_save.pack()
label_status = tk.Label(root, text="")
label_status.pack()
root.mainloop()
При повторном запуске поле ввода содержит ранее введённый текст. Подходит для хранения настроек.
Анимация на after() и Canvas
Простая анимация перемещения круга.
import tkinter as tk
root = tk.Tk()
root.title("Анимация")
canvas = tk.Canvas(root, width=400, height=300, bg="white")
canvas.pack()
ball = canvas.create_oval(10, 10, 50, 50, fill="green")
dx, dy = 3, 2
def animate():
global dx, dy
canvas.move(ball, dx, dy)
pos = canvas.coords(ball)
if pos[2] >= 400 or pos[0] <= 0:
dx = -dx
if pos[3] >= 300 or pos[1] <= 0:
dy = -dy
root.after(30, animate)
animate()
root.mainloop()
Зелёный круг движется по окну, отскакивая от границ. Анимация основана на рекурсивном вызове after().