Qt制作计算器

这篇具有很好参考价值的文章主要介绍了Qt制作计算器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

运用数据队列中的栈知识,使用Qt制作简易的计算器

Qt制作计算器

功能概述

①支持中缀表达式的基本四则运算

②支持软(软件自带键盘),硬(实体键盘)键盘均可操作,并且按键时触发小特效

③支持查看历史记录

核心思路

将用户输入的表达式分解为运算符操作数两类

运算符:"+", "-", "*", "/", "(", ")"

操作数: 即0~9和小数点的组合

然后设置两个栈:运算符栈optr和操作数栈opnd

首先置操作数栈opnd为空,再先将一个操作符"="压入运算符栈optr中作为栈底元素,然后从左到右遍历用户输入的表达式,表达式是一个字符串,记作infix,只要没有遍历到运算符,那么这一串数字整体就是一个操作数,将其压入opnd栈中,若遍历到运算符,则按下列规则计算:

①若infix[i]的优先级高于optr栈顶的运算符,则将infix[i]压入optr栈中

②若infix[i]的优先级低于optr栈顶的运算符,则弹出optr栈顶的运算符,并从opnd弹出两个操作数,进行相应算术运算后,结果再压入opnd栈中

③若infix[i]是"(",则压入optr栈中

④若infix[i]是")",并且optr栈顶是“(”,则optr退栈,从而消去了左右括号,根据规则②计算

⑤若infix[i]是"=","="优先级最低,则optr退栈,用弹出的运算符与从opnd栈中弹出的两个操作数进行运算,结果压入opnd栈中,这个过程一致持续到optr栈只剩下"="为止,运算结束

                                                          运算符之间的优先级关系

运算符 = *和/ +和-
栈内优先级 0 1 5 3 6
栈外优先级 0 6 4 2 1

功能演示

Qt制作计算器

Qt制作计算器

源代码

#include <QWidget>
#include<QStack>
#include<QDebug>
#include<QKeyEvent>
#include<QPushButton>
#include<QThread>
#include<QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    double jointNum(QString str,int &i);//提取操作数
    int in_priority(char ch);//栈内运算符优先级
    int out_priority(char ch);//栈外运算符优先级
    int compare_priority(int in,int out); //比较栈内外的优先级
    int calcualate_num(double num1,double num2,char oper);//根据运算符计算两个操作数
    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);
    void btn_highlight(QPushButton* btn); //键盘按下高亮
    void btn_release(QPushButton* btn);//键盘释放
    void de_weight(QVector<QString> &vec);//去重

private slots:
    void on_btn_equal_clicked();

    void on_btn_clear_clicked();

    void on_btn_back_clicked();

    void on_btn_1_clicked();

    void on_btn_0_clicked();

    void on_btn_point_clicked();

    void on_btn_add_clicked();

    void on_btn_sub_clicked();

    void on_btn_3_clicked();

    void on_btn_2_clicked();

    void on_btn_multiply_clicked();

    void on_btn_6_clicked();

    void on_btn_5_clicked();

    void on_btn_4_clicked();

    void on_btn_divide_clicked();

    void on_btn_9_clicked();

    void on_btn_8_clicked();

    void on_btn_7_clicked();

    void on_btn_right_clicked();

    void on_btn_left_clicked();

private:
    Ui::Widget *ui;
    QStack<char> optr;//运算符栈
    QStack<double> opnd;//操作数栈
    QString infix;//中缀表达式
    QVector<QString> history_infix;//存储历史记录
};
  #include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("计算器");


}

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

double Widget::jointNum(QString str, int &i)//分割,提取操作数
{
    QString temp;
     ui->le_show->clear();
    double result;
    //138×16-5
    while(str[i]>='0'&&str[i]<='9') //处理小数点之前的部分
    {
        temp += str[i++];
    }
    if(str[i]=='.')//处理小数点之后的部分
    {
        i++;
        temp+='.';
        while(str[i]>='0'&&str[i]<='9') //处理小数点之前的部分
            temp += str[i++];
    }
    result = temp.toDouble();
    return result;
}

int Widget::in_priority(char ch)
{
    int in;
    switch(ch)
    {
        case '=':in = 0;break;
        case '+':in = 3;break;
        case '-':in = 3;break;
        case '*':in = 5;break;
        case '/':in = 5;break;
        case '(':in = 1;break;
        case ')':in = 6;break;
    }
    return in;
}

