基于Qt5的计算器设计

news2024/11/20 16:25:33

Qt5的信号与槽


描述:信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式(发布-订阅模式)。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。


信号的本质:信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时候Qt对应的窗口类会发出某个信号,以此对用户的挑选做出反应。

槽的本质:在Qt中槽函数是一类特殊的功能的函数,在编码过程中也可以作为类的普通成员函数来使用。之所以称之为槽函数是因为它们还有一个职责就是对Qt框架中产生的信号进行处理。就是对信号作出的响应,对于打篮球的人来说,信号就是别人在起步投篮,你看到的这个动作就是信号,然后你会条件反射的想对其进行封盖,然后起跳,这个动作就是对应的槽
二者如何关联:使用connect函数关联。


函数原型:
QMetaObject::Connection QObject::connect(
const QObject *sender, PointerToMemberFunction signal,
const QObject *receiver, PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection);
参数:

  • sender: 发出信号的对象,也可以传入对象的指针
  • signal: 属于sender对象, 信号是一个函数, 这个参数的类型是函数
    指针, 信号函数地址
  • receiver: 信号接收者,也可以是对象指针
  • method: 属于receiver对象, 当检测到sender发出了signal信号,
    receiver对象调用method方法,信号发出之后的处理动作

// 参数 signal 和 method 都是函数地址, 因此简化之后的 connect() 如下:
connect(const QObject *sender, &QObject::signal,
const QObject *receiver, &QObject::method);

你实际使用过程中,可以直接使用对象,也可以使用对象指针。


计算器程序中的信号与槽

✨我们需要设计数字按键,加减乘除的按键,还有括号,小数点,等于号等等。

在这里插入图片描述

说明:del是删除一个位函数,delall是删除全部位函数,就是计算器的全部清除功能。is是等于号的按键槽函数

✨按钮的槽函数

void MainWindow::pushButton0()
{
    if(strin=="#")
        ui->textEdit1->clear();
   strin+="0";
   ui->textEdit1->textCursor().insertText("0");//textCursor()获取文本光标插入点的位置,后接入函数表示向光标后位置插入0
}

✨其他的数字一样。

✨括号函数的编写

//括号函数的编写

void MainWindow::pushButtonzuo()
{
    if(strin=="#")
        ui->textEdit1->clear();

    char* s=strin.toLocal8Bit().data();
    if (isdigit(s[strlen(s)-1]))//左括号前面为数字的话,则表示输入错误,前面只能是
        QMessageBox::about(this,"输入错误","左括号前面不是直接是数字");
    else
       { strin+="(";
        bracket=1;//表示前面有左括号
        ui->textEdit1->textCursor().insertText("(");}

}

其他括号一样。

✨加减乘除的编写

void MainWindow::pushButton_add()

{

  strin+="+";

  ui->textEdit1->textCursor().insertText("+");

  operror();

}

其他运算符一样

✨删除一位按钮的函数

//删除按钮
void MainWindow::pushButton_del()
{
   strin.chop(1);
   ui->textEdit1->textCursor().deletePreviousChar();
   if(strin=="#")
       ui->textEdit1->setText("0");
   else
        ui->textEdit1->setText(strin.mid(1));
}

✨删除全部位按钮的函数

void MainWindow::pushButton_delall()
{
     strin="#";
   if(strin=="#")
       ui->textEdit1->setText("0");
}

✨运算符检测函数

void MainWindow::operror(int num)

{

    char*s=strin.toLocal8Bit().data();

    if(!isdigit(s[strlen(s)-2])&&s[strlen(s)-2]!=')')

    {

        QMessageBox::about(this,"输入有误","您输入的双目运算符无左值");

        strin.chop(1);

        for(int i=1;i<=num;i++)

            ui->textEdit1->textCursor().deletePreviousChar();



    }

}

✨计算函数

