Qt--计算器

11 篇文章 1 订阅

一、功能介绍

能实现退格 CE键(删除最后一个数) C键(清除全部)
实现加减乘除符号不重复输入
完成基本功能,并且能实现多运算符表达式(连续运算)

二、代码

func.h

#ifndef FUNC_H
#define FUNC_H

#include <iostream>
#include <stack>
#include <ctype.h>
#include <vector>
#include <string.h>
using namespace std;

int instack(string c);
int outstack(string c);
vector<string> InfixToPostfix(string str);
bool operation(string tmp,stack<double> &stk);
double postfix2ans(vector<string> exp);
void test();

#endif // FUNC_H

func.cpp

#include"func.h"


int instack(string c)//堆栈内部的运算符优先级
{
    int priority;
    if(c=="(")
        priority=0;
    if(c=="+"||c=="-")
        priority=1;
    if(c=="*"||c=="/")
        priority=2;
    if(c=="#")
        priority=0;
    return priority;
}
int outstack(string c)//堆栈外的运算符优先级
{
    int priority;
    if(c=="(")
        priority=3;
    if(c=="+"||c=="-")
        priority=1;
    if(c=="*"||c=="/")
        priority=2;
    return priority;
}

vector<string> InfixToPostfix(string str)
{
    vector<string> exp,res;
    string tstr="";
    for(std::size_t  i=0;i < str.length();i++)
    {
        //cout<<i<<endl;
        if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='('||str[i]==')')
        {
            if(tstr.length()!=0)
            {
                exp.push_back(tstr);
                tstr="";
            }
            tstr+=str[i];
            exp.push_back(tstr);
            tstr="";
        }
        else
        {
            tstr+=str[i];
        }
    }
    if(tstr.length()!=0)
        exp.push_back(tstr);
    exp.push_back("#");
    stack<string> stk;//存放 运算符和括号的栈
    stk.push("#");
    //string test="#";
    string st="";
    //cout<<exp.size()<<endl;
    //int i=0;
    for(std::size_t  i=0;i<exp.size()-1;i++)//for(i=0,st=exp[i];exp[i]!="#";i++,st=exp[i])
    {
        st=exp[i];
        if(st==")")
        {
            while(stk.top()!="(")
            {
                res.push_back(stk.top());
                stk.pop();
            }
            stk.pop();
        }
        else if(st=="+"||st=="-"||st=="*"||st=="/"||st=="("||st=="#")
        {
            while(instack(stk.top())>=outstack(st))
            {
                res.push_back(stk.top());
                stk.pop();
            }
            stk.push(st);
        }
        else
        {
            res.push_back(st);
        }
    }
    while(!stk.empty())
    {
        if(stk.top()!="#")
        {
            res.push_back(stk.top());
        }
        stk.pop();
    }
    return res;
}

bool operation(string tmp,stack<double> &stk)
{
    double a=0,b=0;//操作数
    if(stk.size()<2)
    {
        cout<<"miss operator number"<<endl;
    }
    else
    {
        a=stk.top();
        stk.pop();
        b=stk.top();
        stk.pop();
        if(tmp=="+")
        {
            stk.push(b+a);
        }
        else if(tmp=="-")
        {
            stk.push(b-a);
        }
        else if(tmp=="*")
        {
            stk.push(b*a);
        }
        else if(tmp=="/")
        {
            if(a==0)
            {
                cout<<"denominator is 0!!!"<<endl;
                return false;
            }
            else
            {
                stk.push(b/a);
            }
        }
    }
    return true;
}

