表达式的合法性

由于我们的计算器不是单步计算的,所以我们能够一次性输入一个长表达式。然而假设用户输入的长表达式不合法的话,那么就会引发灾难。所以有必要对于用户的输入做一个限制。

一些限制举例:

比方,在输入了左括号以后那么接下来,不能输入运算符。此时运算符要是不可用的状态。在输入了右括号以后不能直接输入数字,此时数字键应该是不可用状态。等等此类的。

在这里我使用了信号与槽的方式来实现。点击不同的button,会发展出不同的信号。在这之后的事,点击button本身无需考虑,这也是信号槽的良好的设计理念造成的效果,符合面向对象的迪米特原则。

实现部分

常量

首先我们先定义五个常量:

const int INIT = 0;
const int DIGIT = 1;
const int OPERA = 2;
const int LEFT = 3;
const int RIGHT = 4;

第一个常量表示初始化,这里也把它作为按键信号,可理解为特殊的按键,由于在最開始的时候,我们不能输入运算符,右括号,所以初始化时运算符,右括号为不可用状态。

信号与槽

主窗体的头文件中声明一句:

signals:void whichBtn(int type);

了解Qt的都知道,信号signal函数是特殊函数,无需实现部分。

然后在乘法button的槽函数中:

void MainWindow::on_btnMuti_clicked()
{QString s = ui->lineEdit->text();ui->lineEdit->setText(s+"*");emit whichBtn(OPERA);
}

上面的ui->lineEdit就是我们计算器的屏幕控件。上面的s就是屏幕上已有的表达式了,点击乘号*button那么表达式后面多一个乘号*。然后发射一个信号whichBtn(OPERA).其它button类似。

然后怎样处理信号呢?

这里我在主窗体类的头文件中又声明了几个槽函数:

    void enableDigit(int type);void enableOp(int type);void enableLeft(int type);void enableRight(int type);void enableEqual(int type);

用来实现button可用与否的实现,比方第一个是运算符可用与否,它的实现代码:

void MainWindow::enableOp(int type)
{bool enable = false;switch(type){case DIGIT:enable = true;break;case INIT:case OPERA:case LEFT:enable = false;break;default:return;}ui->btnMuti->setEnabled(enable);//乘ui->btnDivi->setEnabled(enable);//除ui->btnAdd->setEnabled(enable);//加ui->btnSub->setEnabled(enable);//减
}

连接

最后呢,我们要连接啦。

    connect(this,&MainWindow::whichBtn,&MainWindow::enableOp);connect(this,&MainWindow::whichBtn,&MainWindow::enableLeft);connect(this,&MainWindow::whichBtn,&MainWindow::enableEqual);connect(this,&MainWindow::whichBtn,&MainWindow::enableRight);connect(this,&MainWindow::whichBtn,&MainWindow::enableDigit);

我这里用的是Qt5的新版connect写法,之前版本号的语法也兼容,只是不太鼓舞。由于太不安全了。很多错误仅仅有执行时才发现。由于原来的写法信号和槽都被转换为字符串了,那么我写错了信号或槽函数的名称是相同能够编译通过的,仅仅有执行时才干检測出来。而新语法则能保证在编译期间就检查出错误来。

右括号的处理

另外值得一提的是:右括号的可用性与其它button不同,它仅仅于左括号相关,而且一定要与左括号数目同样才合法。所以我在主窗体类里声明了一个整型变量lefts用于保存左括号的数目。

在右括号可用性的槽函数中:

void MainWindow::enableRight(int type)
{bool enable = false;switch(type){case INIT:case OPERA:break;case LEFT:enable = true;case RIGHT:case DIGIT:if(lefts)enable = true;break;default:return;}ui->btnRight->setEnabled(enable);
}

须要推断lefts是否为零,假设不为零那么右括号可用,enable设为true。
相同的在我们点击了一个左括号后,在槽函数voidMainWindow::on_btnLeft_clicked()中须要对lefts进行加一操作。而当我们点击了一个右括号后须要在槽函数voidMainWindow::on_btnRight_clicked()中对lefts进行减一操作。

================= 本 项 目 文 章 及 源 码 链 接===============
|== Qt计算器开发(一):后缀表达式实现完整数学表达式的计算  ==|
|== Qt计算器开发(二):信号槽实现数学表达式合法性检查         ==|
|== Qt计算器开发(三):执行效果及项目总结                         ==|
|== Qt计算器源代码下载(免积分)                                                   ==|
|== Qt计算器GitHub托管地址(代码会不定期更新,敬请关注)        ==|
=======================================================