int Widget::out_priority(char ch)
{
    int out;
    switch(ch)
    {
        case '=':out = 0;break;
        case '+':out = 2;break;
        case '-':out = 2;break;
        case '*':out = 4;break;
        case '/':out = 4;break;
        case '(':out = 6;break;
        case ')':out = 1;break;
    }
    return out;
}

int Widget::compare_priority(int in, int out)
{
    if(in<out)
        return -1;
    else if(in==out)
        return 0;
    else
        return 1;
}

int Widget::calcualate_num(double num1, double num2, char oper)
{
    switch(oper)
    {
    case '+':return num2+num1;
    case '-':return num2-num1;
    case '*':return num2*num1;
    case '/':
    {
        if(num1 == 0)
        {
            QMessageBox::warning(this,"错误","除数为0!!!");
            return 0;
        }

        return num2/num1;
    }
    }
}

void Widget::keyPressEvent(QKeyEvent *event) //键盘事件
{
    infix = ui->le_show->text();
    switch (event->key()) {
    case 0x30:infix+="0";btn_highlight(ui->btn_0);break;
    case 0x31:infix+="1";btn_highlight(ui->btn_1);break;
    case 0x32:infix+="2";btn_highlight(ui->btn_2);break;
    case 0x33:infix+="3";btn_highlight(ui->btn_3);break;
    case 0x34:infix+="4";btn_highlight(ui->btn_4);break;
    case 0x35:infix+="5";btn_highlight(ui->btn_5);break;
    case 0x36:infix+="6";btn_highlight(ui->btn_6);break;
    case 0x37:infix+="7";btn_highlight(ui->btn_7);break;
    case 0x38:infix+="8";btn_highlight(ui->btn_8);break;
    case 0x39:infix+="9";btn_highlight(ui->btn_9);break;
    case 0x2b:infix+="+";btn_highlight(ui->btn_add);break;
    case 0x2d:infix+="-";btn_highlight(ui->btn_sub);break;
    case 0x2a:infix+="*";btn_highlight(ui->btn_multiply);break;
    case 0x2f:infix+="/";btn_highlight(ui->btn_divide);break;
    case 0x28:infix+="(";btn_highlight(ui->btn_left);break;
    case 0x29:infix+=")"; btn_highlight(ui->btn_right);break;
    case 0x2e:infix+="."; btn_highlight(ui->btn_point);break;
    case 0x01000003:on_btn_back_clicked();btn_highlight(ui->btn_back);break; //退格
    case 0x01000004:on_btn_equal_clicked();btn_highlight(ui->btn_equal);break; //等于
    case 0x01000005:on_btn_equal_clicked();btn_highlight(ui->btn_equal);break; //等于
    }

    ui->le_show->setText(infix);
}

void Widget::keyReleaseEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case 0x30:btn_release(ui->btn_0);break;
    case 0x31:btn_release(ui->btn_1);break;
    case 0x32:btn_release(ui->btn_2);break;
    case 0x33:btn_release(ui->btn_3);break;
    case 0x34:btn_release(ui->btn_4);break;
    case 0x35:btn_release(ui->btn_5);break;
    case 0x36:btn_release(ui->btn_6);break;
    case 0x37:btn_release(ui->btn_7);break;
    case 0x38:btn_release(ui->btn_8);break;
    case 0x39:btn_release(ui->btn_9);break;
    case 0x2b:btn_release(ui->btn_add);break;
    case 0x2d:btn_release(ui->btn_sub);break;
    case 0x2a:btn_release(ui->btn_multiply);break;
    case 0x2f:btn_release(ui->btn_divide);break;
    case 0x28:btn_release(ui->btn_left);break;
    case 0x29: btn_release(ui->btn_right);break;
    case 0x2e: btn_release(ui->btn_point);break;
    case 0x01000003:btn_release(ui->btn_back);break; //退格
    case 0x01000004:btn_release(ui->btn_equal);break; //等于
    case 0x01000005:btn_release(ui->btn_equal);break; //等于
    }
}

void Widget::btn_highlight(QPushButton *btn) //按下效果
{
    btn->setStyleSheet("QPushButton{background-color: rgb(200, 200, 200);}");
}

void Widget::btn_release(QPushButton *btn) //释放效果
{
    btn->setStyleSheet("QPushButton{background-color: rgb(240, 240, 240);}");
}

