Гид по технологиям

Калькулятор на Python с GUI (Tkinter)

7 min read Python Обновлено 19 Dec 2025
Калькулятор на Python (Tkinter) — пошагово
Калькулятор на Python (Tkinter) — пошагово

Человек держит смартфон с открытым приложением калькулятора

Python предоставляет множество инструментов для анализа данных, веб- и Android-разработки. Один из полезных инструментов для создания настольных приложений — библиотека Tkinter для графического интерфейса. Tkinter содержит виджеты для создания удобных интерфейсов. Эта библиотека проста в использовании, лёгкая и быстрая. Устанавливать Tkinter вручную обычно не требуется: он входит в стандартную поставку Python.

Важно знать базовые понятия пакета Tkinter перед тем, как продолжить практическую часть.

Базовая настройка приложения

Импорт модуля

Первый шаг — импорт модуля и создание главного объекта приложения. В исходном примере используется сокращённое имя модуля.

        `import tkinter as ttk `
    

(Примечание: в реальных проектах чаще используют import tkinter as tk и from tkinter import ttk; в статье используется сокращение в варианте исходника.)

Создание окна

Чтобы создать окно, нужно создать объект окна и задать заголовок и геометрию (ширина×высота):

        `win = ttk.Tk()  
win.title('Simple Calculator')  
win.geometry('500x500')  
`
    

Gеометрия определяет размеры окна в пикселях.

Запуск главного цикла

Метод mainloop() запускает цикл обработки событий. Окно будет активно, пока пользователь не закроет его вручную.

        `win.mainloop()   
`
    

Создание интерфейса

Tkinter содержит множество виджетов. Для калькулятора в примере используются кнопки и поле ввода (Entry). Набор кнопок — цифры 0–9, арифметические операторы (+, -, ×, /), а также кнопки для очистки, удаления и вычисления.

Ниже — пример создания кнопок и их размещения с помощью grid:

        `oneButton = ttk.Button(win, text="1", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(1))  
oneButton.grid(row=2, column=0,padx=2, pady=3)  
twoButton = ttk.Button(win, text="2", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(2))  
twoButton.grid(row=2, column=1, padx=2, pady=3)  
threeButton = ttk.Button(win, text="3", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(3))  
threeButton.grid(row=2, column=2, padx=2, pady=3)  
plusButton = ttk.Button(win, text="+", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq("+"))  
plusButton.grid(row=2, column=3, padx=2, pady=3)  
  
# div 2  
fourButton = ttk.Button(win, text="4", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(4))  
fourButton.grid(row=3, column=0, padx=2, pady=3)  
fiveButton = ttk.Button(win, text="5", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(5))  
fiveButton.grid(row=3, column=1, padx=2, pady=3)  
sixButton = ttk.Button(win, text="6", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(6))  
sixButton.grid(row=3, column=2, padx=2, pady=3)  
minusButton = ttk.Button(win, text="-", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq("-"))  
minusButton.grid(row=3, column=3, padx=2, pady=3)  
# div 3  
sevenButton = ttk.Button(win, text="7", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(7))  
sevenButton.grid(row=4, column=0, padx=2, pady=3)  
eightButton = ttk.Button(win, text="8", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(8))  
eightButton.grid(row=4, column=1, padx=2, pady=3)  
nineButton = ttk.Button(win, text="9", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(9))  
nineButton.grid(row=4, column=2, padx=2, pady=3)  
muxButton = ttk.Button(win, text="x", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq("*"))  
muxButton.grid(row=4, column=3, padx=2, pady=3)  
#div 4  
zeroButton = ttk.Button(win, text="0", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq(0))  
zeroButton.grid(row=5, column=0, padx=2, pady=3)  
  
clearButton = ttk.Button(win, text="clr", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=clearInput)  
clearButton.grid(row=5, column=1, padx=2, pady=3)  
calculateButton = ttk.Button(win, text="cal", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=calculateEq)  
calculateButton.grid(row=5, column=2, padx=2, pady=3)  
divideButton = ttk.Button(win, text="/", pady=10, padx=20, font = "Serif 15",bg = "black", fg = "white", command=lambda: addToEq("/"))  
divideButton.grid(row=5, column=3, padx=2, pady=3)  
`
    

Параметры кнопки включают объект окна, выводимый текст, стиль шрифта и обработчик события (command). Для ровного расположения используйте менеджер геометрии grid и задавайте row и column.

Пример поля ввода и привязки переменной:

        `numericEq = ttk.StringVar()  
dataField = ttk.Entry(win, textvariable=numericEq, font="Serif 15")  
dataField.grid(row=0,columnspan=3, ipadx=80, ipady=15)  
`
    

Виджет Entry отображает текстовое поле. Аргумент textvariable связывает поле с переменной типа StringVar, позволяя программно считывать и записывать текст.

Простой калькулятор, созданный с помощью Python Tkinter

Добавление логики кнопкам

Кнопки реагируют через аргумент command. В примере используются лямбда-функции, чтобы передать значение в обработчик.

Цифровые и арифметические кнопки

Кнопки с цифрами и операторами вызывают функцию addToEq(). Она принимает значение кнопки и добавляет его к текущему выражению. В коде исходника представлен упрощённый пример:

        `def addToEq(x):  
   calcValue = calcValue + str(x)  
   numericEq.set(calcValue)  
`
    

