Qt5信号与槽C++11风格连接简介
2018-01-10 21:36
417 查看
最近在论坛上看到了这个方面的问题,详见这里。
随后浅浅地学习了一下子,看到了Qt官方论坛上给出的说明,觉得C++11的functional连接方法还是比Qt4既有的宏连接方法有很大不同。
官方论坛的文档:http://doc.qt.io/qt-5/signalsandslots-syntaxes.html
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
而后,在构造函数中,直接采用文档所述方法,进行连接.
直接连接即可:
1
2
编译OK,说明,槽的参数可以比信号少。并且,存在着隐含参数转换:
第一行,QByteArray arr 参数被忽略了,因为槽没有参数。
第二行,double c, double d 两个参数,第二个被忽略了,因为槽只有一个int参数。第一个参数被隐含转换。
测试:
1
2
输出:
1
2
但是,如果我们把不支持隐含转换的信号与槽连接,则会错误:
1
QByteArray 无法转换为 int, 因此无法通过编译(具体错误与编译器相关):
1
2
3
1
与估计的一样,无法编译:
1
2
3
此时,我们采用下面这两种方式之一,即可:
1
或者(C++14以上)
1
这等于强制指定了连接方法。测试:
1
输出:
1
1
2
3
4
5
6
7
8
9
测试:
1
2
输出:
1
2
3
1
2
3
4
测试:
1
输出:
1
http://blog.csdn.net/goldenhawking/article/details/78766676
随后浅浅地学习了一下子,看到了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_2connect (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风格连接简介
- Qt 信号槽多次连接后,会多次触发槽函数
- 贡献自己写的,在linux,arm上的屏幕搜索wifi并连接(qt,多选择,wifi按信号排列)
- QT中代码中与设计器中控件信号与SLOT连接
- Qt多个信号连接到一个槽,在槽中识别信号的发送者方法
- Qt操作两个类中的信号和槽连接
- QT 信号与槽有连接 槽未响应
- Qt跨线程信号和槽的连接
- Qt跨线程信号和槽的连接
- 简单的Qt连接信号与槽
- Qt——信号槽连接:基于字符串与基于函数的连接之间的不同
- QT 信号与槽在不同线程不能连接的问题
- QT设计师中关于信号槽的连接仅仅是connect的连接,不能省略槽的声明
- Qt跨线程信号和槽的连接
- Qt信号与槽连接
- Qt连接信号到子类槽函数提示父类无相应槽函数
- qt信号槽之创建和连接自定义的槽
- Qt中控件的信号与槽是用什么语句连接的?
- 在linux,arm上的屏幕搜索wifi并连接(qt,多选择,wifi按信号排列)转
- QT 信号与槽在不同线程不能连接的问题