double MainWindow:: cal(const QString& expression)
{

    QStack<double> values;//数值栈
    QStack<char> operatorstack;//操作符栈

    for(int i=0;i<expression.length();i++)
        {

            if(expression.at(i)=='(')
                 operatorstack.push(expression.at(i).toLatin1());//遇到左括号的话就入栈

            else if(expression.at(i) == ')')//如果遇到右括号的话,弹出操作符和操作数,直到遇到左括号。
                {
                     values.push(temp.toDouble());//压入
                    temp="";//复原
                    while(!operatorstack.isEmpty() && operatorstack.top() != '(')//只要不为空,直到左括号
                    {
                        char op = operatorstack.pop();//记录顶部的操作符
                        double num1=values.pop();//记录取出的第一个数
                        double num2=values.pop();//记录取出的第2个数
                        switch(op)//对不同的操作符做不同的处理
                        {
                            case '+': values.push( num1+num2);break;
                            case '-': values.push(num2-num1);break;
                            case '*': values.push(num1*num2) ;break;
                            case '/': if (num1==0)  QMessageBox::about(this,"除数非法","除数不能为0"); else values.push(num2/num1);break;
                            default: throw std::invalid_argument("无效的操作符");break;
                        }
                    }
                    operatorstack.pop();//结束之后把左括号弹出

                    }




            else if(expression.at(i) == '+'||expression.at(i) =='-')//按照优先级进行运算
               {
                         values.push(temp.toDouble());//压入
                         temp="";//复原
             if(!operatorstack.empty() && operatorstack.top() != '(' &&
                              (operatorstack.top() == '*' || operatorstack.top() == '/')) //如果现在的表达式比之前的低就要出栈
                        {
                             char op = operatorstack.top();//记录操作符
                             operatorstack.pop();//弹出操作符
                             double operand1 = values.pop();
                             double operand2 = values.pop();
                             switch(op)//对不同的操作符做不同的处理
                             {
                                 case '+': values.push(operand1+operand2);break;
                                 case '-': values.push (operand2-operand1);break;
                                 case '*': values.push(operand1*operand2) ;break;
                                 case '/': if (operand1==0)  QMessageBox::about(this,"除数非法","除数不能为0"); else values.push(operand2/operand1);break;
                                default: throw std::invalid_argument("无效的操作符");break;
                             }


                        }
               operatorstack.push(expression.at(i).toLatin1());//作为运算之后就把这个运算符进行压入

              }

         else if(expression.at(i) =="*"||expression.at(i) =="/")//一律压入栈
                  {
                    operatorstack.push(expression.at(i).toLatin1());
                    values.push(temp.toDouble());//压入
                    temp="";//复原
                  }

         else if(expression.at(i).isDigit() || expression.at(i)=='.')//如果是数字或者是小数点
                 {

                   temp=temp.append(expression.at(i));

                 }

         else
            {
                qWarning() << "无法识别的字符:" << expression.at(i);
                return 0.0;
           }




        }

    if (!temp.isEmpty())
    {
        values.push(temp.toDouble());
        temp = "";
    }

        // 执行剩余的操作
        while (!operatorstack.isEmpty())
        {
            char op = operatorstack.top();
            operatorstack.pop();
            if (values.size() < 2)
            {   qDebug()<<"value的大小为="<<values.size();
                qWarning() << "表达式格式不正确";
                return 0.0;
            }
            double operand11 = values.pop();
            double operand22 = values.pop();
            switch(op)//对不同的操作符做不同的处理
            {
                case '+': values.push(operand11+operand22);break;
                case '-': values.push (operand22-operand11);break;
                case '*': values.push(operand11*operand22) ;break;
                case '/': if (operand11==0)  QMessageBox::about(this,"除数非法","除数不能为0"); else values.push(operand22/operand11);break;
                default:throw std::invalid_argument("无效的操作符");break;
            }
        }

        // 最终栈中应该只有一个值,即表达式的结果
        if (values.size() == 1 && operatorstack.isEmpty())
        {
            double a=values.top();
            strin="#"+strin.setNum(a);
            return values.top();
        }
        else
        {   qDebug()<<"value的大小为="<<values.size();
            while (!values.isEmpty()) {
                qDebug()<<"数值栈的值为="<<values.pop();

            }
            qWarning() << "表达式格式不正确";
            return 0.0; // 处理格式不正确的情况,返回默认值或者适当的错误处理
        }

}

结果展示:

在这里插入图片描述
初始化的启动界面

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

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

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

相关文章

视图/存储过程/触发器

视图 介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视 图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#xff0c;视图只保存了查询的SQL逻辑&#xff0c;不保存…

手机悬浮提词器怎么设置?分享三个简单的操作方法

在现代社会中&#xff0c;手机已成为人们生活中必不可少的一部分。随着科技的不断发展&#xff0c;手机的功能也越来越强大&#xff0c;如今手机悬浮提词器已成为许多人工作或学习时必备的工具。下面将分享三个简单的操作方法&#xff0c;帮助大家更好地设置手机悬浮提词器。 打…

关于时空数据的培训 GAN:实用指南(第 01/3 部分)

第 1 部分&#xff1a;深入了解 GAN 训练中最臭名昭著的不稳定性。 一、说明 GAN 是迄今为止最受欢迎的深度生成模型&#xff0c;主要是因为它们最近在图像生成任务上产生了令人难以置信的结果。然而&#xff0c;GAN并不容易训练&#xff0c;因为它们的基本设计引入了无数的不稳…

图像处理的创意之旅:逐步攀登Python OpenCV的高峰

目录 介绍OpenCV简介安装OpenCV加载和显示图像图像处理目标检测图像处理的高级应用视频处理综合案例&#xff1a;人脸识别应用总结 介绍 欢迎来到本篇文章&#xff0c;我们将一起探索如何使用Python中的OpenCV库进行图像处理和计算机视觉任务。无论您是初学者还是有一定编程…

Excel VLOOKUP 初学者教程:通过示例学习

目录 前言 一、VLOOKUP的用法 二、应用VLOOKUP的步骤 三、VLOOKUP用于近似匹配 四、在同一个表里放置不同的VLOOKUP函数 结论 前言 Vlookup&#xff08;V 代表“垂直”&#xff09;是 excel 中的内置函数&#xff0c;允许在 excel 的不同列之间建立关系。 换句话说&#x…

运算符——“MySQL数据库”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;小雅兰的内容是MySQL数据库里面的操作符&#xff0c;下面&#xff0c;让我们进入操作符的世界吧&#xff01;&#xff01;&#xff01; 算术运算符 比较运算符 逻辑运算符 位运算符 运算符的优先级 拓展&#xff1a;使用正…

【海思SS626 | 开发环境】编译整个SDK全过程以及问题汇总

目录 一、概述二、解压SDK&#xff0c;打补丁三、安装交叉编译工具✨3.1 安装 aarch64-mix410-linux.tgz✨3.2 安装 cc-riscv32-cfg11-musl-20220523-elf.tar.gz✨3.3 检查工具链版本&#xff0c;打印版本则表示安装成功 四、安装软件包✨4.1 安装软件包✨4.2 安装mtd-utils的依…

Excel VBA 变量,数据类型常量

几乎所有计算机程序中都使用变量&#xff0c;VBA 也不例外。 在过程开始时声明变量是一个好习惯。 这不是必需的&#xff0c;但有助于识别内容的性质&#xff08;文本&#xff0c;​​数据&#xff0c;数字等&#xff09; 在本教程中&#xff0c;您将学习- 一、VBA变量 变量是…

AI助手-百度免费AI助手工具

AI助手是有百度推出的免费AI助手工具&#xff0c;国内无需魔就可以使用的AI工具&#xff0c;而且无限制&#xff0c;和ChatGPT类似的人工智能聊天机器人差不多&#xff0c;内置了各种功能的快捷入口&#xff0c;直接点开即可使用&#xff0c;而且还可以ai作画。 工具地址&…

Flutter快速入门学习(一)

目录 前言 新建项目 项目入口 Dart的入口&#xff08;项目的入口&#xff09; 布局 视图组件 Container&#xff08;容器&#xff09; Text&#xff08;文本&#xff09; Image&#xff08;图片&#xff09; Row&#xff08;水平布局&#xff09;和Column&#xff08…

【项目实战】【已开源】USB2.0 HUB 集线器的制作教程(详细步骤以及电路图解释)

