Пишем строковый калькулятор на Python для Linux
Мини-проект для знакомства с GNOME Builder и Cambalache.


Иллюстрация: Оля Ежак для Skillbox Media
Эксперты по информационной безопасности из немецкого подразделения ESET порекомендовали пользователям Windows 10 перейти на Windows 11, поскольку в октябре 2025 года заканчивается поддержка. Однако системные требования Windows 11 не позволяют установить её на все старые компьютеры, поэтому в качестве альтернативы можно использовать Linux.
Если вы начинающий Python-разработчик и ищете повод попробовать Linux, сейчас самый подходящий момент. В этой статье мы покажем, как сделать строковый калькулятор для математических вычислений. Он поможет вам познакомиться с Linux и новыми инструментами разработки. Кто знает, возможно, именно после этого в мире станет на одного линуксоида больше.
Содержание
- Готовим необходимые инструменты
- Создаём проект в GNOME Builder
- Подключаем библиотеку StringCalculator
- Создаём пользовательский интерфейс в Cambalache
- Запускаем калькулятор
Шаг 0: готовим необходимые инструменты
Прежде всего мы рекомендуем ознакомиться с основами операционной системы Linux, выбрать подходящий дистрибутив, установить его и настроить Python. Наши статьи помогут вам быстро во всём разобраться.
- Что такое Linux: гайд по самой свободной операционной системе
- Лучшие дистрибутивы Linux: какую версию операционной системы выбрать
- Как запустить Python офлайн и онлайн: руководство для новичка
Для разработки на Python мы будем использовать два мощных инструмента из экосистемы GNOME: Builder — современную интегрированную среду разработки (IDE) для написания кода и Cambalache — удобный визуальный редактор для создания графического интерфейса калькулятора на GTK.
Оба инструмента доступны в магазине приложений Flathub, который обеспечивает безопасную установку программ в изолированной среде. Перейдите на страницы Builder и Cambalache и нажмите кнопку Установить. Система автоматически начнёт загрузку через менеджер пакетов — вам необходимо будет только подтвердить установку, когда появится запрос.
Если автоматическая установка не удалась, скопируйте команду загрузки со страницы приложения и вставить её в терминал. Также проверьте поддержку Flatpak в вашем дистрибутиве — если её нет, выполните настройку вручную.
Общий план работы таков: мы создадим проект в GNOME Builder, добавим Python-библиотеку StringCalculator для обработки арифметических выражений, разработаем пользовательский интерфейс с помощью Cambalache и протестируем работу нашего калькулятора. Приступаем 👇
Шаг 1. Создаём проект в GNOME Builder
Запустите через меню приложений GNOME Builder, нажмите кнопку Создать новый проект и в открывшемся окне заполните следующие поля:
- Название проекта: calculator.
- Идентификатор приложения (Application ID): можно оставить пустым.
- Язык программирования: выберите Python.
- Шаблон: установите как Приложение среды GNOME.
- Местоположение проекта: выберите папку на компьютере, где будут храниться файлы калькулятора.
После заполнения всех полей нажмите кнопку Создать проект.

В левой части окна Builder отображается структура файлов проекта:
- Папка data: содержит файл описания нашего калькулятора, значок запуска, иконки и другие ресурсы.
- Папка po: хранит файлы переводов приложения на различные языки.
- Каталог src: здесь находятся все исходные коды программы.
По умолчанию GNOME Builder создаёт изолированные сборки приложений через Flatpak. Приложения работают в собственных контейнерах и полностью независимы от основной системы. Для управления изоляцией используется манифест Flatpak (файл .json) — конфигурационный файл, который определяет все необходимые компоненты приложения: системные библиотеки, модули Python и прочие зависимости. Этот манифест нам предстоит заполнить — вы найдёте его как файл org.gnome.Example.json.

