基于QT的简易计算器(一)

news2024/11/9 2:16:56

目录

  • 0 简介
  • 1.设计原理
  • 1.1界面设计
    • 1.1.1界面基本布局
    • 1.1.2 界面调整和美化
    • 1.1.2 控件重命名
  • 1.2 连接信号和槽
  • 1.3 软件逻辑
    • 1.3.1四则运算
    • 1.3.2 连续运算(不完全)的原理
    • 1.3.3 清屏
    • 1.3.4 退格
    • 1.3.5 等于
    • 1.3.6 小数点
  • 2.总结与拓展

0 简介

最近在学QT,总体感觉和MFC没有太大的区别,自己跟着哔哩哔哩的老师做了个简易计算器。相关资料如下:

课程链接:风骚程序员】QT游戏开发入门到实战课堂视频精讲,QT桌面应用程序开发,史上最全的QT视频教程系统,游戏开发角度讲解QT入门
项目链接:
链接:https://pan.baidu.com/s/1znbxUV1hi065Kncs814-Rw
提取码:cx9j

限于篇幅,项目创建发布的具体方法可能会在后续的帖子中发出,敬请期待。。。

作为基础项目,并没有做过于复杂的功能。只有整数和小数的四则运算。主要内容如下所示:

1.设计原理

1.1界面设计

1.1.1界面基本布局

先拖拽Line Edit控件和Push Button控件到相应位置,然后再做细化和整理。
在这里插入图片描述

1.1.2 界面调整和美化

确定好控件的大致位置后,我们可以选定按钮,然后点击“栅格布局”按钮,自动调整间距。如下图所示。
在这里插入图片描述
然后我们可以调整按键的颜色等属性。以背景色为例

在想要改变样式的控件上方,鼠标右击菜单中选择“改变样式表”,点击“添加颜色”,选择“背景色”然后选择喜欢的颜色即可。
在这里插入图片描述

1.1.2 控件重命名

为了项目开发和维护方便,往往需要对控件进行重命名。所以我们在此对各个控件进行重命名。
直接点击控件,然后在属性列表中修改相应的属性即可。
在这里插入图片描述

1.2 连接信号和槽

由于项目比较小,所以我们将所有信号都绑定到同一个槽函数Onclicked中进行处理。程序如下:

    //绑定数字
    connect(ui->pushButton_0,&QPushButton::clicked,this,[this](){Onclicked(Num, "0");});
    connect(ui->pushButton_1,&QPushButton::clicked,this,[this](){Onclicked(Num, "1");});
    connect(ui->pushButton_2,&QPushButton::clicked,this,[this](){Onclicked(Num, "2");});
    connect(ui->pushButton_3,&QPushButton::clicked,this,[this](){Onclicked(Num, "3");});
    connect(ui->pushButton_4,&QPushButton::clicked,this,[this](){Onclicked(Num, "4");});
    connect(ui->pushButton_5,&QPushButton::clicked,this,[this](){Onclicked(Num, "5");});
    connect(ui->pushButton_6,&QPushButton::clicked,this,[this](){Onclicked(Num, "6");});
    connect(ui->pushButton_7,&QPushButton::clicked,this,[this](){Onclicked(Num, "7");});
    connect(ui->pushButton_8,&QPushButton::clicked,this,[this](){Onclicked(Num, "8");});
    connect(ui->pushButton_9,&QPushButton::clicked,this,[this](){Onclicked(Num, "9");});
    //绑定运算符
    connect(ui->pushButton_plus,&QPushButton::clicked,this,[this](){Onclicked(Op, "+");});
    connect(ui->pushButton_sub,&QPushButton::clicked,this,[this](){Onclicked(Op, "-");});
    connect(ui->pushButton_mul,&QPushButton::clicked,this,[this](){Onclicked(Op, "*");});
    connect(ui->pushButton_div,&QPushButton::clicked,this,[this](){Onclicked(Op, "/");});
    //其他按钮绑定
    connect(ui->pushButton_clear,&QPushButton::clicked,this,[this](){Onclicked(Clear, "Clear");});
    connect(ui->pushButton_backspace,&QPushButton::clicked,this,[this](){Onclicked(BackSpace, "BackSpace");});
    connect(ui->pushButton_equ,&QPushButton::clicked,this,[this](){Onclicked(Equal , "=");});
    connect(ui->pushButton_dot,&QPushButton::clicked,this,[this](){Onclicked(Dot , ".");});