void Widget::de_weight(QVector<QString> &vec) //去重
{
    for(int i = 0;i<vec.size();i++)
    {
        for(int j = i+1;j<vec.size();j++)
        {
            if(vec.at(j) == vec.at(i))
                vec.removeAt(j);
        }
    }
}


void Widget::on_btn_equal_clicked()// =
{
    ui->text_history->clear();
    optr.clear();
    opnd.clear();
    infix = ui->le_show->text(); //获取表达式
    if(infix[0]=="-")
        infix = "0" + infix;
    if(infix.isEmpty())
        return;
    optr.push('='); //=置于栈底,级别最低
    int i = 0;
    double num,a,b;
    char item,ch;
    while(!optr.empty())
    {
        if(infix[i]=="0"||infix[i]=="1"||infix[i]=="2"||infix[i]=="3"||infix[i]=="4"||infix[i]=="5"||
            infix[i]=="6"||infix[i]=="7"||infix[i]=="8"||infix[i]=="9"||infix[i]==".") //数字字符或者.,则拼接并入栈
        {
            num = jointNum(infix,i);
            opnd.push(num);  //数字入栈
        }
        else //操作符
        { //12+13
             item = optr.top();
            switch(compare_priority(in_priority(item),out_priority(infix[i].toLatin1())))//比较运算符优先级,toLatin1:QChar->char
            {
               case -1:
            {
                optr.push(infix[i].toLatin1());//infix[i]优先级高,入栈
                                i++;  //指向下一个字符
            }
                break;
               case 0:
            {
                item = optr.pop(); //删除括号或者=
                if(item!='=')
                    i++;  //指向下一个字符
            }
                break;
               case 1:
            {
                ch = optr.pop(); //infix[i]级别低,弹出一个运算符并弹出两个操作数进行运算后再压栈
                a = opnd.pop();
                b = opnd.pop();
                opnd.push(calcualate_num(a,b,ch)); //运算后结果入栈
            }
            }

        }
    }
    num = opnd.pop();
    if(!opnd.empty())
     qDebug()<<"error";
    QString temp = infix + "="+ QString::number(num);
    history_infix.push_back(temp);
    de_weight(history_infix);//去重
    for(int i = 0;i<history_infix.size();i++)
    {
        ui->text_history->append(history_infix.at(i));
    }
    ui->le_show->setText(QString::number(num));
    infix = QString::number(num);
}

void Widget::on_btn_clear_clicked() //清空
{
    ui->le_show->clear();
    infix.clear();
}

void Widget::on_btn_back_clicked() //退格
{
    infix.remove(infix.length()-1,1);
    ui->le_show->setText(infix);
}

void Widget::on_btn_1_clicked()
{
    infix += "1";
    ui->le_show->setText(infix);
}

void Widget::on_btn_0_clicked()
{
    infix += "0";
    ui->le_show->setText(infix);
}

void Widget::on_btn_point_clicked()
{
    infix += ".";
    ui->le_show->setText(infix);
}

void Widget::on_btn_add_clicked()
{
    infix += "+";
    ui->le_show->setText(infix);
}

void Widget::on_btn_sub_clicked()
{
    infix += "-";
    ui->le_show->setText(infix);
}

void Widget::on_btn_3_clicked()
{
    infix += "3";
    ui->le_show->setText(infix);
}

void Widget::on_btn_2_clicked()
{
    infix += "2";
    ui->le_show->setText(infix);
}

void Widget::on_btn_multiply_clicked()
{
    infix += "*";
    ui->le_show->setText(infix);
}

void Widget::on_btn_6_clicked()
{
    infix += "6";
    ui->le_show->setText(infix);
}

void Widget::on_btn_5_clicked()
{
    infix += "5";
    ui->le_show->setText(infix);
}

void Widget::on_btn_4_clicked()
{
    infix += "4";
    ui->le_show->setText(infix);
}

void Widget::on_btn_divide_clicked()
{
    infix += "/";
    ui->le_show->setText(infix);
}

void Widget::on_btn_9_clicked()
{
    infix += "9";
    ui->le_show->setText(infix);
}

void Widget::on_btn_8_clicked()
{
    infix += "8";
    ui->le_show->setText(infix);
}

void Widget::on_btn_7_clicked()
{
    infix += "7";
    ui->le_show->setText(infix);
}

void Widget::on_btn_right_clicked()
{
    infix += ")";
    ui->le_show->setText(infix);
}

