Qt 实现简易计算器

环境

Qt 5.4.2

功能

QWidget 实现简易计算器
在这里插入图片描述

源码

1.CalculatorApp.h


#define DEF_MAXCOUNT  13
//运算符
#define DEF_SIGNADD   "+"
#define DEF_SIGNSUB   "-"
#define DEF_SIGNMUL   "×"
#define DEF_SIGNDIV   "/"
#define DEF_SIGNEQU   "="

//数学函数
#define DEF_MATHRATE   "%"   //百分比
#define DEF_MATHFRAC   "1/"  //1/x
#define DEF_MATHSQR    "sqr" //X²
#define DEF_MATHROOT   "√"   //√x


enum ENUM_SEGTYPE{
  ENUM_SEGNTYPE_NUL=1000,
  ENUM_SEGNTYPE_VALUE,       //数值
  ENUM_SEGNTYPE_SIGN,        //符号
};

typedef struct {
    ENUM_SEGTYPE eSegType;   //数据类型: 数值/符号
    double dbValue;          //数据
    QString strExpress;      //表达式
}TagSegInfo;


/** 标准计算器 **/

class CalculatorApp : public QWidget
{
    Q_OBJECT
private:
    void printfExpress();                  //显式表达式
    QString formatDouble(double dbValue);
    void calculErrorEvent(bool isError);

    void digiButtonClick(QString digiVal);  //数字键盘按下
    void mathButtonClick(QString funType);  //数学函数按下
    void mathFunctionCal(QString funType);  //数学函数计算
    void signButtonClick(QString sign);     //数学符号按下
    int  calculatExpress();                 //计算表达式
private slots:
    void on_pushButton_0_clicked();
    void on_pushButton_1_clicked();
    void on_pushButton_2_clicked();
    void on_pushButton_3_clicked();
    void on_pushButton_4_clicked();
    void on_pushButton_5_clicked();
    void on_pushButton_6_clicked();
    void on_pushButton_7_clicked();
    void on_pushButton_8_clicked();
    void on_pushButton_9_clicked();

    void on_pushButton_neg_clicked();
    void on_pushButton_point_clicked();

    void on_pushButton_rate_clicked();
    void on_pushButton_fract_clicked();
    void on_pushButton_square_clicked();
    void on_pushButton_root_clicked();

    void on_pushButton_add_clicked();
    void on_pushButton_sub_clicked();
    void on_pushButton_mul_clicked();
    void on_pushButton_div_clicked();
    void on_pushButton_equal_clicked();

    void on_pushButton_CE_clicked();
    void on_pushButton_C_clicked();
    void on_pushButton_back_clicked();
private:
    QList<TagSegInfo> tagSegList;
    bool bIsAppendDot;   
    bool bIsCalcError;   //表达式错误
    bool bIsDigitPres;   //符号件按下后时候有数字键按下?
private:
    Ui::CalculatorApp *ui;
};
#endif // CALCULATORAPP_H

2.CalculatorApp.cpp

CalculatorApp::CalculatorApp(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::CalculatorApp)
{
    ui->setupUi(this);

    bIsAppendDot = true;
    bIsCalcError = false;
    bIsDigitPres = false;

}

void CalculatorApp::printfExpress()
{
    QString strValue = "";

    ui->label_express->setText("");

    for(int i=0; i<tagSegList.size() ;i++)
    {
        strValue += tagSegList.at(i).strExpress;
    }

    ui->label_express->setText(strValue);
}

void CalculatorApp::calculErrorEvent(bool isError)
{
     bIsCalcError = isError;

     ui->pushButton_rate->setEnabled(!isError);
     ui->pushButton_fract->setEnabled(!isError);
     ui->pushButton_square->setEnabled(!isError);
     ui->pushButton_root->setEnabled(!isError);
     ui->pushButton_div->setEnabled(!isError);
     ui->pushButton_mul->setEnabled(!isError);
     ui->pushButton_sub->setEnabled(!isError);
     ui->pushButton_add->setEnabled(!isError);

     ui->pushButton_point->setEnabled(!isError);
     ui->pushButton_neg->setEnabled(!isError);

     if(!isError) //init
     {
         tagSegList.clear();
         ui->label_express->setText("");
         ui->label_result->setText("0");

         bIsAppendDot = true;
         bIsDigitPres = false;
     }
}