double postfix2ans(vector<string> exp)
{
    string tmp;//临时存放后缀表达式的每一项
    bool flag=true;
    stack<double> stk;
    for(std::size_t  i=0;i<exp.size();i++)
    {
        tmp=exp[i];
        if(tmp=="+"||tmp=="-"||tmp=="*"||tmp=="/")
        {
            flag=operation(tmp,stk);
            if(!flag)
                return 0;
        }
        else
        {
            stk.push(atof(tmp.c_str()));//c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址。
        }
    }
    return stk.top();
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QGridLayout>
#include <QVBoxLayout>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

/* 属性 */
private:
      QPushButton *btnCalculator[24]; // 定义24个按键
      QLineEdit *displayLineEdit; // 显示文本行
      QLineEdit *displayExpressionLineEdit; // 显示表达式
      QVBoxLayout *vLayout; // 垂直布局
      QGridLayout *bottomLayout; // 格子布局

      bool equalFlag; //
      bool firstPressFlag; // 第一次按下标志位
/* 函数 */
private:
      void initWidget(); // 初始化窗口
      void BtnNumberOperator(QString num);// 数字按键操作
/* 信号 */
signals:
      void SignalsrestartCalculator(); // 重新开始计算信号
/* 槽函数 */
private slots:
      /* 按键点击槽函数 */
      void SltBtnNumber0Clicked(); // 按键点击槽函数
      void SltBtnNumber1Clicked(); // 按键点击槽函数
      void SltBtnNumber2Clicked(); // 按键点击槽函数
      void SltBtnNumber3Clicked(); // 按键点击槽函数
      void SltBtnNumber4Clicked(); // 按键点击槽函数
      void SltBtnNumber5Clicked(); // 按键点击槽函数
      void SltBtnNumber6Clicked(); // 按键点击槽函数
      void SltBtnNumber7Clicked(); // 按键点击槽函数
      void SltBtnNumber8Clicked(); // 按键点击槽函数
      void SltBtnNumber9Clicked(); // 按键点击槽函数
      void SltBtnAddClicked(); // 加
      void SltBtnMinusClicked(); // 减
      void SltBtnMultiplyClicked(); //乘
      void SltBtnDivideClicked(); // 除
      void SltBtnPointClicked(); // 小数点
      void SltBtnEqualClicked(); // 等于
      void SltBtnBackSpaceClicked(); // 退格
      void SltBtnCEClicked(); // CE
      void SltBtnCClicked(); // C
      void SltsrestartCalculator(); // 重新开始计算槽函数
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include"func.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    initWidget(); // 初始化窗口
}

Widget::~Widget()
{

}

