QT realizes the function of simple calculator

Design sketch:

1. Define a class name expr, select dialog as the base class, or select the default class name and base class

Click next to finish. The project is created.
2. Double click the. ui file in the interface file under the project file to enter the interface layout

3. Add buttons according to the functions you need to implement and make corresponding layout

4. After the layout is completed, the corresponding button function and slot function are added
There are two ways to add slot functions:

The first one: use connect (which button in the interface, what kind of signal is sent out, who and which function is executed)
Second: right click the button directly, turn to the slot, select the corresponding signal and confirm, then the slot function is bound.

5. code segment
Add a custom header file floatnumber.h to the header file

Code content:

#ifndef FLOATNUMBER_H
#define FLOATNUMBER_H

#endif
#include <iostream>
using namespace std;

struct node{
    int flag;
    union{
        double a;
        char  op;
    }num;
};

Code in expr.cpp:

#include "expr.h"
#include "ui_expr.h"
#include "floatnumber.h"
#include <QPushButton>
#include <QTextEdit>
#include <QString>
#include <QDialog>
#include <QDebug>

typedef struct node _tNode;
#define NUM_OF_NUMBER 20
#define KIND_NUMBER  0
#define KIND_OPERATOR 1

expr::expr(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::expr)
{
    ui->setupUi(this);
    this->tmp = "";
}

expr::~expr()
{
    delete ui;
}

void expr::on_btn_0_clicked()
{
    if(this->tmp != " ")
    {
        this->tmp += this->ui->btn_0->text();
        this->ui->lbl_display->setText(this->tmp);
    }
    }

void expr::on_btn_1_clicked()
{
     this->tmp += this->ui->btn_1->text();
      this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_2_clicked()
{
     this->tmp += this->ui->btn_2->text();
    this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_3_clicked()
{
     this->tmp += this->ui->btn_3->text();
     this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_4_clicked()
{
    this->tmp += this->ui->btn_4->text();
    this->ui->lbl_display->setText(this->tmp);
}


void expr::on_btn_5_clicked()
{
    this->tmp += this->ui->btn_5->text();
    this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_6_clicked()
{
    this->tmp += this->ui->btn_6->text();
    this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_7_clicked()
{
    this->tmp += this->ui->btn_7->text();
    this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_8_clicked()
{
    this->tmp += this->ui->btn_8->text();
    this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_9_clicked()
{
    this->tmp += this->ui->btn_9->text();
    this->ui->lbl_display->setText(this->tmp);
}

void expr::on_btn_plus_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_plus->text();
        this->ui->lbl_display->setText(this->tmp);
    }
  }

void expr::on_btn_sub_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_sub->text();
        this->ui->lbl_display->setText(this->tmp);
       }
}

void expr::on_btn_mul_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_mul->text();
        this->ui->lbl_display->setText(this->tmp);
    }
}

void expr::on_btn_div_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_div->text();
        this->ui->lbl_display->setText(this->tmp);

    }
}

void expr::on_btn_equ_clicked()
{
    if(tmp != " ")
    {
           expr::calculate();
         this->ui->lbl_display->setText(this->tmp);
    }

}

void expr::on_btn_point_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_point->text();
        this->ui->lbl_display->setText(this->tmp);
    }
}

void expr::on_btn_left_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_left->text();
        this->ui->lbl_display->setText(this->tmp);
    }
}

void expr::on_btn_right_clicked()
{
    if(tmp != " ")
    {
        this->tmp += this->ui->btn_right->text();
        this->ui->lbl_display->setText(this->tmp);
      }
}

void expr::on_btn_delet_clicked()
{
    if(tmp != " ")
    {
        tmp = tmp.left(tmp.length()-1);
        this->ui->lbl_display->setText(this->tmp);
    }
}

void expr::on_btn_clear_clicked()
{
    if(tmp != " ")
    {
        tmp.clear();
        this->ui->lbl_display->clear();
        this->ui->lbl_display->setText("0");
    }
}