void CalculatorApp::on_pushButton_0_clicked() { digiButtonClick("0");}
void CalculatorApp::on_pushButton_1_clicked() { digiButtonClick("1");}
void CalculatorApp::on_pushButton_2_clicked() { digiButtonClick("2");}
void CalculatorApp::on_pushButton_3_clicked() { digiButtonClick("3");}
void CalculatorApp::on_pushButton_4_clicked() { digiButtonClick("4");}
void CalculatorApp::on_pushButton_5_clicked() { digiButtonClick("5");}
void CalculatorApp::on_pushButton_6_clicked() { digiButtonClick("6");}
void CalculatorApp::on_pushButton_7_clicked() { digiButtonClick("7");}
void CalculatorApp::on_pushButton_8_clicked() { digiButtonClick("8");}
void CalculatorApp::on_pushButton_9_clicked() { digiButtonClick("9");}

void CalculatorApp::on_pushButton_rate_clicked()  {mathButtonClick(DEF_MATHRATE);}
void CalculatorApp::on_pushButton_fract_clicked() {mathButtonClick(DEF_MATHFRAC);}
void CalculatorApp::on_pushButton_square_clicked(){mathButtonClick(DEF_MATHSQR); }
void CalculatorApp::on_pushButton_root_clicked()  {mathButtonClick(DEF_MATHROOT);}


void CalculatorApp::on_pushButton_add_clicked(){ signButtonClick("+");}
void CalculatorApp::on_pushButton_sub_clicked(){ signButtonClick("-");}
void CalculatorApp::on_pushButton_mul_clicked(){ signButtonClick("×");}
void CalculatorApp::on_pushButton_div_clicked(){ signButtonClick("/");}
void CalculatorApp::on_pushButton_equal_clicked()
{
    if(bIsCalcError) { calculErrorEvent(false); return ; }

    signButtonClick("=");
}


void CalculatorApp::on_pushButton_neg_clicked()   {

    double dbValue = ui->label_result->text().toDouble();

    dbValue = 0 - dbValue;

    ui->label_result->setText(formatDouble(dbValue));


    if((0 < tagSegList.size()) && (ENUM_SEGNTYPE_VALUE == tagSegList.at(tagSegList.size()-1).eSegType))
    {
        TagSegInfo tagSegInfo;
        tagSegInfo.eSegType = ENUM_SEGNTYPE_VALUE;
        tagSegInfo.dbValue = dbValue;
        tagSegInfo.strExpress ="negate("+tagSegList.at(tagSegList.size()-1).strExpress+")";

        tagSegList.replace(tagSegList.size()-1,tagSegInfo);

        printfExpress();
    }

    if((0 < tagSegList.size()) && (DEF_SIGNEQU == tagSegList.at(tagSegList.size()-1).strExpress))
    {
        tagSegList.clear();
        printfExpress();
    }
}

void CalculatorApp::on_pushButton_point_clicked(){

     if(DEF_MAXCOUNT <= ui->label_result->text().count()) { return; }

     bIsDigitPres = true;
     if((tagSegList.size() > 0) && (DEF_SIGNEQU ==  tagSegList.at(tagSegList.size()-1).strExpress))
     {
         tagSegList.clear();
         printfExpress();
     }
     if(!bIsAppendDot) {  ui->label_result->setText("0."); }
     else{  ui->label_result->setText(ui->label_result->text()+"."); }
}

void CalculatorApp::on_pushButton_CE_clicked()
{
    if(bIsCalcError) { calculErrorEvent(false); }

    if((tagSegList.size() > 0) && (DEF_SIGNEQU ==  tagSegList.at(tagSegList.size()-1).strExpress))
    {
       tagSegList.clear();
       printfExpress();
    }
    bIsDigitPres = false;
    ui->label_result->setText("0");
}