void Widget::initWidget()
{
    this->setWindowTitle(tr("简易计算器"));        //设置程序标题
    this->setGeometry(0,0,800,480);
    /* 显示行 */
    displayLineEdit = new QLineEdit();      //文本输入与显示
//    displayLineEdit->resize(800,100); // 设置大小
    displayLineEdit->setReadOnly(true); // 设置只读
    displayLineEdit->setFont(QFont("黑体",20)); // 改变字体的大小,对话框也会变化
    /* 显示表达式 */
    displayExpressionLineEdit = new QLineEdit();      //文本输入与显示
    displayExpressionLineEdit->setReadOnly(true); // 设置只读
    displayExpressionLineEdit->setFont(QFont("黑体",16)); // 改变字体的大小,对话框也会变化

    /* 按键 */
    btnCalculator[0] = new QPushButton("%");
    btnCalculator[1] = new QPushButton("CE");
    btnCalculator[2] = new QPushButton("C");
    btnCalculator[3] = new QPushButton("<-");
    btnCalculator[4] = new QPushButton("");
    btnCalculator[5] = new QPushButton("");
    btnCalculator[6] = new QPushButton("");
    btnCalculator[7] = new QPushButton("/");
    btnCalculator[8] = new QPushButton("7");
    btnCalculator[9] = new QPushButton("8");
    btnCalculator[10] = new QPushButton("9");
    btnCalculator[11] = new QPushButton("X");
    btnCalculator[12] = new QPushButton("4");
    btnCalculator[13] = new QPushButton("5");
    btnCalculator[14] = new QPushButton("6");
    btnCalculator[15] = new QPushButton("-");
    btnCalculator[16] = new QPushButton("1");
    btnCalculator[17] = new QPushButton("2");
    btnCalculator[18] = new QPushButton("3");
    btnCalculator[19] = new QPushButton("+");
    btnCalculator[20] = new QPushButton("");
    btnCalculator[21] = new QPushButton("0");
    btnCalculator[22] = new QPushButton(".");
    btnCalculator[23] = new QPushButton("=");

    vLayout = new QVBoxLayout(this);       // 创建主布局为垂直布局
    bottomLayout = new QGridLayout();       // 为按键创建格子布局
    /* 总体布局 */
    vLayout->addWidget(displayExpressionLineEdit);      // 添加文本区域到布局
    vLayout->addWidget(displayLineEdit);      // 添加文本区域到布局

    vLayout->addLayout(bottomLayout);
    /* 下面布局 格子布局 6*4 */
    for(int i = 0; i< 6;i++){
        for(int j = 0; j< 4;j++){
            bottomLayout->addWidget(btnCalculator[i * 4 + j],i,j);
        }
    }

    /* 按键点击槽函数 */
    /* 数字按键 0-9 */
    connect(btnCalculator[21],SIGNAL(clicked()),this,SLOT(SltBtnNumber0Clicked()));     //按键连接
    connect(btnCalculator[16],SIGNAL(clicked()),this,SLOT(SltBtnNumber1Clicked()));
    connect(btnCalculator[17],SIGNAL(clicked()),this,SLOT(SltBtnNumber2Clicked()));
    connect(btnCalculator[18],SIGNAL(clicked()),this,SLOT(SltBtnNumber3Clicked()));
    connect(btnCalculator[12],SIGNAL(clicked()),this,SLOT(SltBtnNumber4Clicked()));
    connect(btnCalculator[13],SIGNAL(clicked()),this,SLOT(SltBtnNumber5Clicked()));
    connect(btnCalculator[14],SIGNAL(clicked()),this,SLOT(SltBtnNumber6Clicked()));
    connect(btnCalculator[8],SIGNAL(clicked()),this,SLOT(SltBtnNumber7Clicked()));
    connect(btnCalculator[9],SIGNAL(clicked()),this,SLOT(SltBtnNumber8Clicked()));
    connect(btnCalculator[10],SIGNAL(clicked()),this,SLOT(SltBtnNumber9Clicked()));
    /* 加减乘除 */
    connect(btnCalculator[19],SIGNAL(clicked()),this,SLOT(SltBtnAddClicked())); // 加
    connect(btnCalculator[15],SIGNAL(clicked()),this,SLOT(SltBtnMinusClicked()));// 减
    connect(btnCalculator[11],SIGNAL(clicked()),this,SLOT(SltBtnMultiplyClicked())); // 乘
    connect(btnCalculator[7],SIGNAL(clicked()),this,SLOT(SltBtnDivideClicked())); // 除
    connect(btnCalculator[22],SIGNAL(clicked()),this,SLOT(SltBtnPointClicked())); // 小数点
    connect(btnCalculator[23],SIGNAL(clicked()),this,SLOT(SltBtnEqualClicked())); // 等于
    connect(btnCalculator[3],SIGNAL(clicked()),this,SLOT(SltBtnBackSpaceClicked())); // 退格
    connect(btnCalculator[1],SIGNAL(clicked()),this,SLOT(SltBtnCEClicked())); // CE键 清除最后输入的一个数字
    connect(btnCalculator[2],SIGNAL(clicked()),this,SLOT(SltBtnCClicked())); // C键 清除全部

    /* 重新开始计算槽函数 */
    connect(this,SIGNAL(SignalsrestartCalculator()),this,SLOT(SltsrestartCalculator()));

    SltsrestartCalculator(); // 重新开始计算
}

/**
 * @brief Widget::SltBtnNumber0Clicked
 * 按键0
 */
void Widget::SltBtnNumber0Clicked()
{
    BtnNumberOperator("0");
}

void Widget::SltBtnNumber1Clicked()
{
    BtnNumberOperator("1");
}

void Widget::SltBtnNumber2Clicked()
{
    BtnNumberOperator("2");
}

void Widget::SltBtnNumber3Clicked()
{
    BtnNumberOperator("3");
}

void Widget::SltBtnNumber4Clicked()
{
    BtnNumberOperator("4");
}

void Widget::SltBtnNumber5Clicked()
{
   BtnNumberOperator("5");
}

void Widget::SltBtnNumber6Clicked()
{
    BtnNumberOperator("6");
}

void Widget::SltBtnNumber7Clicked()
{
   BtnNumberOperator("7");
}

