QT写个mini四则运算计算器

思路:

1、通过qt建立一个带有主窗口的工程,然后将数字按键和运算符按键用pushbutton放在ui上,再建立一个qstring读取输入的字符串。

2、用户按下=符号时对字符串进行检查,如果合法则进行计算,如果不合法则输出从错误提示。

3、需要写十几个按键对应的字符串操作函数,再写一个中缀表达式计算的函数(这个函数中包含了判断表达式是否合法,一些字符比如二字节的(×÷)计算前应转换为char字节的(*/),以及对计算结果去除末尾多余的0等)。

4、最后程序调试结束后用QT安装时自带的插件将release编译出来的exe文件封装成可执行程序。

github链接在末尾,先上效果图

启动界面:

计算界面:

报错提示:

主窗口头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QString>
#include <QMainWindow>
#include <string>
#include <stack>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void get_result();

    void sur_win();
private slots:

    void on_p1_clicked();

    void on_p2_clicked();

    void on_p3_clicked();

    void on_p4_clicked();

    void on_p5_clicked();

    void on_p6_clicked();

    void on_p7_clicked();

    void on_p8_clicked();

    void on_p9_clicked();

    void on_p0_clicked();

    void on_AC_clicked();

    void on_backspace_clicked();

    void on_padd_clicked();

    void on_psubstract_clicked();

    void on_pmultiple_clicked();

    void on_pequal_clicked();

    void on_pdivide_clicked();

    void on_pdot_clicked();

    void on_ppow_clicked();

    void on_jingxi_clicked();

    void on_brackestl_clicked();

    void on_brackestr_clicked();

    void on_pequal2_clicked();
private:
    Ui::MainWindow *ui;
    QString input = "", ans = "";
    std::string s = "";
    int tag = 1;    //tag = 1表示刚输入了一个符号,再输入符号的时候会直接替换刚才输入的符号
};
#endif // MAINWINDOW_H

主窗口CPP文件

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include "surprise_window.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setFixedSize(640, 640);
    ui->input_line->setPlaceholderText("请点击这里输入算式");
    ui->answers->setPlaceholderText("答案会显示在这里哦!!");
}


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

void caculation(std::stack<double> &s1, std::stack<char>& s2, int& flag){
    if (s1.size() < 2){flag = 0; return;}
    double a = s1.top();
    s1.pop();
    double b = s1.top(), d = 1;
    s1.pop();
    char op = s2.top();
    s2.pop();
    switch(op){
        case('+'): s1.push(b + a); break;
        case('-'): s1.push(b - a); break;
        case('*'): s1.push(b * a); break;
        case('/'): if(a == 0) {flag = 0;break;}s1.push(b / a); break;
        case('^'): while(a--) d *= b;s1.push(d); break;
        default: flag = 0;
    }
}


//计算环节
void MainWindow::get_result(){
    if (input.size() < 2){ans = "ERROR_INPUT!!!"; return;} //长度不够可以直接报错
    s = input.toStdString();
    //16bit的×和÷转化为*和/
    for (int i = 0; i < s.size() - 1; ++i){
       // std::cout << int(s[i]) << std::endl;
        if (s[i] == -61){
            if (s[i + 1] == -105){s[i] = '*';s.erase(i + 1, 1); i-= 1;}
            else if (s[i + 1] == -73){s[i] = '/'; s.erase(i + 1, 1);i -= 1;}
        }
    }
   // std::cout << s << std::endl;
    //写个检查括号数量的函数吧,哎!
    int cnt = 0, flag = 1;
    for (int i = 0; i < s.size(); ++i){
        if (s[i] == '(') {cnt += 1;}
        else if(s[i] == ')'){ cnt -= 1;}
        if (cnt < 0){ans = "ERROR_INPUT!!!"; return;} //右括号过多
    }
    if (cnt != 0){ans = "ERROR_INPUT!!!"; return;}  //左括号过多
    s = '(' + s + ')';//加个括号方便中缀表达式边界条件计算
    int n = s.size();
    std::stack<double> s1;
    std::stack<char> s2;
    for (int i = 0; i < n && flag; ++i){
        if ('0' <= s[i] && s[i] <= '9'){
            double t = 0;
            while(i < n && s[i] >= '0' && s[i] <= '9'  && flag){t *= 10; t += s[i] - '0'; i += 1;}
            //如果后面还有整数部分的话,小数部分不能漏
            if(s[i] == '.'){
                i += 1;
                double tt = 0;
                while(i < n && s[i] >= '0' && s[i] <= '9'  && flag){tt *= 10;tt += s[i] - '0'; i += 1;}
                while(tt > 1){tt /= 10;}
                t += tt;
            }
            i -= 1;
            s1.push(t);
        }
        else if (s[i] == '+'){
            while(s2.top() != '('  && flag){caculation(s1, s2, flag);}
            s2.push(s[i]);
        }
        else if (s[i] == '-'){
            if (i == 0 || (i && !(s[i - 1] >= '0' && s[i - 1] <= '9') && s[i - 1] != ')')){
                double t = 0;
                i += 1;
                while (i < n && s[i] <= '9' && s[i] >= '0'  && flag){t *= 10; t += s[i] - '0';i += 1;}
                 s1.push(t * -1);
                i -= 1;
            }
            else{
                while(s2.top() != '('  && flag){caculation(s1, s2, flag);}
                s2.push(s[i]);
            }
        }
        else if (s[i] == '*' || s[i] == '/'){
            while (s2.top() != '(' && (s2.top() == '*' || s2.top() == '/' || s2.top() == '^') && flag){caculation(s1, s2, flag);}
            s2.push(s[i]);
        }
        else if (s[i] == '^'){
            while (s2.top() != '(' && s2.top() == '^'  && flag){caculation(s1, s2, flag);}
            s2.push(s[i]);
        }
        else if (s[i] == ')'){
            while (s2.top() != '(' && flag){caculation(s1, s2, flag);}
            s2.pop();
        }
        else if(s[i] == '('){
            s2.push(s[i]);
        }
    }
    if (!flag || s2.size() != 0 || s1.size() == 0){ans = "ERROR_INPUT!!!";} //如果因为字符串违规退出或者栈中仍有符号或者栈中没有数字
    else{
        std::string ss = std::to_string(s1.top());
        int i = ss.size() - 1;
        //std::cout << ss << std::endl;
        while(ss[i] != '.' && ss[i] == '0'){ss.erase(i, 1); i -= 1;}
        if(ss[i] == '.') ss.erase(i, 1);
        //std::cout << ss << std::endl;
        ans = QString::fromStdString(ss);
    }
}

