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.