void CalculatorApp::on_pushButton_C_clicked()
{
    if(bIsCalcError) { calculErrorEvent(false); }

    tagSegList.clear();

    ui->label_result->setText("0");
    ui->label_express->setText("");

    bIsAppendDot = true;
    bIsCalcError = false;
    bIsDigitPres = false;

}
void CalculatorApp::on_pushButton_back_clicked()
{
    if(bIsCalcError) { calculErrorEvent(false); }

    if((tagSegList.size() > 0) && (ENUM_SEGNTYPE_VALUE ==  tagSegList.at(tagSegList.size()-1).eSegType))
    { return;}

    if((tagSegList.size() > 0) && (ENUM_SEGNTYPE_SIGN ==  tagSegList.at(tagSegList.size()-1).eSegType))
    {
        if(ENUM_SEGNTYPE_SIGN ==  tagSegList.at(tagSegList.size()-1).eSegType)
        {
            tagSegList.clear();
            printfExpress();
            bIsDigitPres = false;

            return;
        }
        if(!bIsDigitPres) { return; }
    }
    if(1 < ui->label_result->text().count())
    { ui->label_result->setText(ui->label_result->text().mid(0,ui->label_result->text().count()-1));}
    else{ ui->label_result->setText("0");    bIsDigitPres = false;}

}

//Double value 小数点位数处理
QString CalculatorApp::formatDouble(double dbValue)
{
    int ndecimal = DEF_MAXCOUNT -1-QString::number(dbValue,'f',0).count();

    QString strResult = QString::number(dbValue,'f',ndecimal);

    while('0' == strResult.at(strResult.count()-1))
    {
        strResult = strResult.mid(0,strResult.count()-1);
    }

    if('.' == strResult.at(strResult.count()-1))
    {
        strResult = strResult.mid(0,strResult.count()-1);
    }

    if(strResult.count() > (1+DEF_MAXCOUNT))
    {
        calculErrorEvent(true);
        strResult = "溢出";
    }

    return strResult;
}
//数字按键
void CalculatorApp::digiButtonClick(QString digiVal)
{
    if(DEF_MAXCOUNT <  ui->label_result->text().count()) { return; }

    if(bIsCalcError) { calculErrorEvent(false);}

    bIsAppendDot = true;

    if((0 <  tagSegList.size()) && (ENUM_SEGNTYPE_VALUE == tagSegList.at(tagSegList.size()-1).eSegType))
    {
         tagSegList.removeLast();
         printfExpress();

         ui->label_result->setText(digiVal);
         bIsDigitPres = true;
         return;
    }

    if((0 <  tagSegList.size()) && (ENUM_SEGNTYPE_SIGN == tagSegList.at(tagSegList.size()-1).eSegType) &&(!bIsDigitPres))
    {
        if(DEF_SIGNEQU == tagSegList.at(tagSegList.size()-1).strExpress)  { tagSegList.clear(); printfExpress();}

        ui->label_result->setText(digiVal);
        bIsDigitPres = true;
        return;
    }

    if((0 >= tagSegList.size()) && (!bIsDigitPres))
    {
        ui->label_result->setText(digiVal);
        bIsDigitPres = true;
        return;
    }
    if("0" == ui->label_result->text())  { ui->label_result->setText(digiVal); }
    else { ui->label_result->setText(ui->label_result->text()+digiVal);        }

    bIsDigitPres = true;
}