Важно: calcValue должна быть доступна в области видимости функции (например, как глобальная переменная или атрибут объекта). Без этого код вызовет ошибку UnboundLocalError.

Кнопка вычисления

Кнопка “cal” вычисляет выражение, переданное в calcValue. В примере используется функция eval() для исполнения арифметики:

        `def calculateEq():  
   total = str(eval(calcValue))  
   numericEq.set(total)  
`
    

Мера предосторожности: eval() выполняет любой код, который в ней передан. В пользовательских приложениях используйте безопасный парсер выражений или фильтруйте ввод.

Кнопка очистки

Кнопка очистки ставит calcValue в пустую строку и обновляет поле ввода:

        `def clearInput():  
  calcValue = ""  
  numericEq.set("")  
`
    

Результат вычисления в приложении-калькуляторе на Tkinter

Запуск и отладка

Сохраните файл, например calculator.py, и запустите: python calculator.py. При возникновении ошибок проверьте области видимости переменных, корректность имён функций и соответствие отступов.

Важно: если в проекте используются глобальные переменные (calcValue), объявите их как global внутри функций для записи, или лучше — инкапсулируйте логику в класс.

Полезные рекомендации и расширения

  • Используйте tk.StringVar() только для связи с Entry. Для внутренней логики работайте со строками и числовыми типами.
  • Для безопасных вычислений замените eval() на ast.literal_eval для простых типов или на специализированный парсер выражений.
  • Рассмотрите клавиатурные привязки (bind) для ввода цифр с клавиатуры.
  • Добавьте форматирование результата (например, округление float до 6 знаков).

Важно: для коммерческих приложений убедитесь, что ввод не может привести к выполнению нежелательного кода.

Типичные ошибки и как их исправить

  • UnboundLocalError при обновлении calcValue: объявите переменную глобальной или храните в self.
  • Деление на ноль: добавьте проверку перед вычислением.
  • Неправильный формат числа: обработайте пробелы и локальные разделители (запятая/точка).
  • Низкая отзывчивость интерфейса: избегайте тяжёлых вычислений в основном потоке; используйте отдельный поток/процесс для длительных задач.

Чек-лист разработчика

  • Создать главное окно и настроить geometry и title
  • Создать StringVar для поля ввода
  • Реализовать кнопки 0–9 и операторы
  • Реализовать функции addToEq, calculateEq, clearInput
  • Обработать ошибки деления на ноль и неверного ввода
  • Провести ручное тестирование клавиатуры и мыши

Критерии приёмки

  • Приложение запускается без ошибок командой python file_name.py
  • Кнопки добавляют соответствующие символы в поле ввода
  • Нажатие “cal” корректно вычисляет выражение
  • Кнопка очистки полностью сбрасывает поле ввода
  • Обработка деления на ноль и других ошибок не приводит к падению приложения

Шаблон: минимальная структура (рекомендация)

  1. Импортировать модули
  2. Создать класс CalculatorApp
  3. В init создать окно, переменные, виджеты и бинды
  4. Написать методы addToEq, calculateEq, clearInput
  5. Вызвать mainloop()

Пример структуры:

class CalculatorApp:
    def __init__(self):
        # инициализация
        pass
    def addToEq(self, x):
        pass
    def calculateEq(self):
        pass
    def clearInput(self):
        pass

if __name__ == '__main__':
    app = CalculatorApp()
    app.mainloop()

Когда подход не подходит (контр-примеры)

  • Нужен мощный научный калькулятор с выражениями, функциями и историей вычислений — лучше использовать специализированную библиотеку или фреймворк.
  • Требуется сложная проверка пользовательского ввода и безопасность — избегайте eval(), используйте парсер выражений.
  • Приложение должно масштабироваться и иметь сложный интерфейс — рассмотрите Qt (PyQt/PySide) или web‑интерфейс.

Краткая памятка (cheat sheet)

  • grid(row=i, column=j) — позиционирование
  • Entry(textvariable=var) — двусторонняя связь
  • Button(command=handler) — обработчик клика
  • ttk.StringVar() — связанная переменная
  • eval() — быстро, но небезопасно

Глоссарий (1 строка)

  • Tkinter — стандартная библиотека Python для создания графического интерфейса.

Риски и меры

  • Риск: выполнение вредного кода через eval(). Мера: фильтрация ввода или использование безопасного парсера.
  • Риск: некорректная локализация десятичных разделителей. Мера: нормализовать ввод (заменять “,” на “.”).

Короткое резюме

Вы создали базовый графический калькулятор на Tkinter: настроили окно, добавили виджеты и реализовали простую логику. Следующие шаги — улучшить обработку ошибок, заменить eval() на безопасный парсер и добавить дополнительные функции (клавиатурные бинды, история, форматирование результата).

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

OctoPrint на Android: установить и настроить
3D-печать

OctoPrint на Android: установить и настроить

LAV Filters: установка и настройка
Мультимедиа

LAV Filters: установка и настройка

Бесплатная лицензия Windows 10 после смены оборудования
Windows

Бесплатная лицензия Windows 10 после смены оборудования

Редактирование скриншотов на Mac с Preview
macOS

Редактирование скриншотов на Mac с Preview

Как разблокировать человека в Facebook — пошагово
Социальные сети

Как разблокировать человека в Facebook — пошагово

Как перейти на цифровые заметки
Продуктивность

Как перейти на цифровые заметки