Шаг 2. Добавляем библиотеку StringCalculator
При создании строкового калькулятора важно обеспечить корректный разбор арифметических выражений, вводимых пользователем. Программа должна правильно определять порядок выполнения операций с учётом скобок. Для этого необходим алгоритм, который может посимвольно анализировать строку, распознавать числа, операторы и скобки. Без такого алгоритма невозможно построить корректную последовательность вычислений.
Например, для выражения 2 + (3 × 4) калькулятор должен сначала вычислить произведение в скобках (3 × 4 = 12), а затем прибавить к результату 2, чтобы в итоге получить 14. К счастью, нам не придётся выполнять эту задачу, поскольку Python-библиотека StringCalculator сделает всю работу за нас.
Чтобы добавить StringCalculator в калькулятор, откройте файл манифеста (org.gnome.Example.json) и вставьте следующий код в начало раздела modules. Builder установит библиотеку и настроит все зависимости:
{
"name": "StringCalculator",
"buildsystem": "simple",
"build-commands": [
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"StringCalculator\" --no-build-isolation"
],
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/62/86/50ac01ebf63c8f3c3ddd23eec68493765c1f6369ed1db4df5aa6e0a24d4a/StringCalculator-0.0.4.tar.gz",
"sha256": "2c56fd149285be8a616a281579ab96f80be3bc26b253e9d32afe57322a02a2f3"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/81/1b/071431e8a00545d344587a7e639b475f13f3008f05e6268d246b7482cd80/StringCalculator-0.0.4-py3-none-any.whl",
"sha256": "7844529b2b7a55e4384e30faaca91e3d5a2bf24d537154742f6f38eea6d9e76b"
}
]
}
После этого в манифесте должно следовать описание модуля приложения. Если сейчас запустить проект с помощью кнопки в верхней панели, на экране появится стандартное приветствие Hello, World!. У нас не появилось ошибок при запуске, и это означает, что модуль StringCalculator установлен корректно.

Шаг 3. Строим пользовательский интерфейс
В папке src найдите файл window.ui, который содержит XML-разметку интерфейса калькулятора. Щёлкните правой кнопкой мыши по файлу и выберите: Открыть с помощью → Внешняя программа → Cambalache.
При первом открытии интерфейс будет пустым, поскольку Cambalache использует формат файлов с расширением .cmb. Чтобы исправить это, нужно экспортировать файл: нажмите на кнопку с тремя точками в правом верхнем углу, выберите Export all UI и закройте Cambalache. После этого Builder покажет сообщение: Файл на диске был изменён. Нажмите кнопку Отказаться от изменений и перезагрузить, затем перезагрузите проект. В папке src появится новый файл window.cmb — его и открываем в Cambalache.

Сначала уберите метку с надписью Hello, World! — найдите элемент GtkLabel content label в дереве проекта и удалите его. Теперь добавьте контейнер GtkBox на его место. Для этого откройте меню Layout над макетом, выберите GtkBox, наведите курсор на нужное место в макете, вызовите контекстное меню правой кнопкой мыши и выберите пункт Add object here.

Удалите третью секцию, нажав Ctrl + Del. После этого измените ориентацию контейнера с горизонтальной на вертикальную — в правой панели найдите раздел orientation и выберите значение vertical из выпадающего списка.

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

Продолжим работу с верхней секцией калькулятора. В левую часть добавьте поле для ввода арифметических выражений — откройте меню Control над макетом и выберите GtkEntry. В правую часть поместите кнопку для вычисления результата — снова откройте меню Control и выберите GtkButton.

В нижнюю часть главного контейнера добавьте поле для отображения результата — откройте меню Display и выберите виджет GtkTextView.
Интерфейс нашего калькулятора почти готов. Осталось только вернуться к кнопке и в правой панели в разделе label добавить надпись CALCULATE.