//数学函数
void CalculatorApp::mathButtonClick(QString funType)
{
    double dbValue  = ui->label_result->text().toDouble();
    //Error
    if((DEF_MATHFRAC == funType) && (0 == dbValue)) {
        calculErrorEvent(true);
        ui->label_express->setText(ui->label_express->text()+"1/(0)");
        ui->label_result->setText("除数不能为0");
        return;
    }

    if((DEF_MATHROOT == funType) && (0 > dbValue)) {
        calculErrorEvent(true);
        ui->label_express->setText("√("+ ui->label_result->text()+")");
        ui->label_result->setText("无效输入");
        return;
    }
    //无效计算
    if((DEF_MATHRATE == funType) && (0 >= tagSegList.size()))
    {
        tagSegList.clear();
        ui->label_result->setText("0");
        ui->label_express->setText("");
        return;
    }
    //清空
    if((0 <  tagSegList.size()) && (DEF_SIGNEQU == tagSegList.at(tagSegList.size()-1).strExpress))
    {
        tagSegList.clear();
    }
    mathFunctionCal(funType);

}

//数学函数
void CalculatorApp::mathFunctionCal(QString funType)
{
    TagSegInfo tagSegInfo;
    tagSegInfo.eSegType = ENUM_SEGNTYPE_VALUE;
    tagSegInfo.dbValue = ui->label_result->text().toDouble();
    tagSegInfo.strExpress =funType;

    bIsAppendDot = false;
    bIsDigitPres = true;

    if(DEF_MATHRATE == funType)
    {
         tagSegInfo.dbValue = tagSegInfo.dbValue / (double)100;
    }else if(DEF_MATHFRAC == funType)
    {
         tagSegInfo.dbValue = (double)1 / tagSegInfo.dbValue ;
    }else if(DEF_MATHSQR == funType)
    {
         tagSegInfo.dbValue *= tagSegInfo.dbValue ;
    }else if(DEF_MATHROOT == funType)
    {
         tagSegInfo.dbValue = qSqrt(tagSegInfo.dbValue );
    }

    if((0 >= tagSegList.size()) || ((0 < tagSegList.size()) && (ENUM_SEGNTYPE_SIGN == tagSegList.at(tagSegList.size()-1).eSegType)))
    {
        if(DEF_MATHRATE == tagSegInfo.strExpress){ tagSegInfo.strExpress = formatDouble(tagSegInfo.dbValue); }
        else { tagSegInfo.strExpress = tagSegInfo.strExpress+"("+ui->label_result->text()+")"; }

        ui->label_result->setText(formatDouble(tagSegInfo.dbValue));
        tagSegList.append(tagSegInfo);
        printfExpress();

        return;
    }

    if((0 <  tagSegList.size()) && (ENUM_SEGNTYPE_VALUE == tagSegList.at(tagSegList.size()-1).eSegType))
    {
        if(DEF_MATHRATE == tagSegInfo.strExpress){tagSegInfo.strExpress = formatDouble(tagSegInfo.dbValue);}
        else{tagSegInfo.strExpress =  tagSegInfo.strExpress+"("+tagSegList.at(tagSegList.size()-1).strExpress+")";}

        ui->label_result->setText(formatDouble(tagSegInfo.dbValue));
        tagSegList.replace(tagSegList.size()-1,tagSegInfo);
        printfExpress();

        return;
    }
}