void Widget::on_btn_left_clicked()
{
    infix += "(";
    ui->le_show->setText(infix);
}

项目源码:https://github.com/17359830697/calcualate

这篇文章对你有帮助的话就点个赞吧~

点赞收藏关注就是对我最大的支持~文章来源地址https://www.toymoban.com/news/detail-476082.html

到了这里,关于Qt制作计算器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MFC基于对话框——仿照Windows计算器制作C++简易计算器

    目录 一、界面设计 二、设置成员变量 三、初始化成员变量  四、初始化对话框 ​五、添加控件代码 1.各个数字的代码(0~9) 2.清除功能的代码 3.退格功能的代码 4.加减乘除功能的代码 5.小数点功能的代码 6.正负号功能的代码 7.等于功能的代码 六、源码领取方式 制作好之后

    2024年02月05日
    浏览(70)
  • tkinter制作一个简单计算器

            我们知道tkinter是python常用的UI框架,那么它是如何使用的呢?我们用一个简单的例子来显示它的作用,制作一个简单的计算器,如下图所示。 上图是一个计算器,我们可以看出它一共有20个键,每个按键都表示一个功能,在最上方是一个文本框用来显示数值。接下

    2024年02月11日
    浏览(60)
  • 用python制作一个简易计算器

    这是一个用Python制作简单计算器的教程。你可以根据需要进行更多的改进,例如添加其他运算符或功能。 首先,我们需要创建一个简单的用户界面,用于显示计算器的按键和结果。在Python中,我们可以使用 tkinter 库来创建图形用户界面。创建一个新的Python文件,并将其命名为

    2024年02月11日
    浏览(45)
  • 制作一个简易的计算器app

    github项目地址:https://github.com/13008451162/AndroidMoblieCalculator 笔者的Ui制作的制作的比较麻烦仅供参考,在这里使用了多个LinearLayout对屏幕进行了划分。不建议大家这样做最好使用GridLayout会更加快捷简单 笔者大致划分是这样的: 使用了四个大框,在第四个大框里面有多个小框

    2024年02月15日
    浏览(44)
  • 用Java制作简单的计算器

    本篇文章主要是提供思路,当然文章末尾也又提供了源代码。 代码也是写了几天,重要的理解,不是直接复制粘贴就交作业了。 转载请注明出处,尊重作者劳动成果。 目录 界面的设计: 事件的响应: 计算: 详细代码如下:  总结: 要制作一个简单的计算器,首先就是对

    2024年02月08日
    浏览(46)
  • 微信小程序如何制作简易计算器

    1、首先在浏览器中输入\\\"GitHub - dunizb/wxapp-sCalc: :speech_balloon:微信小程序版简易计算器demo,适合入门练手\\\"网址,输入完成后会进入到以下这个界面: 2、点击旁边绿色的按键 3、点击之后会有以下几个选项: 点击最后一行的Download ZIP,下载一个文件 然后解压一下这个文件,解压完

    2024年04月23日
    浏览(64)
  • QT 简易计算器

    2024年02月09日
    浏览(43)
  • Python制作简易计算器(GUI)---Tkinter

    tkinter模块是Python标准的TK GUI工具包接口,可以实现一些较为简单GUI的创建。 麻雀虽小,五脏俱全 TK工具集使用TCL(Tool Command Language)语言开发 运行相同的程序时,运行速度快于pyqt5 组件能满足基本使用 程序界面较简陋 开发时,使用的语句更短更易懂 Python内置的标准库 Qt框

    2024年02月08日
    浏览(63)
  • python界面开发案例:制作一个计算器软件

    前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 在我们手机上大家都有一个计算器,对吧 那它这功能是怎么实现的呢? 今天我们在电脑上来实现一个电脑端计算器界面~ 开发环境: Python 3.8 / 编译器 Pycharm 2021.2版本 / 编辑器 本文所有模块环境源码教程皆可点击文章下方

    2023年04月16日
    浏览(62)
  • Qt实现简单计算器

    三级项目想用Qt做界面。 为了熟悉一下Qt操作,历时8h做了个计算器。 没用到数据库,布的控件也比较简单。 所以calculator.pro和widget.ui就不放了(太长了占地方) 文件压缩包放在下一篇了,需要自取。 自学时间较短,有很多不足欢迎指正。 ⭐:del按键上的图片用的是绝对路

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包