Чтобы обращаться к элементам интерфейса в программе, нам необходимо добавить идентификаторы для каждого виджета. Для этого выделите нужный виджет и в правой панели заполните поле Object Id. Для GtkEntry укажите entry, для GtkButton — calculate_button, а для GtkTextView — text_view.
Чтобы сохранить созданный интерфейс в файле window.ui, нажмите на кнопку с тремя точками в правом верхнем углу, выберите Export all UI, а затем в Builder нажмите на кнопку Отказаться от изменений и перезагрузить.
Шаг 4. Запускаем калькулятор
В Builder перейдите в папку src и откройте файл window.py — в нём мы напишем основной код калькулятора. Для начала добавим в секцию импортов класс SolveMathProblem из Python-библиотеки StringCalculator:
from StringCalculator import SolveMathProblem
Теперь добавим объявления виджетов интерфейса калькулятора и после шаблонной строки label = Gtk.Template.Child() вставим следующий код:
calculate_button = Gtk.Template.Child()
entry = Gtk.Template.Child()
text_view = Gtk.Template.Child()
Далее в Python-функции __init__ добавим обработчик события нажатия кнопки, который будет вычислять результат. Для этого свяжем сигнал clicked кнопки с функцией-обработчиком on_calculate_clicked: self.calculate_button.connect ("clicked", self.on_calculate_clicked).
Также в функции __init__ создадим переменную text — пустую строку для хранения истории вычислений. В неё будут добавляться все введённые выражения и их результаты, которые затем отобразятся в поле text_view.
В итоге функция инициализации калькулятора должна выглядеть так:
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.text = ""
self.calculate_button.connect("clicked", self.on_calculate_clicked)
Нам осталось добавить в калькулятор функцию-обработчик:
def on_calculate_clicked(self, widget):
# Проверяем содержимое поля ввода
if len(self.entry.get_text().strip()) == 0:
# Если поле пустое, выводим сообщение об ошибке
self.text_view.get_buffer().set_text(_("Enter an arithmetic expression"))
self.entry.grab_focus() # Возвращаем фокус на поле ввода
return
# Получаем введённое пользователем арифметическое выражение
problem = self.entry.get_text()
try:
# Пытаемся вычислить результат, передавая выражение в функцию SolveMathProblem
result = SolveMathProblem(problem)
except ZeroDivisionError:
# Выводим ошибку, если кто-то попытается поделить на ноль
self.text_view.get_buffer().set_text(_("Division by zero!"))
self.entry.grab_focus() # Возвращаем фокус на поле ввода
return
except Exception as e:
# Обрабатываем другие типы ошибок
self.text_view.get_buffer().set_text(_("Invalid expression"))
self.entry.grab_focus() # Возвращаем фокус на поле ввода
return
# Формируем строку с результатом, чтобы добавить её к истории вычислений
self.text += problem + "=" + str(result) + "\n"
# Обновляем текстовое поле с результатом
self.text_view.get_buffer().set_text(self.text)
Наш калькулятор на Python готов к использованию! Запустите проект с помощью кнопки в верхней панели GNOME Builder и протестируйте его работу. Например, введите 2 + 2 × 2 и убедитесь, что калькулятор правильно применяет порядок операций, выдавая результат 6. Также попробуйте разделить число на ноль или нажать кнопку при пустой строке ввода.


Что дальше
Калькулятор уже работает, но его можно улучшить. Вот несколько идей:
- Добавьте боковые отступы для главного контейнера GtkBox, чтобы интерфейс стал более аккуратным.
- Сделайте кнопку очистки для поля ввода выражений калькулятора.
- Привяжите функцию on_calculate_clicked к клавише Enter для быстрого получения результата без мыши.
- Попробуйте использовать функцию re.sub() из модуля re для удаления лишних пробелов в выражении перед обработкой. Подробнее об этом можно прочитать в статье про регулярные выражения в Python.
Вот несколько материалов, которые помогут вам в доработке калькулятора:
- Документация GTK 4 — руководство по созданию интерфейсов.
- Учебник по Python GTK — пошаговые инструкции с примерами кода.
- GNOME Discourse — форум для обсуждения и обмена опытом.
- Документация Cambalache и GNOME Builder — руководства к нашим инструментам для проектирования и разработки GTK-приложений.
Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!