Qt计算器开发(二):信号槽实现数学表达式合法性检查相关推荐

  1. QT源码剖析-QT对象通信机制信号槽的绑定具体实现

    本文详细介绍QT核心机制之一 信号和槽. 我们在此根据Qt源代码一步一步探究其信号槽的实现过程. 核心知识点: 模板元编程技术. Qt moc预编译机制. QObject类. 目录 1. QObjec ...

  2. VS2008 Qt Designer 中自定义信号槽

    一.Qt Designer自定义槽函数 发现:在VS2008 +Qt4.7  中打开ui文件,所用的英文QT Designer工具,没有转到槽函数的功能,不如QtCreator自带的QtDesigne ...

  3. linux下qt加载boost,信号槽的实现实例—— Qt 和 Boost

    Qt 的信号槽和 Boost.Signals 由于有着截然不同的设计目标,因此二者的实现.强度也十分不同.将二者混合在一起使用也不是不可能的,我们将在本系统的最后一部分来讨论这个问题. 使用信号槽 信 ...

  4. Qt之connect函数—信号槽连接的几种方式和优缺点

    connect函数在qt中作为连接信号和槽的函数,并不陌生.它目前有以下3种写法: 1.使用SIGNAL和SLOT宏 connect(ui->pushButton,SIGNAL(clicked( ...

  5. Qt——P13 Q4版本信号槽连接

    widget.cpp #include "widget.h" #include "ui_widget.h" #include <QPushButton&g ...

  6. 【Qt学习】04 信号-槽 子窗口向主窗口传递参数

    概述 学习内容:子对话框向主对话框发送消息,使用SIGNAL-SLOT实现. 环境 IDE:Qt creator 4.11.0 编译器:MinGW 5.3.0 32bit for C++ 例子 1.s ...

  7. 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.7 如何连接信号槽

    本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1mN4y137H6 信号和槽要建立连接,本质上是通过 `connect` 函数来连接实现的. 但 ...

  8. Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)

    转载地址: https://blog.csdn.net/nicai888/article/details/51169520 一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说: ...

  9. Qt信号槽之槽函数中获取发送信号对象——sender()

    QObject::sender() 我们如何在槽函数中获取到信号的发送对象呢,使用sender()方法即可获取.但是使用此方法我们需要注意几点: QObject *QObject::sender() ...

最新文章

  1. linux文本编辑nano
  2. Java 连接数据库 JDBCUtil
  3. 王爽 16 位汇编语言学习记录
  4. SAP ABAP的权限检查跟踪(Authorization trace)工具使用步骤介绍
  5. docker 多个mysql_mysql8.0 利用docker容器安装配置多主多从集群
  6. NeurIPS 2021 Transformer部署难?北大华为诺亚提出Vision Transformer的后训练量化方法...
  7. CSS cursor 属性-鼠标形状
  8. android mapping.txt,Android根据mapping.txt还原混淆的代码
  9. android servlet乱码问题,初识 JSP---(Servlet映射 / ServletRequest / get与post区别 / 解决乱码)...
  10. matlab电力系统潮流计算软件matpower_衡真课堂 | 电力系统稳态与暂态分析
  11. 使用mysqldump备份数据库
  12. OFD文件怎么编辑修改?
  13. 无人机航摄地面站航线设计主要参数
  14. 软件工程领域国际会议列表
  15. 通过regsrv32.exe绕过Applocker应用程序白名单的多种方法
  16. tplink怎么进去_在TP-Link工作体验如何?
  17. C#人民币大小写金额转换(C#版本)
  18. Python定义全局变量的用法
  19. Jim Joseph加入Burson Cohn Wolfe,担任新设立的全球职位
  20. 破解 WiFi,获取 WiFi 密码

热门文章

  1. 北欧小国的宏大AI实验: 让1%的人口接受人工智能培训
  2. 上万家物联网公司会被“政策死”吗
  3. 密歇根大学联合谷歌大脑提出,通过「推断语义布局」实现「文本到图像合成」
  4. 德国图宾根大学发布可扩展「对抗黑盒攻击」,仅通过观察决策即可愚弄深度神经网络
  5. 14 岁发现 Bug 兼职游戏开发、拒绝过乔布斯,Dropbox 创始人成为科技创业者的偶像...
  6. 知乎高赞:我的编程能力从什么时候开始突飞猛进的?
  7. 入门一班 20180917 软硬连接
  8. docker容器内部无法ping通域名?
  9. ORACLE的impdp和expdp命令
  10. Microsoft宣布发布GA版Azure Event Grid