Создаем простой калькулятор в PyQt5

Калькуляторы – это одни из самых простых приложений, которые идут по умолчанию в каждой версии Windows. Со временем их расширял для поддержки научных и программных режимов, однако на фундаментальном уровне все они одинаковы.

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

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Пока это реализовано под Qt, вы можете легко конвертировать логику в работу для работы в оборудовании при помощи MicroPython или Raspberry Pi.

Создаем простой калькулятор в PyQt5

Исходный код

Скачать: https://github.com/mfitzp/15-minute-apps/tree/master/calculator
Полный исходный код Calculon доступен в пятнадцатиминутном репозитории. Вы можете скачать\клонировать его для получения рабочей копии:

Затем установить все необходимые зависимости при помощи:

После этого вы можете запустить калькулятор при помощи:

Ознакомьтесь с тем, как работает код в путеводителе.

Пользовательский интерфейс

Пользовательский интерфейс «Calculon» был создан в Qt Designer. Макет mainwindow использует QVBoxLayout с LCD экраном добавленным вверху и QGridLayout внизу.

Мы используем макет сетки, который используется для позиционирования всех кнопок калькулятора. Каждая кнопка занимает одно место в сетке, кроме знака равно, который занимает две клетки.

Создаем простой калькулятор в PyQt5

Каждая кнопка определена сочетанием горячих клавиш на клавиатуре для вызова сигнала .pressed. Например, 3 для кнопки 3. Действия в каждой кнопке определены кодом и связаны с этим сигналом.

Если вы хотите поправить дизайн в Qt Designer, не забудьте пересоздать файл MainWindow.py используя pyuic5 mainwindow.ui -o MainWindow.py.

Действия

Чтобы кнопки делали что-либо, нам нужно связать их с определенными обработчиками. Определенные связи показаны сначала внизу, затем подробно описанные обработчики.

Сначала мы подключаем цифровые кнопки к своим обработчикам. В Qt Designer мы назвали все кнопки, используя стандартный формат, так, в pushButton_nX литера Х является числом. Это упрощает их итерацию и подключение.

Мы используем оберточную функцию на сигнале для передачи дополнительной информации с каждым запуском. В нашем случае, введенное число от 0 до 9 используя функцию range.

Следующий блок сигналов, который мы подключим, нужен для стандартных операций подсчетов, включая суммирование, умножение, вычитание и деление. Опять же, они подключены к общему слоту и состоят из завернутого сигнала для передачи операции (определенный тип операторов Python).

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

Теперь кнопки и действия связаны, и мы можем реализовать логику в методах слота для обработки этих действий.

Операции

Операции калькулятора обрабатываются с использованием трех компонентов – стек, состояние и нынешняя операция.

Стек

Стек – это небольшое хранилище памяти для двух элементов максимум, который содержит числовые значения, которые мы хотим посчитать. Когда пользователь начинает вводить новое число, оно попадает в конец стека (который является началом при условии, если стек является пустым). Каждое введенное число умножает текущий стек на 10 и добавляет введенное значение.

Таким образом мы заполняем числа в правой части ,как и ожидалось. Иными словами:

Создаем простой калькулятор в PyQt5

Состояние

Флажок состояние (state) нужен для переключения между готовыми и введенными состояниями. Это также влияет на поведение при вводе чисел. В режиме готовности, введенное значение настраивается напрямую под стек и текущую позицию. В режиме ввода, указанном выше, используется логика shift+add.

Это необходимо, так что мы можем вводить числа над результатом подсчета, вместо того, чтобы получить новые добавленные в результаты предыдущего подсчета числа.

Вы увидите переключатели между состояниями READY и INPUT.

Текущая операция (current_op)

Переменная current_op содержит текущую активную операцию, которая будет задействована после того, как пользователь нажмет на кнопку уравнения. Если операция в данный момент прогрессирует, то мы сначала подсчитываем результат этой операции, выводим результат в стек и создаем новую.

Запуск новой операции также вводит 0 в стек, таким образом, увеличивая его длину до 2, затем переключает режим на INPUT. Таким образом, мы получаем гарантию того, что любое вводимое далее число будет начинаться с нуля.

Обработчик операции для подсчета процентов работает немного иначе. Вместо этого, он управляет текущим содержимым стека напрямую. Вызов operation_pc берет последнее значение в стеке и делит его на 100.

Знак равно

Основа калькулятора – это обработчик, который действительно выполняет кое-какую математику. Все операции (за исключением процентов) обрабатываются обработчиком знака равно, который вызывается нажатием на клавишу знака равно, Enter или другой операционной клавиши.

Обработчик equals берет current_op и добавляет его к значениям в стеке (2 значения, распакованные при помощи *self.stack) для получения результата. Результат отправляется обратно в стек в качестве единственного значения, и мы переходим к состоянию READY. Ошибки (исключения, например, деление на ноль) учитываются, и уведомление об ошибке может быть отображено при необходимости.

Была также добавлена поддержка для повторяемых предыдущих операций при повторном нажатии знака равно. Это может быть реализовано при сохранении значения и оператора, когда задействуется знак равно. Повторное использование возможно при условии, что знак равно введен еще раз без выхода из режима READY (без пользовательского введения).

Память

Наконец, мы можем определить обработчики для действий памяти. Для «Calculon» мы подобрали только два действия с памятью – хранение и повторный вызов. Хранение берет текущее значение с LCD дисплея и копирует его в self.memory. Повторный вызов берет значение из self.memory и помещает его в конечное место нашего стека.

Настроив режим на INPUT и обновив дисплей мы сможем действовать также, как при введении чисел от руки.

Дальнейшие идеи

Текущая версия «Calculon» поддерживает только базовые математические операции. Большая часть пользовательских калькуляторов также включает в себя поддержку научных (в некоторых случаях и программных) режимов, которые добавляют ряд альтернативных функций.

В «Calculon» вы можете определить эти дополнительные операции как набор лямбд, каждая из которых принимает два параметра для обработки.

Переключение режимов (например, между нормальным и научным) в калькуляторе может быть для нынешнего макета, базирующегося на QMainWindow. Вы можете перебрать макет калькулятора в QtDesigner, чтобы иметь возможность использовать базу QWidget. Каждое представление – это обычный виджет, и переключение между режимами может быть выполнено смены вашего центрального виджета в рабочем окне.