最近在论坛上看到了这个方面的问题,详见这里。 
随后浅浅地学习了一下子,看到了Qt官方论坛上给出的说明,觉得C++11的functional连接方法还是比Qt4既有的宏连接方法有很大不同。 
官方论坛的文档:http://doc.qt.io/qt-5/signalsandslots-syntaxes.html

1.实验代码

我们在一个简单的Dialog中,安排如下几个信号与槽:

class SSTest : public QDialog
{
//...
signals:
void sgn_test1(QByteArray arr);
void sgn_test2(int n);
void sgn_test2(QString s);
void sgn_test3(double c, double d);
public slots:
void slt_1();
void slt_2(double v);
void slt_2(QString s);
void slt_3(int s);
//...
}; //cpp
//......
void SSTest::slt_1()
{
qDebug()<<"SSTest::slt_1()";
}
void SSTest::slt_2(double v)
{
qDebug()<<"SSTest::slt_2(double v):"<<v;
}
void SSTest::slt_2(QString s)
{
qDebug()<<"SSTest::slt_2(QString s):"<<s;
}
void SSTest::slt_3(int s)
{
qDebug()<<"SSTest::slt_3(int s):"<<s;
}
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

而后,在构造函数中,直接采用文档所述方法,进行连接.

2.各类情况测试

2.1. 信号、槽均无重载

此类情况,对应 sgn_test1、slt_1 
直接连接即可:

connect (this,&SSTest::sgn_test1,this,&SSTest::slt_1);
connect (this,&SSTest::sgn_test3,this,&SSTest::slt_3);
  • 1
  • 2

编译OK,说明,槽的参数可以比信号少。并且,存在着隐含参数转换: 
第一行,QByteArray arr 参数被忽略了,因为槽没有参数。 
第二行,double c, double d 两个参数,第二个被忽略了,因为槽只有一个int参数。第一个参数被隐含转换。 
测试:

    emit sgn_test1(QByteArray());
emit sgn_test3(1.7,2.2);
  • 1
  • 2

输出:

SSTest::slt_1()
SSTest::slt_3(int s): 1
  • 1
  • 2

但是,如果我们把不支持隐含转换的信号与槽连接,则会错误:

connect (this,&SSTest::sgn_test1,this,&SSTest::slt_3);
  • 1

QByteArray 无法转换为 int, 因此无法通过编译(具体错误与编译器相关):

C:\...\qobjectdefs_impl.h:299: error: 'QByteArray::operator QNoImplicitBoolCast() const' is private within this context
enum { value = sizeof(test(dummy())) == sizeof(int) };
~~~~~^~~~~~~~~~
  • 1
  • 2
  • 3

2.2. 信号唯一,槽重载

我们试着简单连接sgn_test3和slt_2

connect (this,&SSTest::sgn_test3,this,&SSTest::slt_2);
  • 1

与估计的一样,无法编译:

C:\...\sstest.cpp:15: error: no matching function for call to 'SSTest::connect(SSTest*, void (SSTest::*)(double, double), SSTest*, <unresolved overloaded function type>)'
connect (this,&SSTest::sgn_test3,this,&SSTest::slt_2);
^
  • 1
  • 2
  • 3

此时,我们采用下面这两种方式之一,即可:

connect (this,&SSTest::sgn_test3,this,static_cast<void(SSTest::*)(double)>(&SSTest::slt_2));
  • 1

或者(C++14以上)

connect (this,&SSTest::sgn_test3,this,qOverload<double>(&SSTest::slt_2));
  • 1

这等于强制指定了连接方法。测试:

emit sgn_test3(1.7,2.2);
  • 1

输出:

SSTest::slt_2(double v): 1.7
  • 1

2.3. 信号重载、槽重载

有了上面的经验,面对重载已经不怕了:

//C++14风格同时指定信号、槽的参数表
connect (this,qOverload<QString>(&SSTest::sgn_test2),this,qOverload<QString>(&SSTest::slt_2)); //static_cast风格同时指定信号、槽的参数表
connect (this,static_cast<void(SSTest::*)(int)>(&SSTest::sgn_test2),this,static_cast<void(SSTest::*)(double)>(&SSTest::slt_2)); //信号重载,连接到单一的槽
connect (this,static_cast<void(SSTest::*)(int)>(&SSTest::sgn_test2),this,&SSTest::slt_1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

测试:

emit sgn_test2("haha!");
emit sgn_test2(1);
  • 1
  • 2

输出:

SSTest::slt_2(QString s): "haha!"
SSTest::slt_2(double v): 1
SSTest::slt_1()
  • 1
  • 2
  • 3

2.4. 更灵活的lambda表达式

当然,既然Qt5采用的是functional机制,一定可以用lambda:

int p = 100;
connect (this,&SSTest::sgn_test3,[=](double a ,double b)->void{
qDebug()<<(p*a+b);
});
  • 1
  • 2
  • 3
  • 4

测试:

emit sgn_test3(1.7,2.2);
  • 1

输出:

172.2
  • 1

3. 总结

传统的Qt4 Signal-Slot宏连接兼容性好,但是没有编译时检查,往往会由于笔误,产生预料之外的效果。现在,有了C++11 functional的支持,可以借助编译器进行严格的类型检查,明显是有利于调试了。

http://blog.csdn.net/goldenhawking/article/details/78766676

Qt5信号与槽C++11风格连接简介的更多相关文章

  1. Qt5信号和槽机制

    信号槽是 Qt 框架引以为豪的机制之一.熟练使用和理解信号槽,能够设计出解耦的非常漂亮的程序,有利于增强我们的技术设计能力. 所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被 ...

  2. PyQt Designer中连接信号和槽时为什么只能连接控件自己的信号和槽函数?

    老猿在学习ListView组件时,想实现一个在ListView组件中选中一个选择项后触发消息给主窗口,通过主窗口显示当前选中的项的内容. 进入QtDesigner后,设计一个图形界面,其中窗口界面使用 ...

  3. QT 信号与槽连接

    转帖 http://www.cnblogs.com/cnhome/archive/2009/10/01/1577277.html 信号(SIGNAL)和槽(SLOT)是Qt编程的一个重要部分.这个机制 ...

  4. QT_5_ Qt中信号和槽 + 自定义信号和槽 + lambda 表达式

    1.Qt中信号和槽 1.1 需求:点击按钮关闭窗口 1.2 利用connect进行链接 1.3 参数1 信号发送者(指针) 参数2 发送的信号(信号地址) 参数3 信号的接受者(指针) 参数4 处理槽 ...

  5. PyQt5信号与槽详解

    1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...

  6. Qt信号与槽使用方法最完整总结

    在图形界面编程中(参考<C++最好的图形库是什么?>),组件之间如何实现通信是核心的技术内容.Qt 使用了信号与槽的机制,非常的高效.简单.易学,方便开发者的使用.本文详细的介绍了Qt 当 ...

  7. Qt 信号和槽函数

    信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性.当某个信号被发射,就需要调用与之相绑定的槽函数.这与Windows下的消息机制类似,消息机制是基于回调函数.一个回调即是一个函数的 ...

  8. qt学习:信号,槽

    [C.GUI.Qt.4编程(第二版)](加)布兰切特,(英)萨默菲尔德.扫描版[学习库www.xuexi111.com].pdf 信号和槽是Qt编程的基础,它可以让各种对象联系在一起. 1. 使用co ...

  9. QT信号和槽

    QT信号和槽 ============ 信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性.要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler) ...

随机推荐

  1. 【Educational Codeforces Round 31 B】Japanese Crosswords Strike Back

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 所有数字的和加上n-1,如果为x则唯一,否则不唯一 [代码] #include <bits/stdc++.h> usin ...

  2. dataTable() 与 DataTable() 的差别与处理方式

    jQuery dataTable的初始化有两种方式: var dataTable = $('#example').dataTable(); 与 var DataTable = $('#example' ...

  3. cURL(wget)—— 测试 RESTful 接口及模拟 GET/POST/PUT/DELETE/OPTIONS 请求

    cURL 是一个简单的 http 命令行工具.与最优秀的 Unix 工具一样,在设计之时,cURL 是个小型程序,功能十分专一,而且是故意为之,仅用于访问 http 服务器.(在 Linux 中,可以 ...

  4. 2016最新CocoaPods安装与使用

    前言 是不是已经厌烦了将各种库拖拽到Xcode项目中?那么,CocoaPods的出现就帮你解决了这一问题.CocoaPods是Objective-C项目中最有名的类库管理工具,可以解决库与库之间的依赖 ...

  5. html的meta标签的charset应该用UTF-8还是utf-8?

    之前我也纠结过写html的时候是用<meta charset="UTF-8"/> 或者是 <meta charset="utf-8"/> ...

  6. Eclipse下配置Ant脚本 自己主动打包带签名的Android apk

    尽管eclipse非常少用了,可是在古老的项目上还是会用到.一个麻烦事是打带签名包的时候.非常不方便.下边纪录下配置ant,自己主动打包带签名apk的过程,作为备忘.(PC环境为MAC) 1,第一步得 ...

  7. js进阶 12-1 jquery的鼠标事件有哪些

    js进阶 12-1 jquery的鼠标事件有哪些 一.总结 一句话总结:1+3*2+1+1,其中里面有两组移入移出,一组和click,总结就是click(3个),hover(5个),mousemove ...

  8. IIS最大并发连接数 = 队列长度 + IIS最大并发工作线程数

    深入理解IIS的多线程工作机制   首先让我们来看看IIS里面的这2个数字:最大并发连接数,队列长度.先说这2个数字在哪里看. 最大并发连接数:在IIS中选中一个网站,右键网站名称,在右键菜单中找到并 ...

  9. 前端js实现打印(导出)excel表格

    产品原型: 图片.png 功能需求:点击导出考勤表格按钮,会自动下载成Excel格式 图片.png 图片.png jsp页面代码: <div class="tools"> ...

  10. 【34.14%】【BZOJ 3110】 [Zjoi2013]K大数查询

    Time Limit: 20 Sec Memory Limit: 512 MB Submit: 5375 Solved: 1835 [Submit][Status][Discuss] Descript ...