QT学习之计算器

网格布局初尝试,快速构建计算器

在这里插入图片描述
项目结构:
在这里插入图片描述

wident.h拖动建立界面,20个button,一个lineedit
布局好后整体网格布局调整,依次给每个案件输入文本,并改objectname方便后期辨识

为了在lineedit显示数字,转到槽,编辑点击事件,如显示“1”

void Widget::on_pushButton1_clicked()
{expression += "1";ui->mainlineEdit->setText(expression);
}

QString expression定义在 wident.h文件 ,定义在类的头文件中,使得expression在类的所有成员函数中都可以直接访问。无论是数字按钮、操作符按钮的点击响应函数,还是计算结果的函数等,都能够方便地使用这个变量来存储和操作表达式

主要看计算部分:

int Widget::Priority(char ch)
{switch(ch){case '(':return 3;case '*':case '/':return 2;case '+':case '-':return 1;default:return 0;}
}

这个函数用于判断操作符的优先级。根据不同的操作符返回不同的优先级值
( 的优先级最高,* 和 / 次之,+ 和 - 最低

接下来,是计算输入的式子:

一、准备工作

创建两个栈:

s_num:用于存储数字。
s_opt:用于存储操作符。

将用户输入的表达式从 QString 转换为 char * 类型的数组 opt,以便后续处理
(因为代码中后续的表达式计算部分使用了一些传统的 C 风格字符串处理)

二、遍历表达式

数字处理:
当遍历到的字符是数字时,不断读取后续连续的数字字符,将其转换为整数。例如,遇到字符 “1” “2” “3”,将其识别为数字 123
将转换后的整数压入 s_num 栈中。

操作符处理:
如果遍历到的字符是操作符(如 “+” “-” “ * ” “/” 等)或 括号:
首先判断s_opt栈是否为空,或者当前操作符的优先级高于s_opt栈顶操作符的优先级,或者遇到左括号 “ ( ” 且当前字符不是右括号 “ ) ”。
如果满足这些条件之一,则将当前操作符压入 s_opt 栈中。

如果遇到右括号 “)”,则不断从s_opt栈中弹出操作符并进行相应计算,直到遇到左括号 “(”,然后将左括号从s_opt栈中弹出。

如果当前操作符的优先级小于等于s_opt栈顶操作符的优先级,或者遇到右括号且s_opt栈顶不是左括号,或者表达式遍历结束且s_opt栈不为空,则从s_opt栈中弹出一个操作符进行计算。

三、计算过程
当从s_opt栈中弹出一个操作符时,根据操作符的类型进行相应的计算:
如果是 “+”,从s_num栈中 弹出两个数字(先弹出的作为第二个操作数,后弹出的作为第一个操作数),进行加法运算,并将结果压入s_num栈中。
如果是 “-”,进行减法运算,注意顺序与加法相反。
如果是 “*”,进行乘法运算。
如果是 “/”,进行除法运算,同样注意顺序。
重复上述过程,直到s_opt栈为空且表达式遍历结束。
四、得到结果
此时s_num栈中只剩下一个数字,即表达式的计算结果。
将这个结果转换为QString类型,并显示在主行编辑框中。同时清空用于存储表达式的字符串expression,为下一次计算做准备。

例子:1+2+(3/3+2)
在这里插入图片描述
以表达式 1 + 2 + (3 / 3 + 2) 为例,来详细解释算法的处理过程。

初始状态
表达式: 1 + 2 + (3 / 3 + 2)

s_num: 操作数栈,初始为空
s_opt: 操作符栈,初始为空
opt: 存储表达式的字符数组
i: 当前字符索引,初始为 0
tmp: 用于累积构建数字,初始为 0

遍历表达式

1、读取 ‘1’:
是数字,tmp = 1
下一个字符是空格或操作符,将 1 推入 s_num
s_num = [1],tmp 重置为 0

2、读取 ‘+’:
是操作符,s_opt 为空,将 ‘+’ 推入 s_opt
s_opt = [‘+’]

3、读取 ‘2’:
是数字,tmp = 2
下一个字符是空格或操作符,将 2 推入 s_num
s_num = [1, 2],tmp 重置为 0

4、读取 ‘+’:
是操作符,优先级与栈顶 ‘+’ 相同
进行计算:num1 = 2,num2 = 1,计算 1 + 2 = 3
将结果 3 推入 s_num
s_num = [3]
将新的 ‘+’ 推入 s_opt
s_opt = [‘+’]

5、读取 ‘(’:
是左括号,直接推入 s_opt
s_opt = [‘+’, ‘(’].

6、读取 ‘3’:
是数字,tmp = 3
下一个字符是空格或操作符,将 3 推入 s_num
s_num = [3, 3],tmp 重置为 0

7、读取 ‘/’:
是操作符,s_opt 栈顶是 ‘(’,将 ‘/’ 推入 s_opt
s_opt = [‘+’, ‘(’, ‘/’].

8、读取 ‘3’:
是数字,tmp = 3
下一个字符是空格或操作符,将 3 推入 s_num。
s_num = [3, 3, 3],tmp 重置为 0.

9、读取 ‘+’:
是操作符,s_opt 栈顶是 ‘/’,优先级较低
进行计算:num1 = 3,num2 = 3,计算 3 / 3 = 1
将结果 1 推入 s_num
s_num = [3, 1]
将 ‘+’ 推入 s_opt
s_opt = [‘+’, ‘(’, ‘+’].

10、读取 ‘2’:
是数字,tmp = 2
下一个字符是空格或操作符,将 2 推入 s_num
s_num = [3, 1, 2],tmp 重置为 0.

11、读取 ‘)’:
处理括号,弹出并计算括号内表达式。
取出 num1 = 2,num2 = 1,计算 1 + 2 = 3
将结果 3 推入 s_num。
s_num = [3, 3]
弹出 ‘(’

12、结束计算:
s_opt 栈中还有 ‘+’
计算 num1 = 3,num2 = 3,计算 3 + 3 = 6
将结果 6 推入 s_num
s_num = [6]
最终结果
s_num 栈顶的值 6 即为最终结果

在这里插入图片描述

代码:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//this->setMaximumSize(200,280);//this->setMinimumSize(200,280);this->setWindowTitle("计算器");QFont f("仿宋",14);ui->mainlineEdit->setFont(f);//按钮放图片//QIcon con("");//ui->pushButton_del->setIcon(con);ui->pushButton_equal->setStyleSheet("background:orange");
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton1_clicked()
{expression += "1";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton2_clicked()
{expression += "2";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton3_clicked()
{expression += "3";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton4_clicked()
{expression += "4";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton5_clicked()
{expression += "5";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton6_clicked()
{expression += "6";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton7_clicked()
{expression += "7";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton8_clicked()
{expression += "8";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton9_clicked()
{expression += "9";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_sum_clicked()
{expression += "+";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_sub_clicked()
{expression += "-";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_mult_clicked()
{expression += "*";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_div_clicked()
{expression += "/";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_left_clicked()
{expression += "(";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_right_clicked()
{expression += ")";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton0_clicked()
{expression += "0";ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_clear_clicked()
{expression.clear();ui->mainlineEdit->clear();
}void Widget::on_pushButton_del_clicked()
{expression.chop(1);ui->mainlineEdit->setText(expression);
}void Widget::on_pushButton_equal_clicked()
{QStack<int> s_num, s_opt;char opt[128] = {0};int i = 0, tmp = 0, num1, num2;//把QString转换成char *QByteArray ba;ba.append(expression);   //把QString转换成QByteArraystrcpy(opt, ba.data());  //data可以把QByteArray转换成const char *while (opt[i] != '\0' || s_opt.empty() != true){if (opt[i] >= '0' && opt[i] <= '9'){tmp = tmp * 10 + opt[i] - '0';i++;if (opt[i] < '0' || opt[i] > '9'){s_num.push(tmp);tmp = 0;}}else           //操作符{if (s_opt.empty() == true || Priority(opt[i]) > Priority(s_opt.top()) ||(s_opt.top() == '(' && opt[i] != ')')){s_opt.push(opt[i]);i++;continue;}if (s_opt.top() == '(' && opt[i] == ')'){s_opt.pop();i++;continue;}if (Priority(opt[i]) <= Priority(s_opt.top()) || (opt[i] == ')' && s_opt.top() != '(') ||(opt[i] == '\0' && s_opt.empty() != true)){char ch = s_opt.top();s_opt.pop();/*减法和除法,先出栈的作为第二个参数   后缀表达式*/switch(ch){case '+':num1 = s_num.top();s_num.pop();num2 = s_num.top();s_num.pop();s_num.push(num1 + num2);break;case '-':num1 = s_num.top();s_num.pop();num2 = s_num.top();s_num.pop();s_num.push(num2 - num1);break;case '*':num1 = s_num.top();s_num.pop();num2 = s_num.top();s_num.pop();s_num.push(num1 * num2);break;case '/':num1 = s_num.top();s_num.pop();num2 = s_num.top();s_num.pop();s_num.push(num2 / num1);break;}}}}ui->mainlineEdit->setText(QString::number(s_num.top()));expression.clear();
}int Widget::Priority(char ch)
{switch(ch){case '(':return 3;case '*':case '/':return 2;case '+':case '-':return 1;default:return 0;}
}

PS:后缀表达式复习
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/417820.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF性能优化之UI虚拟化

文章目录 前言一、VirtualizingStackPanel1.1 虚拟化功能介绍1、在Window中添加一个ListBox控件。2、在设计视图中用鼠标选中ListBox控件并右健依次单击“编辑其他模板”&#xff0d;“编辑项的布局模板”&#xff0d;“编辑副本”。3、查看生成的模板代码。 1.2 虚拟化参数介绍…

F12抓包04:(核心功能)Network接口抓包、定位缺陷

课程大纲 一、录制请求 ① tab导航选择“网络”&#xff08;Network&#xff09;&#xff0c;即可进入网络抓包界面&#xff0c;进入界面默认开启录制模式&#xff0c;显示浏览器当前标签页的请求列表。 ② 查看请求列表&#xff0c;包含了当前标签页执行的所有请求和下载的资…

分支管理

目录 创建分支 切换分支 合并分支 删除分支 合并冲突 创建分支 git branch [分支]指令 创建新的分⽀后&#xff0c;Git 新建了⼀个指针叫dev&#xff0c; * 表⽰当前 HEAD 指向的分⽀是 master 分⽀。另外&#xff0c;可以通过⽬录结构发现&#xff0c;新的 dev 分⽀…

保姆级教学:OC监听网络状态变化 Reachability监听网络变化 ios网络变化

本文主要讲解了,在oc开发中,怎么去使用代码进行网络监听,十分的通俗易懂。 首先,在xcode工程中导入SystemConfiguration框架。 然后导入Reachability.h文件。 Reachability文件 点击下载,也可以按照如下内容创建对应的文件。 Reachability.m //文件名Reachability.m …

多线程 | synchronized的简单使用

synchronized 关键字是 Java 中解决并发问题的一种常用方法&#xff0c;也是最简单的一种方法&#xff0c;其作用有三个: &#xff08;1&#xff09;互斥性&#xff1a;确保线程互斥的访问同步代码 &#xff08;2&#xff09;可见性&#xff1a;保证共享变量的修改能够及时可见…

探索Pyro4:Python中的远程对象通信艺术

文章目录 探索Pyro4&#xff1a;Python中的远程对象通信艺术背景&#xff1a;为何选择Pyro4&#xff1f;Pyro4是什么&#xff1f;如何安装Pyro4&#xff1f;简单的库函数使用方法场景应用示例常见Bug及解决方案总结 探索Pyro4&#xff1a;Python中的远程对象通信艺术 背景&…

C 语言指针与数组的深度解析

目录 ​编辑 一、引言 二、指针的基本概念 1.定义与声明 2.指针的运算 3.指针的作用 三、数组的基本概念 1.定义与声明 2.数组的初始化 3.数组的大小 四、指针与数组的关系 1.数组名作为指针 2.指针与数组的相互转换 3.指针与数组的参数传递 五、指针与数组的高…

深度学习(九)-图像形态操作

仿射变换 仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后&#xff0c;直线仍然是直线&#xff1b;平行性是指图像在完成仿射变换后&#xff0c;平行线仍然是平行线。 平移 镜像 旋转…

[已更新问题二三matlab+python]2024数学建模国赛高教社杯C题:农作物的种植策略 思路代码文章助攻手把手保姆级

发布于9.6 10:00 有问题后续会修正!! 问题一代码展示: 问题二代码结果展示: 问题三代码展示: https://docs.qq.com/doc/DVVVlV0NmcnBDTlVJ问题一部分代码分享: #!/usr/bin/env python # coding: utf-8# In[15]:import pandas as pd# In[16]:# 读取Excel文件 file_path 附件2…

通义灵码助力高校开学第一课,“包”你满意,新学期加油!

通义灵码作为国内领先的 AI 编码工具&#xff0c;近年来在高校中得到了广泛应用和推广。它不仅帮助大学生更高效地学习编程、提高代码质量&#xff0c;还激发了他们的创新思维&#xff0c;并为未来的职业生涯做好了准备。 通义灵码是什么&#xff1f; 通义灵码是一款基于通义…

数据分析新星,DuckDB与Pandas处理大数据速度对比

大家好&#xff0c;Pandas库众所周知&#xff0c;适合数据分析新手入门&#xff0c;但在大数据面前却显得处理缓慢。相比之下&#xff0c;开源的DuckDB以其卓越的列式存储性能&#xff0c;在大数据处理上速度惊人&#xff0c;速度远超Pandas。而且&#xff0c;DuckDB配备了Pyth…

GPT-4o在加密货币情绪动态和行为模式应用

本文研究了加密货币相关讨论中的预测性陈述、希望言论和后悔检测行为&#xff0c;旨在通过少量学习和大语言模型&#xff08;如GPT-4o&#xff09;分析投资者的情绪动态和预测行为。该问题的研究难点包括&#xff1a;数据量有限、资源可用性不足、需要准确分类预测性陈述、希望…

企业精英引领未来,大数据讲座照亮中职学子职业航道

为深化校企合作模式&#xff0c;加速产教融合步伐&#xff0c;搭建起职业教育与职场世界的无缝对接桥梁&#xff0c;唯众企业携手武汉市第二职业教育中心&#xff08;简称“武汉二职”&#xff09;&#xff0c;共同举办了一场别开生面的专题讲座。此次活动不仅促进了企业与学生…

掌握SQLAlchemy:Python数据库的魔法师

文章目录 掌握SQLAlchemy&#xff1a;Python数据库的魔法师背景&#xff1a;为什么选择SQLAlchemy&#xff1f;SQLAlchemy是什么&#xff1f;如何安装SQLAlchemy&#xff1f;五个简单的库函数使用方法1. 创建引擎2. 定义模型3. 创建会话4. 添加数据5. 查询数据 场景应用1. 多表…

vulhub ThinkPHP5 5.0.23远程代码执行漏洞

1.执行以下命令启动靶场环境并在浏览器访问 cd thinkphp/5.0.23-rcedocker-compose up -ddocker ps 2.访问网页172.16.1.26:8080 3.判断是否存在漏洞&#xff1a;访问/index.php?scaptcha页面&#xff0c;会出现如下报错 4.使用HackBar 插件发送 POST 请求 _method__constru…

etcdctl defrag 剔除、添加etcd节点

零、准备工作 find / -name etcdctl cp /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/12/fs/usr/local/bin/etcdctl /usr/local/bin/etcdctlalias ec"etcdctl --endpointshttps://127.0.0.1:2379 --cacert /etc/kubernetes/pki/etcd/ca.crt --…

【杂记】裂脑人实验和语言模型幻觉

【杂记】裂脑人实验和语言模型幻觉 模型的自主意识在哪里&#xff0c;人的自我认知在哪里&#xff1f;自然而然的&#xff0c;“裂脑人” 这个词突然出现在我脑海里。然后随意翻了翻相关的文章&#xff0c;觉得这个问题和目前大模型面临的幻觉问题也高度相关&#xff0c;遂随笔…

macos下的 sed命令安装与使用 gnu-sed

sed命令是我们在linu类系统中非常重要的一个命令, 但是在macos下面默认是没有sed命令的, 不过我们可以通过brew install gnu-sed ( 或者通过 sudo port install gsed )这个软件包来获得这个命令 GNU sed 命令安装 下面2种方式,选择一种安装即可 # brew安装 brew install gn…

栈 | 队列

系统栈主要保存以下内容&#xff1a; 1.局部变量&#xff0c;2.函数的形参和返回值 3.函数的调用关系 一、栈 1.基本概念 栈是一种特殊的线性表&#xff0c;具有线性结构。表尾为栈顶&#xff0c;表头为栈顶。遵循先进后出原则&#xff0c;只能在栈顶进行插入和删除操作。 …

下载Mongodb 4.2.25 版本教程

1、MongoDB 安装包的下载链接 Download MongoDB Community Server | MongoDB 进入如下截图&#xff1a; 2、查找历史版本 往下拉&#xff0c;点击“...”,找到”Archived releases”,点击进入 、 3、下载Mongodb 4.2.25 版本 找到如下图4.2.25版本下载链接&#xff0c;点击就可…