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

表达式的合法性

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

一些限制举例:

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

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

实现部分

常量

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

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函数是特殊函数,无需实现部分。

然后在乘法按钮的槽函数中:

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

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

然后如何处理信号呢?

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

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

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

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写法,之前版本的语法也兼容,不过不太鼓励。因为太不安全了。许多错误只有运行时才发现。因为原来的写法信号和槽都被转换为字符串了,那么我写错了信号或槽函数的名称是同样可以编译通过的,只有运行时才能检测出来。而新语法则能包装在编译期间就检查出错误来。

右括号的处理

另外值得一提的是:右括号的可用性与其他按钮不同,它只于左括号相关,并且一定要与左括号数目相同才合法。所以我在主窗口类里声明了一个整型变量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。

同样的在我们点击了一个左括号后,在槽函数void
MainWindow::on_btnLeft_clicked()中需要对lefts进行加一操作。而当我们点击了一个右括号后需要在槽函数void
MainWindow::on_btnRight_clicked()中对lefts进行减一操作。

================= 本 项 目 文 章 及 源 码 链 接===============

|== Qt计算器开发(一):后缀表达式实现完整数学表达式的计算  ==|

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

|== Qt计算器开发(三):运行效果及项目总结                         ==|

|== Qt计算器源码下载(免积分)                                                   ==|

|== Qt计算器GitHub托管地址(代码会不定期更新,敬请关注)        ==|

=======================================================

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

时间: 2024-12-23 22:31:57

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

Qt计算器开发(三):运行效果及项目总结

运行效果 工程目录 Counter |--- Counter.pro |--- 头文件 |      |--- aboutdialog.h |      `--- mainwindow.h |--- 源文件 |      |--- aboutdialog.cpp |      |--- main.cpp |      `--- mainwindow.cpp `--- UI文件 |--- aboutdialog.ui `--- mainwindow.ui 总结 项目 这个工程的Ui部分我是直接使用

Qt开发之信号槽机制

一.信号槽机制原理 1.如何声明信号槽 Qt头文件中一段的简化版: class Example: public QObject { Q_OBJECT signals: void customSignal(); void customSignal(int i) public slots: void customSlot(); void customSlot(int i); }; 2.宏与MOC源对象 摘录代码: // qobjectdefs.h i. … ii. #define slots iii

VS2008 Qt Designer 中自定义信号槽

一.Qt Designer自定义槽函数 发现:在VS2008 +Qt4.7  中打开ui文件,所用的英文QT Designer工具,没有转到槽函数的功能,不如QtCreator自带的QtDesigner功能齐全,只能Editor已有的信号槽. 发现:在QtCreator中右击某个控件 有"转到槽"功能,就会在.h和.cpp文件中生成我们的自定义槽函数void on_openButton_clicked() 解决方法:在VS2008中,选择某个项目,选择菜单Qt/Creat basic

Qt 编程指南 3 信号槽

https://qtguide.ustclug.org/ 忽略自动补全报的错 在图形界面修改过后,自动补全未必及时读取新加入的控件的信息 1 代码自写 1 在主窗口头文件Qt_tset1.h里声明这个函数FoodIsComing() 2 在主窗口函数文件Qt_tset1.cpp里实现这个函数体FoodIsComing() 3 创建链接执行函数.控件动作触发事件,然后调用函数执行 例如: 按键 的 单击动作 触发 主窗体 中的    FoodIsComing() 函数,并执行. 2 图形 所谓信号

QT学习之路---信号槽

#include<QApplication> #include<QPushButton> int main(int argc,char *argv[]) { QApplication a(argc,argv); QPushButton *button = new QPushButton("Quit"); QObject::connect(button,SIGNAL(clicked()),&a,SLOT(quit())); button->show(

用ISO C++实现自己的信号槽(Qt另类学习)

qtc++objectsignalclassstring 目录(?)[-] Qt信号与槽 引入元对象系统 建立信号槽链接 信号的激活 槽的调用 全家福 零零散散写在后面 Q_OBJECT Connection 其他 有网友抱怨: 哪个大牛能帮帮我,讲解一下信号槽机制的底层实现? 不要那种源码的解析,只要清楚的讲讲是怎么发送信号,怎么去选择相应的槽,再做出反应.也就是类似于一个信号槽的相应流程...求解啊!!! 看了源码,真的是一头雾水...撞墙的心都有了~~~~ 本文使用 ISO C++ 一步一

QT 信号槽 异步事件驱动 单线程 多并发

利用好Qt 模块的异步信号槽,单线程同样可是实现很强悍的的并发能力.应付正常的功能是足够的. 需要注意的是:该模式本质上为 单线程 事件驱动异步模式,所以需要做的事优化你的业务代码构架以应付性能与并发压力需求. (当然能够实现异步事件驱动,在Qt模块内部还是启动了更多的子服务线,但在用户代码层面确实单线程模式). 案例场景: 客户端程序,连接多服务端,接收服务端的上传数据. 20个TCP服务端启动.客户端APP逐个建立连接: 单个服务端上传吞吐:一个PDU 大小: 512*2*20字节    上

Qt 学习之路:深入 Qt5 信号槽新语法

在前面的章节(信号槽和自定义信号槽)中,我们详细介绍了有关 Qt 5 的信号槽新语法.由于这次改动很大,许多以前看起来不是问题的问题接踵而来,因此,我们用单独的一章重新介绍一些 Qt 5 的信号槽新语法. 基本用法 Qt 5 引入了信号槽的新语法:使用函数指针能够获得编译期的类型检查.使用我们在自定义信号槽中设计的Newspaper类,我们来看看其基本语法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

[转]深入理解信号槽机制

原文不可考 来源链接http://blog.csdn.net/liuuze5/article/details/53523463 深入理解信号槽(一) 这篇文章来自于 A Deeper Look at Signals and Slots,Scott Collins 2005.12.19.需要说明的是,我们这里所说的"信号槽"不仅仅是指 Qt 库里面的信号槽,而是站在一个全局的高度,从系统的角度来理解信号槽.所以在这篇文章中,Qt 信号槽仅仅作为一种实现来介绍,我们还将介绍另外一种信号槽的