1.3 软件逻辑

1.3.1四则运算

此次我们的软件功能只涉及两个数的运算,所以需要先区分算式中的两个数据
以运算符为分界,运算符之前的数据为第一个数据,之后的为第二个参与运算的数据,如下所示:

            if(mOp.isEmpty())
            {
                mNum1 += _btn;
            }
            else
            {
                mNum2 += _btn;
            }

然后就是四则运算的具体实现,这里我们封装了一个运算函数,来实现具体的功能。

void Widget::Cal_res(bool *is_right, double *res)
{
    if(mNum1.isEmpty() || mNum2.isEmpty() || mOp.isEmpty())
    {
        *is_right = false;
        *res = 0.0;
        return ;
    }
    double num1 = mNum1.toDouble();
    double num2 = mNum2.toDouble();
    double result = 0;
    if(mOp == '+')
        result = num1 + num2;
    else if(mOp == '-')
        result = num1 - num2;
    else if(mOp == '*')
        result = num1 * num2;
    else if(mOp == '/')
    {
        if(num2 != 0)
            result = num1 / num2;
        else
        {
            ui->lineEdit->setText("error!");
            {
                *is_right = 0;
                *res = 0;
                return ;
            }
        }
    }
    ui->lineEdit->setText(QString::number(result));
    *is_right = true;
    *res = result;
    return ;
}

is_right参数来反映是否得到了正确的结果,错误为false,正确为true;
res参数返回具体的计算结果。

  1. 首先是if的条件判断,如果缺少数据或者运算符,此时无法计算,直接返回。
  2. 接下来根据具体的运算符执行相关的逻辑计算,当除数为0时终止计算,并输出error
  3. 得到正确的计算结果,并返回。

1.3.2 连续运算(不完全)的原理

在此次项目中,我们实现了连续运算,但是并未考虑到运算符的优先级等问题,只是在进行下次运算时,自动计算上一个算式的计算结果,所以我们做了如下的处理:

            if(!mNum1.isEmpty())
            {
                if(!mNum2.isEmpty())
                {
                Cal_res(&is_right, &res);
                if(is_right)
                {
                    mNum1 = QString::number(res);
                    mNum2.clear();
                }
                }
                mOp = _btn;
            }

也就是说,直接将上次的运算结果赋值给mNum1 ,然后再执行接下来的运算。

1.3.3 清屏

清除(清屏)的逻辑比较简单,只需将数据清除,使之显示为空即可。

            mNum1.clear();
            mNum2.clear();
            mOp.clear();

后面就是我们显示的语句:

    ui->lineEdit->setText(mNum1 + mOp + mNum2);

1.3.4 退格

退格是非常常见的操作,在写错的时候可以点击退格,然后重新输入需要计算的数据或运算符。退格实现的原理如下:

            if(!mNum2.isEmpty())
                mNum2.chop(1);
            else if(!mOp.isEmpty())
                mOp.chop(1);
            else if(!mNum1.isEmpty())
                mNum1.chop(1);
            else
                return ;

由于我们的算式是mNum1+mOp+mNum2的格式,退格是从后往前逐一删除的,所以要反向判断,如果有相关字符串5,直接将末尾的字符清除,再重新显示即可。

1.3.5 等于

等号就是计算并显示结果,而我们在前面的小节中已经阐述了核心的计算逻辑,接下来直接调用相关的接口即可:

            Cal_res(&is_right, &res);
            mNum1.clear();
            mNum2.clear();
            mOp.clear();
            return ;

我们调用函数得到了相应的结果,然后再将相关的数据清零,以便进行下次计算。

1.3.6 小数点