void expr::calculate()
{
    _tNode Node[NUM_OF_NUMBER];
    double num = 0;
    int   i = 0;                         //String position
    int num_of_point = 0;      //Number of digits after decimal point
    int num_or_op = 0;         //Floating point number and number of operators
    int isfloat = 0;                 //Decimal point
    int len = tmp.length();   //String length

    while(i < len)
    {
        if(tmp[i] >= '0' && tmp[i] <= '9')
        {
            if(!isfloat)   //Integral part
            {
                num = num*10 + (tmp[i].toLatin1()-'0');   //tmp[i].toLatin1() converts character I to ASCII
                ++i;
            }
            else   //Fractional part
            {
                double per = 1;
                for(int k = 0;k < num_of_point;k++)
                    per *= 0.1;
                num +=  (tmp[i].toLatin1()-'0') * per;
                num_of_point++;
                ++i;
            }
        }
        else if(tmp[i] == '.')   //Read to decimal point
        {
            isfloat = 1;
            num_of_point = 1;
           ++i;
        }
        else  //Read operator
        {
            if(num) //After reading the operator, it indicates that a complete number has been input, and the number, decimal point, etc. should be cleared
            {
                Node[num_or_op].flag = KIND_NUMBER;
                Node[num_or_op].num.a = num;
                num = 0;
                ++num_or_op;
                isfloat= 0;
                num_of_point = 0;
            }
            Node[num_or_op].flag = KIND_OPERATOR;
            Node[num_or_op].num.op = tmp[i].toLatin1();
            ++num_or_op;
            ++i;
        }
    }
    if(num)   //Last operand
    {
        Node[num_or_op].flag = KIND_NUMBER;
        Node[num_or_op].num.a = num;
        ++num_or_op;
        num = 0;
    }
    
    //Change arithmetic expression to suffix expression
    QStack<_tNode>pNode;  //Build a stack of type_tnodepnode, which is a storage operator stack
    _tNode _Node[NUM_OF_NUMBER];
    int j = 0;
    for(int m = 0;m< num_or_op;)
    {
        if(Node[m].flag)  //Symbol entry
        {
            if(pNode.isEmpty())
            {
                pNode.push(Node[m++]);

            }
            else
            {
                _tNode tem = pNode.top();
                int ret = process(tem.num.op,Node[m].num.op);
                switch(ret)
                {
                    case -1:
                        pNode.push(Node[m++]);
                        break;
                     case 1:
                          _Node[j++] = pNode.top();
                          pNode.pop();
                          break;
                       default:
                             pNode.pop();
                            m++;
                            break;
            }
            }
        }
    else
    {
        _Node[j++] = Node[m++];
    }
    }
while(!pNode.isEmpty()) //Remaining elements in pop-up stack
{
    _tNode tem = pNode.top();
    if(tem.num.op != '(' &&tem.num.op != ')')
        _Node[j++] = tem;
     pNode.pop();
}

QStack<double> last;  //Build a data stack
double d1,d2;
for(int n = 0;n < j;n++)
{
    if(_Node[n].flag) //A symbol pop-up number is encountered for calculation
    {
        d2 = last.top();
        last.pop();
        d1 = last.top();
        last.pop();
        switch(_Node[n].num.op)
        {
            case '+':
                   d1 += d2;
                    break;
        case '-':
            d1 -= d2;
            break;
        case '*':
            d1 *= d2;
            break;
        case '/':
            d1 /= d2;
            break;
        default:
            break;
        }
        last.push(d1);
    }
    else
    {
        last.push(_Node[n].num.a);
    }
}
qDebug() << d1;
tmp += '=';
tmp += QString::number(d1);
}

int expr::process(char a,char b)  //Priority comparison
{
    char aim[7][8] = {{ ">><<<>>" },{ ">><<<>>" },{ ">>>><>>" },{ ">>>><>>" },{ "<<<<<=1" },{ ">>>>1>>" },{ "<<<<<1=" }};
    char sta[7] = { '+','-','*','/','(',')','#' };
    char result;
    int i,pa,pb;
    for (i = 0; i<6; i++)
          {
             if (a == sta[i])
             {
                 pa = i;
             }
             if (b == sta[i])
             {
                 pb = i;
             }
          }
    result = aim[pa][pb];
    if(result == '>')return 1;
    else if(result == '<')return -1;
    else return 0;
  }


Code in expr.h:

#ifndef EXPR_H
#define EXPR_H

#include <QDialog>
#include <QStack>

namespace Ui {
class expr;
}

class expr : public QDialog
{
    Q_OBJECT

public:
    explicit expr(QWidget *parent = 0);
    ~expr();

    void calculate();
    int  process(char a,char b);

private slots:
    void on_btn_0_clicked();

    void on_btn_1_clicked();

    void on_btn_2_clicked();

    void on_btn_3_clicked();

    void on_btn_4_clicked();

    void on_btn_5_clicked();

    void on_btn_6_clicked();

    void on_btn_7_clicked();

    void on_btn_8_clicked();

    void on_btn_9_clicked();

    void on_btn_plus_clicked();

    void on_btn_sub_clicked();

    void on_btn_mul_clicked();

    void on_btn_div_clicked();

    void on_btn_equ_clicked();

    void on_btn_point_clicked();

    void on_btn_left_clicked();

    void on_btn_right_clicked();

    void on_btn_delet_clicked();

    void on_btn_clear_clicked();

private:
    QString tmp;
    Ui::expr *ui;

};

#endif // EXPR_H

Note: the arithmetic expression should consider the priority of symbols, so it should be applied to the stack
To initialize a variable of QString type to null, there must be no space between the double quotes. Otherwise, forced exit occurs during calculation. There is a memory leak problem. You can also change QString to char type to avoid this error.

Keywords: ascii

Added by soianyc on Sun, 17 Nov 2019 22:10:32 +0200