Qt练手项目(计算器)代码含思路

思路

采用的是对符号标志位进行记录,利用标志位分割输入的字符串得到要运算的数字的方法,如图所示是我这个思路的一个例子。这样就能够进行连续输入运算,输入长串的计算公式,且能保障乘除法计算的优先级,底层还是应用的两个数字的加减乘除运算
在这里插入图片描述

代码

config.h文件 配置了一些resource信息

#ifndef CONFIG_H
#define CONFIG_H
/********** 配置图标信息 **********/
#define ICON_PATH ":/resou/cal.ico"
/********** 配置标题信息 **********/
#define WINDOW_TITLE "计算器"
#endif // CONFIG_H

主要部分是widget文件
widget.h文件 计算器的功能我分为了界面初始化、按钮监听、显示、运算、清零、返回上一步和求倒数功能

#ifndef WIDGET_H
#define WIDGET_H
#include<Qstring>
#include <QWidget>
#include <QByteArray>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    //初始化计算器界面
    void initwidget();
    //启动计算器开始监听按钮
    void start();
    //对按钮选择及结果进行显示
    void showcal(QString str);
    //对运算的两个数字和符号进行处理
    void compute(QVector<QString> str1, QVector<QString> str2);
    //清零
    void calclear();
    //清除上一位
    void del_prev();
    //求倒数功能
    void reverse();
public:
    //输出的结果
    QVector<QString> m_numarr;
    QVector<QString> m_flagarr;
    //显示计算过程公式
    QString m_showstr;
    //记录flag标志位
    int m_pos;

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include "config.h"
#include <QIcon>
#include <QString>
#include <QDebug>
#include "math.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    initwidget();

}

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

void Widget::initwidget()
{   //初始化窗口标题图标
    setWindowTitle(WINDOW_TITLE);
    setWindowIcon(QIcon(ICON_PATH));
    //初始化参数:显示栏、标志位、标志向量、数字向量
    m_showstr = "0";
    m_pos = 0;
    m_flagarr.clear();
    QVector<QString>().swap(m_flagarr);
    m_numarr.clear();
    QVector<QString>().swap(m_numarr);
    this->ui->textBrowser->setText(m_showstr);
    start();
}

void Widget::start()
{
    //连接按钮与功能
    connect(ui->pushButton1, &QPushButton::clicked,[=](){
        showcal("1");
    });
    connect(ui->pushButton0, &QPushButton::clicked,[=](){
        showcal("0");
    });
    connect(ui->pushButton2, &QPushButton::clicked,[=](){
        showcal("2");
    });
    connect(ui->pushButton3, &QPushButton::clicked,[=](){
        showcal("3");
    });
    connect(ui->pushButton4, &QPushButton::clicked,[=](){
        showcal("4");
    });
    connect(ui->pushButton5, &QPushButton::clicked,[=](){
        showcal("5");
    });
    connect(ui->pushButton6, &QPushButton::clicked,[=](){
        showcal("6");
    });
    connect(ui->pushButton7, &QPushButton::clicked,[=](){
        showcal("7");
    });
    connect(ui->pushButton8, &QPushButton::clicked,[=](){
        showcal("8");
    });
    connect(ui->pushButton9, &QPushButton::clicked,[=](){
        showcal("9");
    });
    connect(ui->pushButtonplus, &QPushButton::clicked,[=](){
        showcal("+");
    });
    connect(ui->pushButtondmulty, &QPushButton::clicked,[=](){
        showcal("*");
    });
    connect(ui->pushButtondiv, &QPushButton::clicked,[=](){
        showcal("/");
    });
    connect(ui->pushButtonminus, &QPushButton::clicked,[=](){
        showcal("-");
    });
    connect(ui->pushButtonremain, &QPushButton::clicked,[=](){
        showcal("%");
    });
    connect(ui->pushButtonreturn, &QPushButton::clicked,[=](){
        calclear();
    });
    connect(ui->pushButtonequal, &QPushButton::clicked,[=](){
        compute(m_flagarr, m_numarr);
    });
    connect(ui->pushButtonDel, &QPushButton::clicked,[=](){
        del_prev();
    });
    connect(ui->pushButtondot, &QPushButton::clicked,[=](){
        showcal(".");
    });
    connect(ui->pushButtonreverse, &QPushButton::clicked,[=](){
        reverse();
    });
}