void Widget::SltBtnNumber8Clicked()
{
    BtnNumberOperator("8");
}

void Widget::SltBtnNumber9Clicked()
{
   BtnNumberOperator("9");
}
/**
 * @brief Widget::SltBtnAddClicked
 * + 运算符
 */
void Widget::SltBtnAddClicked()
{
    firstPressFlag = false; // 不是第一次按下
    equalFlag = false; // 等号被打断

    /* 判断符号重复 */
    // 截取最后一个字符
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString laststr = displayLineEdit->text().right(1);
   // qDebug() << laststr << endl;
    /* 判断最后一个字符是不是不是下面这些符号 */
    bool iscontains = operatorSignal.contains(laststr,Qt::CaseSensitive); // 大小写敏感
    if(!iscontains){ // 包含 啥也不管
        displayLineEdit->setAlignment(Qt::AlignLeft); // 左对齐
        displayLineEdit->setText(displayLineEdit->text()+="+");
    }

}

void Widget::SltBtnMinusClicked()
{
    firstPressFlag = false; // 不是第一次按下
    equalFlag = false; // 等号被打断

    /* 判断符号重复 */
    // 截取最后一个字符
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString laststr = displayLineEdit->text().right(1);
   // qDebug() << laststr << endl;
    /* 判断最后一个字符是不是不是下面这些符号 */
    bool iscontains = operatorSignal.contains(laststr,Qt::CaseSensitive); // 大小写敏感
    if(!iscontains){ // 包含 啥也不管
        displayLineEdit->setAlignment(Qt::AlignLeft); // 左对齐
        displayLineEdit->setText(displayLineEdit->text()+="-");
    }
}

void Widget::SltBtnMultiplyClicked()
{
    firstPressFlag = false; // 不是第一次按下
    equalFlag = false; // 等号被打断
    /* 判断符号重复 */
    // 截取最后一个字符
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString laststr = displayLineEdit->text().right(1);
   // qDebug() << laststr << endl;
    /* 判断最后一个字符是不是不是下面这些符号 */
    bool iscontains = operatorSignal.contains(laststr,Qt::CaseSensitive); // 大小写敏感
    if(!iscontains){ // 包含 啥也不管
        displayLineEdit->setAlignment(Qt::AlignLeft); // 左对齐
        displayLineEdit->setText(displayLineEdit->text()+="*");
    }
}

void Widget::SltBtnDivideClicked()
{
    firstPressFlag = false; // 不是第一次按下
    equalFlag = false; // 等号被打断
    /* 判断符号重复 */
    // 截取最后一个字符
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString laststr = displayLineEdit->text().right(1);
   // qDebug() << laststr << endl;
    /* 判断最后一个字符是不是不是下面这些符号 */
    bool iscontains = operatorSignal.contains(laststr,Qt::CaseSensitive); // 大小写敏感
    if(!iscontains){ // 包含 啥也不管
        displayLineEdit->setAlignment(Qt::AlignLeft); // 左对齐
        displayLineEdit->setText(displayLineEdit->text()+="/");
    }
}

void Widget::SltBtnPointClicked()
{
    firstPressFlag = false; // 不是第一次按下
    equalFlag = false; // 等号被打断

    /* 判断符号重复 */
    // 截取最后一个字符
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString laststr = displayLineEdit->text().right(1);
   // qDebug() << laststr << endl;
    /* 判断最后一个字符是不是不是下面这些符号 */
    bool iscontains = operatorSignal.contains(laststr,Qt::CaseSensitive); // 大小写敏感
    if(!iscontains){ // 包含 啥也不管
        displayLineEdit->setAlignment(Qt::AlignLeft); // 左对齐
        displayLineEdit->setText(displayLineEdit->text()+=".");
    }
}

/**
 * @brief Widget::SltBtnEqualClicked
 * = 运算符 获取表达式 计算结果
 */
