Qt5信号与槽C++11风格连接简介
最近在论坛上看到了这个方面的问题,详见这里。
随后浅浅地学习了一下子,看到了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风格连接简介的更多相关文章
- Qt5信号和槽机制
信号槽是 Qt 框架引以为豪的机制之一.熟练使用和理解信号槽,能够设计出解耦的非常漂亮的程序,有利于增强我们的技术设计能力. 所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被 ...
- PyQt Designer中连接信号和槽时为什么只能连接控件自己的信号和槽函数?
老猿在学习ListView组件时,想实现一个在ListView组件中选中一个选择项后触发消息给主窗口,通过主窗口显示当前选中的项的内容. 进入QtDesigner后,设计一个图形界面,其中窗口界面使用 ...
- QT 信号与槽连接
转帖 http://www.cnblogs.com/cnhome/archive/2009/10/01/1577277.html 信号(SIGNAL)和槽(SLOT)是Qt编程的一个重要部分.这个机制 ...
- QT_5_ Qt中信号和槽 + 自定义信号和槽 + lambda 表达式
1.Qt中信号和槽 1.1 需求:点击按钮关闭窗口 1.2 利用connect进行链接 1.3 参数1 信号发送者(指针) 参数2 发送的信号(信号地址) 参数3 信号的接受者(指针) 参数4 处理槽 ...
- PyQt5信号与槽详解
1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...
- Qt信号与槽使用方法最完整总结
在图形界面编程中(参考<C++最好的图形库是什么?>),组件之间如何实现通信是核心的技术内容.Qt 使用了信号与槽的机制,非常的高效.简单.易学,方便开发者的使用.本文详细的介绍了Qt 当 ...
- Qt 信号和槽函数
信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性.当某个信号被发射,就需要调用与之相绑定的槽函数.这与Windows下的消息机制类似,消息机制是基于回调函数.一个回调即是一个函数的 ...
- qt学习:信号,槽
[C.GUI.Qt.4编程(第二版)](加)布兰切特,(英)萨默菲尔德.扫描版[学习库www.xuexi111.com].pdf 信号和槽是Qt编程的基础,它可以让各种对象联系在一起. 1. 使用co ...
- QT信号和槽
QT信号和槽 ============ 信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性.要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler) ...
随机推荐
- Day2:模块初识
一.模块(库) 别人写好的一堆功能,封装起来,你直接导入就可以用,就不用自己再写一次,使用import方法 二.分类:标准库与第三方库 标准库:免安装,导入即可使用,最常用的一些功能 第三方库:需要下 ...
- 杭州"人才新政22条" 硕士来杭工作一次性补贴2万元
转载自原文杭州"人才新政22条" 硕士来杭工作一次性补贴2万元 2016-11-8 继去年1月推出“人才新政27条”后,杭州在引才上又将有新动作.在昨天举行的2016浙江·杭州国际 ...
- Android 使用XML隐藏ActionBar中遇错的解决的方法
今天我在使用Menifest.xml让程序隐藏标题栏是一直出错.主要内容是: You need to use a theme.AppCompat theme(descendant) with this ...
- docker安装及问题处理
1.在Ubuntu的命令行中输入 sudo apt-get install docker.io 2.如果切换到了root用户下 apt-get install docker.io 3.对于新安装的Ub ...
- swift开发网络篇 - post 请求
/** 所有网络请求,统一使用异步请求! 在今后的开发中,如果使用简单的get/head请求,可以用NSURLConnction异步方法 GET查/POST增/PUT改/DELETE删/HEAD GE ...
- 强力推荐微信小程序之简易计算器,很适合小白程序员
原文链接:https://mp.weixin.qq.com/s/gYF7GjTRpeZNoKPAPI9aXA 1 概述 前几日QQ群里的朋友问我有没有计算器小程序案例,今天我们说下小程序计算器,然后就 ...
- linux(debian)系统django配远程连接sqlserver数据库
费了将近一天时间.最终解决,记下来留给须要的人 须要安装的: python-odbc : https://github.com/mkleehammer/pyodbc下载后install 安装pytho ...
- 使用Array和[]创建数组的区别
原文 简书原文:https://www.jianshu.com/p/57a337d20aea 大纲 前言 对使用Array和[]创建数组的区别的解释 个人理解 前言 JS定义数组变量时,在不需要给定数 ...
- web网站如何获取用户的地理位置
web网站如何获取用户的地理位置 一.总结 一句话总结:通过gps知道用户的经度和纬度,然后通过经度和纬度在在地图(google或者百度)上面显示位置. 1.html5如何通过gps知道用户的经度和纬 ...
- ios app初始化和数据迁移的设计思路
整体思路 一般app启动之后,都有一个初始化的过程. 此外兴许app升级,还须要考虑数据迁移.所以初始化和数据迁移的框架.在初期的版本号就要考虑好 总结一下我们的app採取的方案: 1.在持久化的文件 ...