小数点的添加就比较讲究了,我们先看看实现的具体程序:

            if(mOp.isEmpty())
            {
                if((!mNum1.isEmpty()) && (!mNum1.contains('.')))
                {
                    mNum1 += _btn;
                }
            }
            else
            {
                if((!mNum2.isEmpty()) && (!mNum2.contains('.')))
                {
                    mNum2 += _btn;
                }
            }

也就是说,先判断是否为空,如果没有位值,则小数点将没有任何意义,然后就判断该小数点应该添加的位置,然后完成添加。

2.总结与拓展

显然,这只是一个基本的小项目,还有很多功能值得开发和探索,如果有时间,还会更新后续帖子,并在一下方面做出延伸和拓展,敬请期待。。。

  • 增加更换皮肤的功能
  • 界面可缩放
  • 连续计算时可显示整个算式
  • 增加小括号运算符号
  • 可保存历史(前几次)计算结果
  • 增加键盘输入功能

红色部分不是必须的,但是可以提升使用体验。
蓝色部分是从计算本身的功能出发,需要做出的一些改进。

-----------------------------------------------------------END-------------------------------------------------------------

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字化浪潮下,AI数字人融入多元化应用场景

随着AI数字人技术的发展,各个行业都在不断挖掘数字人更多的潜力,VR全景中的AI数字人功能逐渐成为了一种新颖的用户交互方式。AI数字人将企业的文化、品牌价值、商业服务等充分结合为一体,为企业提供了全新的机会,从客户互动到营销…

VueX中的getters配置项

一、配置getters属性 当我们想对VueX中的state中的数据进行处理,我们就可以使用getter配置项。 就像是组件中的数据和计算属性之间的关系。 const getters { 属性名 (state) { return 处理结果; } } 我们能够直接拿到state进行操作,并返回操作结果。 …

LeetCode——数组 移除元素(Java)

移除元素 简介[简单] 27. 移除元素[简单] 26. 删除有序数组中的重复项[简单] 283. 移动零[简单] 844. 比较含退格的字符串[简单] 977. 有序数组的平方 简介 记录一下自己刷题的历程以及代码。写题过程中参考了 代码随想录。会附上一些个人的思路,如果有错误&#x…

红黑树——插入底层实现【C++】面试重灾区!!

目录 前言 一,概念 定义 二,insert 情况一: 情况二: 情况三: insert代码 三, 红黑树验证(面试题) 产生随机数验证 每日一图区: 前言 AVL树是一棵绝对平衡的二叉搜索树,其…

IM 系统通信系统是什么

IM(Instant Messaging)系统是一种实时通信系统,允许用户通过互联网或内部网络即时发送文本消息、文件、音频、视频和其他类型的数据给其他用户或群组。这类系统通常支持在线状态显示、消息确认、消息历史记录和多端同步等功能,以提…

WEB3 在 React搭建的Dapp中通过redux全局获取并存储用户ETH与自定义token与交易所存储数量

上文 web3 在React dapp中全局管理web3当前登录用户/智能合约等信息中 我们简单操作,将web3的公共信息都存在了window对象上 然后 我们先来启动一下环境 终端输入 ganache -d打开项目 终端输入 truffle migrate --reset在区块链上发布一下智能合约 然后 我们在…

FedAT:分层机制更新的联邦学习

文章链接:FedAT: A Communication-Efficient Federated Learning Method with Asynchronous Tiers under Non-IID Data 发表会议: SC’21 (International Conference for High Performance Computing, Networking, Storage, and Analysis) 高性能计算,体…

Redis安装与常用命令

目录 一、Reids简介 二、Redis安装 2.1 Linux安装 2.2 Windows安装 三、Redis常用命令 3.1 Redis字符串 3.2 Redis哈希(Hash) 3.3 Redis列表(List) 3.4 Redis集合(Set) 一、Reids简介 Redis(Remote Dictiona…

11.Z-Stack协议栈使用

f8wConfig.cfg文件 选择信道、设置PAN ID 选择信道 #define DEFAULT_CHANLIST 0x00000800 DEFAULT_CHANLIST 表明Zigbee模块要工作的网络,当有多个信道参数值进行或操作之后,把结果作为 DEFAULT_CHANLIST值 对于路由器、终端、协调器的意义&#xff1…

【Linux网络】Linux网络抓包工具tcpdump

一、tcpdump介绍 tcpdump 是一个Linux的网络抓包工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。tcpdump 适用于大多数的类Unix系统操作系统(如linux,BSD等)。 二、安装&用法说明 1)安装 $ yum -y install tcpdump2&#…