void Widget::SltBtnEqualClicked()
{
    firstPressFlag = false; // 不是第一次按下
    equalFlag = true; // 等号按下

    /* 剔除最后一个字符不是数字的情况 */
    // 截取最后一个字符
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString laststr = displayLineEdit->text().right(1);
    QString str = displayLineEdit->text(); // 获取表达式
   // qDebug() << laststr << endl;
    /* 判断最后一个字符是不是不是下面这些符号 */
    bool iscontains = operatorSignal.contains(laststr,Qt::CaseSensitive); // 大小写敏感
    if(iscontains){ // 包含  剔除最后一个字符
         str = str.left(str.length() -1); // 删除最后一个字符
    }
    // 如果不包含直接计算下面的
    // 计算结果
    displayLineEdit->setAlignment(Qt::AlignRight); // 靠右对齐
    displayExpressionLineEdit->setAlignment(Qt::AlignRight); // 靠右对齐
    displayLineEdit->setText(str += "="); // 表达式加上等号
    QString res = displayLineEdit->text(); // 获取表达式
    string s = res.toStdString(); // Qt 转化为 c++ 使用的字符串
    double ans = postfix2ans(InfixToPostfix(s)); // 计算结果
    displayExpressionLineEdit->setText(displayLineEdit->text()); // 显示表达式
    displayLineEdit->setText(QString::number(ans)); // 显示结果
}

/**
 * @brief Widget::SltBtnBackSpaceClicked
 * 退格键 去掉最后一个字符
 */
void Widget::SltBtnBackSpaceClicked()
{
    QString res = displayLineEdit->text(); // 获取表达式
    /* 删除最后一个字符 */
    res = res.left(res.length() - 1); // 去掉最后一个字符
    displayLineEdit->setText(res); // 显示在文本行中
}
/**
 * @brief Widget::SltBtnCEClicked
 * CE键 删除掉最后输入的数字
 */
void Widget::SltBtnCEClicked()
{
    QString operatorSignal = "+-*/.="; // 一些操作运算符
    QString numberSignal = "0123456789"; // 数字
    QString str = displayLineEdit->text(); // 获取表达式
    int index = 0; // 记录删除数字的个数
    /* 333  333+ 333+333 */

    while(1){
        /* 判断 字符串是否为空 或者是 333这种纯数字 后面也会为空的情况  */
        if(str == ""){
            displayLineEdit->setText("0");
            firstPressFlag = true; // 第一次按下
            break;
        }
         QString laststr = str.right(1); // 截取最后一个字符
         qDebug() << laststr <<endl;
         /* 判断最后一个字符是不是数字 */
         if(numberSignal.contains(laststr,Qt::CaseSensitive)){ // 是数字 操作
            str = str.left(str.length() -1); // 删除最后一个字符
            index ++;
         }else{ // 不是数字 那就是表达式 退出
             displayLineEdit->setText(displayLineEdit->text().left(displayLineEdit->text().length() - index));
             break;
         }
    }

}
/**
 * @brief Widget::SltBtnCClicked
 * C键 清除全部
 */
void Widget::SltBtnCClicked()
{
    SltsrestartCalculator(); // 重新开始计算
}

/**
 * @brief BtnNumberOperator
 * 数字按键操作 相同的操作 封装一个函数
 */
void Widget::BtnNumberOperator(QString num)
{
    if(equalFlag)// 如果上一个是等号 按下数字就是重新开始
        emit SignalsrestartCalculator(); // 发出信号
    if(firstPressFlag){ // 如果是第一次按下 需要先清除数字0 也就是直接显示这个数字 否则加上这个数字
        firstPressFlag = false;
        displayLineEdit->setText(num); // 显示num
    }
    else
        displayLineEdit->setText(displayLineEdit->text()+= num); // 显示的文字加上num
}

/**
 * @brief Widget::SltsrestartCalculator
 * 重新开始计算槽函数
 */
void Widget::SltsrestartCalculator()
{
    firstPressFlag = true; // 第一次按下
    equalFlag = false; // 等号被打断
    displayLineEdit->clear(); // 清空
    displayExpressionLineEdit->clear(); // 清空
    displayLineEdit->setText("0"); // 默认状态显示一个0
    displayLineEdit->setAlignment(Qt::AlignLeft); // 左对齐
}

main.cpp

#include "widget.h"

#include <QApplication>

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

三、运行

在这里插入图片描述
在这里插入图片描述

参考链接:参考链接

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值