void MainWindow::sur_win(){
    surprise_window* ww = new surprise_window();
    ww->show();
}

void MainWindow::on_p1_clicked(){input = input + "1";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p2_clicked(){input = input + "2";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p3_clicked(){input = input + "3";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p4_clicked(){input = input + "4";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p5_clicked(){input = input + "5";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p6_clicked(){input = input + "6";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p7_clicked(){input = input + "7";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p8_clicked(){input = input + "8";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p9_clicked(){input = input + "9";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_p0_clicked(){input = input + "0";ui->input_line->setText(input);tag = 1;}

void MainWindow::on_backspace_clicked(){input = input.left(input.size() - 1);ui->input_line->setText(input); tag = 1;}

void MainWindow::on_AC_clicked(){input = ""; ui->input_line->setText(input); ui->answers->setText("");}


void MainWindow::on_brackestl_clicked(){input = input + "(";ui->input_line->setText(input);}

void MainWindow::on_brackestr_clicked(){input = input + ")";ui->input_line->setText(input);}

void MainWindow::on_pequal2_clicked(){input = ans;ui->input_line->setText(input);}


//下面的按键是运算符

void MainWindow::on_padd_clicked(){
    if(tag) {input = input + "+";}
    else {input = input.left(input.size() - 1) + "+";}
    ui->input_line->setText(input); tag = 0;
}
void MainWindow::on_psubstract_clicked(){
    if(tag) {input = input + "-";}
    else {input = input.left(input.size() - 1) + "-";}
    ui->input_line->setText(input); tag = 0;
}
void MainWindow::on_pmultiple_clicked(){
    if(tag) {input = input + "×";}
    else {input = input.left(input.size() - 1) + "×";}
    ui->input_line->setText(input); tag = 0;
}
void MainWindow::on_pdivide_clicked(){
    if(tag) {input = input + "÷";}
    else {input = input.left(input.size() - 1) + "÷";}
    ui->input_line->setText(input); tag = 0;
}
void MainWindow::on_ppow_clicked(){
    if(tag) {input = input + "^";}
    else {input = input.left(input.size() - 1) + "^";}
    ui->input_line->setText(input); tag = 0;
}
//将结果赋值到input,方便利用当前结果计算计算
void MainWindow::on_pequal_clicked(){
    get_result(); ui->answers->setText(ans);
}
void MainWindow::on_pdot_clicked(){
    if (input.size() > 0 && input[input.size() - 1] != '.'){input = input + ".";ui->input_line->setText(input);tag = 1;}//不能连续输入2个'.'
}
void MainWindow::on_jingxi_clicked(){
    sur_win();
}

还有两个小头文件

#ifndef SURPRISE_WINDOW_H
#define SURPRISE_WINDOW_H

#include <QMainWindow>


namespace Ui {
class surprise_window;
}

class surprise_window : public QMainWindow
{
    Q_OBJECT

public:
    explicit surprise_window(QWidget *parent = nullptr);
    ~surprise_window();

private slots:
    void on_yes_clicked();

    void on_no_clicked();

private:
    Ui::surprise_window *ui;
};

#endif // SURPRISE_WINDOW_H

#ifndef CORRECT_H
#define CORRECT_H

#include <QWidget>

namespace Ui {
class correct;
}

class correct : public QWidget
{
    Q_OBJECT

public:
    explicit correct(QWidget *parent = nullptr);
    ~correct();
    Ui::correct *ui;
public slots:
    void on_ok_clicked();
private:
    QFont f;
};

#endif // CORRECT_H

两个小文件的cpp
 

#include "surprise_window.h"
#include "ui_surprise_window.h"
#include "correct.h"
#include "ui_correct.h"
surprise_window::surprise_window(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::surprise_window)
{
    ui->setupUi(this);
}

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



void surprise_window::on_yes_clicked(){
    correct * wd = new correct();
    wd->ui->texta->setText("恭喜你答对了!!!!!!!!!!!!!!");
    wd->show();
}

void surprise_window::on_no_clicked(){
    correct *wd = new correct();
    wd->ui->texta->setText("我劝你思考清楚再做决定哦!!!!!!!!");
    wd->show();
};

#include "correct.h"
#include "ui_correct.h"

correct::correct(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::correct)
{
    ui->setupUi(this);
    f.setPixelSize(36);
    ui->texta->setFont(f);
}

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


void correct::on_ok_clicked(){
    close();
}

main文件

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

还有3个UI文件..突然发现UI文件不知道怎么发出来,随便截几张图吧,回头把下载链接跟工程上传上来。

然后用qt自带的软件封装一下就行了。

https://github.com/100000000000000000000000000000000/Qt-easy-caculator-s

上面的链接为qt6的widget工程的源码文件以及可执行的计算器文件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值