Создание калькулятора на Python с Qt: пошаговое руководство

0
15

Памятка по созданию калькулятора на Python Qt

  1. Установите PyQt5 или PySide6 через pip.
  2. Создайте главное окно на основе QMainWindow или QWidget.
  3. Разместите QLineEdit для дисплея в верхней части.
  4. Создайте сетку кнопок с помощью QGridLayout.
  5. Определите переменные для хранения текущего числа, операции и флага нового ввода.
  6. Напишите обработчики для цифр (0-9) и десятичной точки.
  7. Реализуйте обработчики для операций (+, -, *, /).
  8. Реализуйте обработчик для кнопки ‘=’ с проверкой деления на ноль.
  9. Добавьте кнопку ‘C’ для сброса состояния.
  10. Добавьте кнопку ‘±’ для смены знака числа.
  11. Протестируйте все комбинации операций.
  12. Настройте стили через QSS для улучшения интерфейса.

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

Building a simple calculator with - изображение номер один
Building a simple calculator with — изображение номер один

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

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

Создаем простой калькулятор в - изображение номер два
Создаем простой калькулятор в — изображение номер два

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

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

Стек

Basic calculator - изображение номер три
Basic calculator — изображение номер три

def input_number(self, v): if == READY: = INPUT [-1] = v else: [-1] = [-1] * 10 + v ()

Таблица №1

1
2
3
4
5
6
7
8
def input_number(self, v):
    if self.state == READY:
        self.state = INPUT
        self.stack[1] = v
    else:
        self.stack[1] = self.stack[1] * 10 + v
 
    self.display()

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

Py - изображение номер четыре
Py — изображение номер четыре

Состояние

Простейший калькулятор на языке программирования - изображение номер пять
Простейший калькулятор на языке программирования — изображение номер пять

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

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

Таблица №2

1
2
3
4
5
6
7
8
def input_number(self, v):
    if self.state == READY:
        self.state = INPUT
        self.stack[1] = v
    else:
        self.stack[1] = self.stack[1] * 10 + v
 
    self.display()

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

wxpython - изображение номер шесть
wxpython — изображение номер шесть

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

def operation(self, op): if self.current_op: # Завершение текущей операции () (0) = INPUT self.current_op = op

Таблица №3

1
2
3
4
5
6
7
def operation(self, op):
    if self.current_op:  # Завершение текущей операции
        self.equals()
 
    self.stack.append(0)
    self.state = INPUT
    self.current_op = op

Таблица №4

1
2
3
4
def operation_pc(self):
    self.state = INPUT
    self.stack[1] *= 0.01
    self.display()

Память

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

ЧИТАТЬ ТАКЖЕ:  Что такое Lambda функция в Python: определение, синтаксис и примеры использования

def memory_store(self): = () def memory_recall(self): = INPUT [-1] = ()

Таблица №5

1
2
3
4
5
6
7
def memory_store(self):
    self.memory = self.lcdNumber.value()
 
def memory_recall(self):
    self.state = INPUT
    self.stack[1] = self.memory
    self.display()

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

Действия

Build a calculator with - изображение номер восемь
Build a calculator with — изображение номер восемь

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

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

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

Таблица №6

1
2
for n in range(0, 10):
    getattr(self, ‘pushButton_n%s’ % n).pressed.connect(lambda v=n: self.input_number(v))

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

self.pushButton_add.(lambda: ()) self.pushButton_sub.(lambda: ()) self.pushButton_mul.(lambda: ()) self.pushButton_div.(lambda: ()) # для Python2.7

Таблица №7

1
2
3
4
self.pushButton_add.pressed.connect(lambda: self.operation(operator.add))
self.pushButton_sub.pressed.connect(lambda: self.operation(operator.sub))
self.pushButton_mul.pressed.connect(lambda: self.operation(operator.mul))
self.pushButton_div.pressed.connect(lambda: self.operation(operator.truediv))  # для Python2.7

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

self.pushButton_pc.(self.operation_pc) self.pushButton_eq.() self.pushButton_ac.() self.pushButton_m.(self.memory_store) self.pushButton_mr.(self.memory_recall)

Таблица №8

1
2
3
4
5
6
7
self.pushButton_pc.pressed.connect(self.operation_pc)
self.pushButton_eq.pressed.connect(self.equals)
 
self.pushButton_ac.pressed.connect(self.reset)
 
self.pushButton_m.pressed.connect(self.memory_store)
self.pushButton_mr.pressed.connect(self.memory_recall)

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

Операции

Как сделать калькулятор в питоне - изображение номер девять
Как сделать калькулятор в питоне — изображение номер девять

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

Знак равно

Калькулятор на питоне - изображение номер десять
Калькулятор на питоне — изображение номер десять

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

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

def equals(self): # Поддержка, позволяющая «=» повторять предыдущую операцию # если новые данные небыли введены. if == READY and self.last_operation: s, self.current_op = self.last_operation (s) if self.current_op: self.last_operation = [-1], self.current_op try: = [self.current_op(*)] except Exception: (‘Err’) = else: self.current_op = None = READY ()

Таблица №9

ЧИТАТЬ ТАКЖЕ:  Увеличение размера шрифта в IDLE Python: настройки, подсветка и табуляция
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def equals(self):
    # Поддержка, позволяющая «=» повторять предыдущую операцию
    # если новые данные небыли введены.
    if self.state == READY and self.last_operation:
        s, self.current_op = self.last_operation
        self.stack.append(s)
 
    if self.current_op:
        self.last_operation = self.stack[1], self.current_op
 
        try:
            self.stack = [self.current_op(*self.stack)]
        except Exception:
            self.lcdNumber.display(‘Err’)
            self.stack = [0]
        else:
            self.current_op = None
            self.state = READY
            self.display()

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

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

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

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

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

Как сделать - изображение номер одиннадцать
Как сделать — изображение номер одиннадцать

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2026 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Часто задаваемые вопросы по созданию калькулятора на Python Qt

Вопрос: Какой модуль Qt лучше использовать для калькулятора?
Ответ: Рекомендуется PyQt5 или PySide6, так как они предоставляют все необходимые виджеты для интерфейса.

Вопрос: Как обрабатывать нажатие кнопок в калькуляторе?
Ответ: Используйте сигнал clicked() для каждой кнопки и подключайте его к соответствующему слоту-обработчику.

Вопрос: Как реализовать отображение ввода и результата?
Ответ: Используйте QLineEdit или QLabel для отображения текста, обновляя его через setText().

Вопрос: Как хранить текущее значение и операцию?
Ответ: Создайте переменные состояния (например, current_value, current_op) для хранения чисел и выбранной операции.

Вопрос: Как обработать нажатие кнопки ‘=’?
Ответ: В слоте для ‘=’ выполните вычисление на основе сохраненной операции и текущего значения, затем обновите дисплей.

Вопрос: Как добавить поддержку десятичных чисел?
Ответ: Проверяйте, содержит ли текущее число точку, и добавляйте её только если её нет.

Вопрос: Как реализовать кнопку очистки (C)?
Ответ: В слоте для ‘C’ сбросьте все переменные состояния и очистите дисплей.

Вопрос: Как обработать деление на ноль?
Ответ: Перед выполнением деления проверяйте, не равен ли делитель нулю, и выводите сообщение об ошибке.

Вопрос: Как добавить кнопку ‘±’ для смены знака?
Ответ: Умножьте текущее значение на -1 и обновите дисплей.

Вопрос: Как улучшить внешний вид калькулятора?
Ответ: Используйте QSS (Qt Style Sheets) для настройки цветов, шрифтов и отступов кнопок.