Практические примеры Tkinter: от окон до сложных виджетов и анимации

Раздел: GUI -> 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() при закрытии окна, программа может упасть. В данном примере это не критично, но для сложных приложений лучше отменить таймер.

- Python tkinter таблицы (создание таблиц в tkinter python)
- Python text get (метод get() для текста в python (например, из tkinter))
- Import tkinter as tk python (импорт tkinter как tk в python)

Расширенные примеры программ на 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().

Примеры программ на Tkinter - comments

En
Python tkinter programs (python)