【知网检索征稿】第九届社会科学与经济发展国际学术会议 (ICSSED 2024)

第九届社会科学与经济发展国际学术会议 (ICSSED 2024) 2024 9th International Conference on Social Sciences and Economic Development 第九届社会科学与经济发展国际学术会议(ICSSED 2024)定于2024年3月22-24日在中国北京隆重举行。会议主要围绕社会科学与经济发展等研究…

Everything结合内网穿透搭建在线资料库,一秒实现随时随地访问

Everythingcpolar搭建在线资料库,实现随时随地访问 文章目录 Everythingcpolar搭建在线资料库,实现随时随地访问前言1.软件安装完成后,打开Everything2.登录cpolar官网 设置空白数据隧道3.将空白数据隧道与本地Everything软件结合起来总结 前…

(免费领源码)Java#MYSQL在线学习平台09650-计算机毕业设计项目选题推荐

目 录 摘要 1 绪论 1.1 选题背景及意义 1.2国内外现状分析 1.3论文结构与章节安排 2 在线学习平台系统分析 2.1 可行性分析 2.2 系统业务流程分析 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 3 在线学习平台总体设计 …

nginx 常用优化配置项教程

本文目录 跨域配置 动静分离 反向代理-负载均衡 配置SLL证书 资源压缩 缓存机制 IP黑白名单 防盗链 大文件传输优化 跨域问题 产生原因 产生跨域问题的主要原因就在于 「同源策略」 ,为了保证用户信息安全,防止恶意网站窃取数据,…

每日一题 2103. 环和杆 (简单)

简单题,直接统计就行 class Solution:def countPoints(self, rings: str) -> int:n len(rings) // 2cnt [[0, 0, 0] for _ in range(10)]for i in range(0, 2*n, 2):if rings[i] "R":cnt[int(rings[i 1])][0] 1if rings[i] "G":cnt[i…

阿里云多款ECS产品全面升级 性能最多提升40%

“阿里云始终围绕‘稳定、安全、性能、成本、弹性’的目标不断创新,为客户创造业务价值。”10月31日,杭州云栖大会上,阿里云弹性计算计算产品线负责人张献涛表示,通过持续的产品和技术创新,阿里云发布了HPC优化实例等多…

conda命令克隆(复制)环境方法及问题解决

背景:与同事进行工作交接,在服务器上想直接拷贝他的环境过来,直接复制anaconda3/envs里的环境包过来后续安装包的时候由于路径是原来的路径会安装到对方环境里,因此使用conda命令来进行环境克隆。 (Linux/服务器中&am…

【广州华锐互动】有机化合物结构3D虚拟展示帮助学生更好地理解和掌握复杂化学知识

随着科技的发展,我们的学习方式正在发生深刻的变化。其中,有机化合物结构3D虚拟展示作为一种新兴的教学方式,正在逐渐被广泛接受和应用。这种新型的展示方式对于提高学生的学习效率,增强学习体验,以及推动化学教育的发…

十六章反射与注解总结

16.1 反射 反射(Reflection)是指在运行时获取类的信息,并可以动态调用类的方法、访问或修改类的属性,以及构造对象的能力。 Java的反射提供了一套API,允许你在运行时检查类的结构、调用类的方法、获取和设置类的属性&…

curl(一)基础

一 基础入门 ① 本文讲解curl的版本 curl支持的协议 国密curl ② 升级curl 后续: 注意新版本的新特性备注: 升级的必要性 yum 升级 curl 源码编译安装curl ③ curl排错参数 1、-v 或 --verbose --> 重点 2、--trace 和 --trace-ascii --…