//运算符
void CalculatorApp::signButtonClick(QString sign)
{
    bIsAppendDot = false;

    TagSegInfo tagSegInfo1;
    TagSegInfo tagSegInfo2;

    tagSegInfo1.eSegType = ENUM_SEGNTYPE_VALUE;
    tagSegInfo1.dbValue = ui->label_result->text().toDouble();
    tagSegInfo1.strExpress = ui->label_result->text();

    tagSegInfo2.eSegType = ENUM_SEGNTYPE_SIGN;
    tagSegInfo2.dbValue = 0;
    tagSegInfo2.strExpress = sign;


    if(0 >= tagSegList.size())
    {
        tagSegList.append(tagSegInfo1);
        tagSegList.append(tagSegInfo2);
        printfExpress();
        bIsDigitPres = false;
        return;
    }

    if(ENUM_SEGNTYPE_VALUE == tagSegList.at(tagSegList.size()-1).eSegType)
    {
         tagSegList.append(tagSegInfo2);

         if(1 >= tagSegList.size()) {
             printfExpress();
             bIsDigitPres = false;
             return;
         }
    }

    if(ENUM_SEGNTYPE_SIGN == tagSegList.at(tagSegList.size()-1).eSegType)
    {
        if((DEF_SIGNEQU == sign) && (DEF_SIGNEQU == tagSegList.at(tagSegList.size()-1).strExpress) && (2 >= tagSegList.size()))
        { return; }

        if((DEF_SIGNEQU != sign) && (DEF_SIGNEQU == tagSegList.at(tagSegList.size()-1).strExpress) && (2 >= tagSegList.size()))
        {
            tagSegList.replace(tagSegList.size()-1,tagSegInfo2);
            printfExpress();

            bIsDigitPres = false;
            return;
        }

        if((DEF_SIGNEQU != sign) && (DEF_SIGNEQU == tagSegList.at(tagSegList.size()-1).strExpress))
        {
            tagSegList.removeLast();
            tagSegList.removeLast();
            tagSegList.replace(tagSegList.size()-1,tagSegInfo2);
            printfExpress();

            bIsDigitPres = false;
            return;
        }

        if((DEF_SIGNEQU != sign) && (!bIsDigitPres))
        {
            tagSegList.replace(tagSegList.size()-1,tagSegInfo2);
            printfExpress();

            bIsDigitPres = false;
            return;
        }
    }

    if(2 >= tagSegList.size())
    {
        tagSegList.append(tagSegInfo1);
        tagSegList.append(tagSegInfo2);
    }

    if(DEF_SIGNEQU == sign) { printfExpress(); }

    if(-1 == calculatExpress()) { return; }

    if(DEF_SIGNEQU != sign) { tagSegList.removeAt(1); tagSegList.removeAt(1); printfExpress(); }

    ui->label_result->setText(tagSegList.at(0).strExpress);
    bIsDigitPres = false;

}

//运算符
int CalculatorApp::calculatExpress()
{
    if(2 > tagSegList.size()) {return -1; }

    double dbValue = 0;

    if(DEF_SIGNEQU == tagSegList.at(1).strExpress)
    {
        dbValue = tagSegList.at(0).dbValue;
    }

    if(3 > tagSegList.size()) {return -1; }

    if(DEF_SIGNADD == tagSegList.at(1).strExpress)
    {
        dbValue = tagSegList.at(0).dbValue + tagSegList.at(2).dbValue;
    }else if(DEF_SIGNSUB == tagSegList.at(1).strExpress)
    {
        dbValue = tagSegList.at(0).dbValue - tagSegList.at(2).dbValue;
    }else if(DEF_SIGNMUL == tagSegList.at(1).strExpress)
    {
        dbValue = tagSegList.at(0).dbValue * tagSegList.at(2).dbValue;
    }else if(DEF_SIGNDIV == tagSegList.at(1).strExpress)
    {
        if(0 == tagSegList.at(2).dbValue)
        {
            calculErrorEvent(true);
            printfExpress();
            ui->label_result->setText("除数不能为0");
            return -1;
        }
        dbValue = tagSegList.at(0).dbValue / tagSegList.at(2).dbValue;
    }
    TagSegInfo tagSegInfo;
    tagSegInfo.eSegType = ENUM_SEGNTYPE_VALUE;
    tagSegInfo.dbValue = dbValue;
    tagSegInfo.strExpress = formatDouble(dbValue);
    tagSegList.replace(0,tagSegInfo);
    return 0;
}

3.CalculatorApp.ui

部分QSS

QStackedWidget{
	background-color: rgb(255, 255, 255);
}
QPushButton{
font:  18pt "宋体";
border:0px;
background-color: rgb(239, 242, 247);
}
QPushButton:hover{
border:0px;
background-color: rgb(222, 222, 222);
}
QPushButton:pressed{
border:2px solid rgb(170,170,170);
background-color: rgb(203, 203, 203);
}

运行

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值