写在前面 本文是一篇关于 USB2.0 HUB 集线器的制作教程&#xff0c;包括详细的步骤以及电路图解释。 本文记录了笔者制作 USB2.0 HUB 集线器的心路历程&#xff0c;希望对你有帮助。 本文以笔记形式呈现&#xff0c;通过搜集互联网多方资料写成&#xff0c;非盈利性质&#xf…

windows系统安装php,运行php

一、安装php 官网&#xff1a;PHP For Windows: Binaries and sources Releases 下载最新的PHP解释器 解压好放入 C:\php 目录文件下 二、配置php 配置环境变量&#xff1a;在CMD命令提示符中输入以下命令&#xff0c;将PHP路径添加到系统环境变量中&#xff0c;以便可以在…

正规股票配资网站的三个明显特点分析

随着股票市场的快速发展&#xff0c;越来越多的投资者开始考虑使用股票配资来增加自己的资金流动性和收益率。然而&#xff0c;在选择股票配资网站时&#xff0c;投资者往往难以辨别哪些网站是正规的&#xff0c;哪些网站存在风险。因此&#xff0c;以下将分析正规股票配资网站…

kafkaStream实时流式计算

2 实时流式计算 2.1 概念 一般流式计算会与批量计算相比较。在流式计算模型中&#xff0c;输入是持续的&#xff0c;可以认为在时间上是无界的&#xff0c;也就意味着&#xff0c;永远拿不到全量数据去做计算。同时&#xff0c;计算结果是持续输出的&#xff0c;也即计算结果…

服务器硬件监控解决方案,提升服务器稳定性

前言 在当今数字化时代&#xff0c;服务器的稳定运行对于企业的核心业务至关重要。为了确保服务器的正常运行并及时发现潜在问题&#xff0c;我们公司开发了一款先进的服务器硬件监控解决方案。本文将深入探讨服务器硬件监控的重要性、解决方案的特点和优势&#xff0c;以及支持…

5基于pytorch的多目标粒子群算法,MOPSO,引导种群逼近真实Pareto前沿,算法运行结束后将外部存档中粒子作为获得的Pareto最优解近似。

基于pytorch的多目标粒子群算法&#xff0c;MOPSO,引导种群逼近真实Pareto前沿&#xff0c;算法运行结束后将外部存档中粒子作为获得的Pareto最优解近似。程序已调通&#xff0c;可以直接运行。 5pytorch多目标粒子群算法最优解5pytorch多目标粒子群算法最优解 (xiaohongshu.co…

VMware vCenter 从6.7跨版本升级至7.0U3N

本文尝试使用 vCenter Server Appliance 管理界面 (VAMI) 进行对vCenter Server Appliance7应用进行小版本升级&#xff0c;从6.7.0.47000升级到7.0.3.01600&#xff08;7.0U3N&#xff09;。 一、升级前的准备工作 1、检查当前运行环境&#xff08;当前为6.7.0.47000&#x…

ES6 特性

一、ES6 1.1 ES6 概念 1.1.1 什么是 ES ES 全称 EcmaScript 是脚本语言的规范JavaScript 是 EcmaScript 的一种实现ES 新特性就是指 JavaScript 的新特性 1.1.2 为什么要使用 ES 语法简单&#xff0c;功能丰富框架开发应用前端开发职位要求 1.1.3 为什么要学习 ES6 ES6 …

docker学习1

Docker jar包环境镜像&#xff0c;镜像存在docker仓库中&#xff0c;随用随取&#xff0c;无需现配环境 docker通过隔离机制&#xff0c;各个镜像之间互不干扰 docker比vm轻量化&#xff0c;每次只需运行镜像即可&#xff0c;镜像占内存小启动快&#xff0c;虚拟机启动慢&…

代码随想录|198.打家劫舍,213.打家劫舍II, 337.打家劫舍 III

198.打家劫舍 思路&#xff1a; 题目要求不偷相邻两家&#xff0c;两种偷法&#xff0c;偷法1是偷前k-1间房子&#xff0c;最后一间不偷&#xff1b;偷法2是偷前k-2间房子和最后一间。 代码实现1 class Solution {public int rob(int[] nums) {//偷法1&#xff1a;偷前k-1间…