void Widget::showcal(QString str)
{
    //初始状态显示为0,有新输入后要刷新
    if(m_showstr == "0")
    {
        m_showstr = "";
    }
    //对标志位进行判断
    if(str == "+" || str =="-" || str == "*" || str == "/"||str == "-"||str == "%")
    {
        //如果已经选择了标志位,且未追加输入数字,对标志位进行更新
        if(m_showstr.right(1) == "+" || m_showstr.right(1) == "-" || m_showstr.right(1) == "*" || m_showstr.right(1) == "/" || m_showstr.right(1) == "%")
        {
            m_showstr.chop(1);
        }
        //在初始状态为0状态直接应用符号标志位
        else if (m_showstr.right(1) == "") {
            str = "0" + str;
        }
        //记录标志位,以符号标志位做隔断,记录标志位前的字符为要计算的数字
        if(m_pos == 0)
        {
            m_numarr.append(m_showstr.mid(m_pos));}
        else {
            m_numarr.append(m_showstr.mid(m_pos+1));
        }
        m_pos = m_showstr.size();
        m_flagarr.append(str);
    }
    m_showstr += str;
    this->ui->textBrowser->setText(m_showstr);
}

void Widget::calclear()
{
    m_showstr = "";
    m_pos = 0;
    m_flagarr.clear();
    QVector<QString>().swap(m_flagarr);
    m_numarr.clear();
    QVector<QString>().swap(m_numarr);
    this->ui->textBrowser->setText("0");
}

void Widget::compute(QVector<QString> str1, QVector<QString> str2)
{
    str2.append(m_showstr.mid(m_pos+1));
    int pos;
    QString num1;
    QString num2;
    QString result;
    double n1;
    double n2;
    //先乘除后加减
    while(str1.indexOf("*") != -1 || str1.indexOf("/") != -1 || str1.indexOf("%") != -1)
    {
        pos = str1.indexOf("*");
        if(pos != -1)
        {
            num1 = str2.value(pos);
            num2 = str2.value(pos+1);
            n1 = num1.toFloat();
            n2 = num2.toFloat();
            result = QString::number(n1 * n2);
            str2.replace(pos, result);
            str2.remove((pos+1), 1);
            str1.remove(pos, 1);
        }
        pos = str1.indexOf("/");
        if(pos != -1){
            num1 = str2.value(pos);
            num2 = str2.value(pos+1);
            n1 = num1.toFloat();
            n2 = num2.toFloat();
            result = QString::number(n1 / n2);
            str2.replace(pos, result);
            str2.remove((pos+1), 1);
            str1.remove(pos, 1);
        }
        pos = str1.indexOf("%");
        if(pos != -1){
            num1 = str2.value(pos);
            num2 = str2.value(pos+1);
            n1 = num1.toFloat();
            n2 = num2.toFloat();
            result = QString::number(fmod(n1,n2));
            str2.replace(pos, result);
            str2.remove((pos+1), 1);
            str1.remove(pos, 1);
        }
    }
    while(str1.indexOf("+") != -1 || str1.indexOf("-") != -1)
    {
        pos = str1.indexOf("+");
        if(pos != -1)
        {
            num1 = str2.value(pos);
            num2 = str2.value(pos+1);
            n1 = num1.toFloat();
            n2 = num2.toFloat();
            result = QString::number(n1 + n2);
            str2.replace(pos, result);
            str2.remove((pos+1), 1);
            str1.remove(pos, 1);
        }
        pos = str1.indexOf("-");
        if(pos != -1){
            num1 = str2.value(pos);
            num2 = str2.value(pos+1);
            n1 = num1.toFloat();
            n2 = num2.toFloat();
            result = QString::number(n1 - n2);
            str2.replace(pos, result);
            str2.remove((pos+1), 1);
            str1.remove(pos, 1);
        }
    }
    //更新参数状态
    m_showstr = str2.value(0);
    m_pos = 0;
    m_flagarr.clear();
    QVector<QString>().swap(m_flagarr);
    m_numarr.clear();
    QVector<QString>().swap(m_numarr);
    this->ui->textBrowser->setText(result);
}

void Widget::del_prev()
{
    if(m_showstr.right(1) == "+" || m_showstr.right(1) == "-" || m_showstr.right(1) == "*" || m_showstr.right(1) == "/")
    {
        m_showstr.chop(1);
        //标志位的清除涉及到数字记录
        m_flagarr.removeLast();
        m_numarr.removeLast();
        m_pos -= m_showstr.size();
        this->ui->textBrowser->setText(m_showstr);
    }
    else
    {
        //数字位的清除
        m_showstr.chop(1);
        this->ui->textBrowser->setText(m_showstr);
    }
}

void Widget::reverse()
{
    float reverse_x = m_showstr.toFloat();
    QString reverse_x_str = QString::number(1 / reverse_x);
    m_showstr = reverse_x_str;
    this->ui->textBrowser->setText(m_showstr);
}

效果

截图
附了我这全部代码文件,0积分的资源
https://download.youkuaiyun.com/download/weixin_45058446/87723436

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值