最近在论坛上看到了这个方面的问题,详见这里。 随后浅浅地学习了一下子,看到了Qt官方论坛上给出的说明,觉得C++11的functional连接方法还是比Qt4既有的宏连接方法有很大不同。 官方论坛的文档:http://doc.qt.io/qt-5/signalsandslots-syntaxes.html
我们在一个简单的Dialog中,安排如下几个信号与槽:
class SSTest : public QDialog
{
- 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);
编译OK,说明,槽的参数可以比信号少。并且,存在着隐含参数转换: 第一行,QByteArray arr 参数被忽略了,因为槽没有参数。 第二行,double c, double d 两个参数,第二个被忽略了,因为槽只有一个int参数。第一个参数被隐含转换。 测试:
emit sgn_test1(QByteArray());
emit sgn_test3(1.7,2.2);
输出:
SSTest::slt_1()
SSTest::slt_3(int s): 1
但是,如果我们把不支持隐含转换的信号与槽连接,则会错误:
connect (this,&SSTest::sgn_test1,this,&SSTest::slt_3);
QByteArray 无法转换为 int, 因此无法通过编译(具体错误与编译器相关):
C:\...\qobjectdefs_impl.h:299: error: 'QByteArray::operator QNoImplicitBoolCast() const' is private within this context
enum { value = sizeof(test(dummy())) == sizeof(int) };
~~~~~^~~~~~~~~~
2.2. 信号唯一,槽重载
我们试着简单连接sgn_test3和slt_2
connect (this,&SSTest::sgn_test3,this,&SSTest::slt_2);
与估计的一样,无法编译:
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);
^
此时,我们采用下面这两种方式之一,即可:
connect (this,&SSTest::sgn_test3,this,static_cast<void(SSTest::*)(double)>(&SSTest::slt_2));
或者(C++14以上)
connect (this,&SSTest::sgn_test3,this,qOverload<double>(&SSTest::slt_2));
这等于强制指定了连接方法。测试:
emit sgn_test3(1.7,2.2);
输出:
SSTest::slt_2(double v): 1.7
2.3. 信号重载、槽重载
有了上面的经验,面对重载已经不怕了:
测试:
emit sgn_test2("haha!");
emit sgn_test2(1);
输出:
SSTest::slt_2(QString s): "haha!"
SSTest::slt_2(double v): 1
SSTest::slt_1()
2.4. 更灵活的lambda表达式
当然,既然Qt5采用的是functional机制,一定可以用lambda:
int p = 100;
connect (this,&SSTest::sgn_test3,[=](double a ,double b)->void{
qDebug()<<(p*a+b);
});
测试:
emit sgn_test3(1.7,2.2);
输出:
172.2
3. 总结
传统的Qt4 Signal-Slot宏连接兼容性好,但是没有编译时检查,往往会由于笔误,产生预料之外的效果。现在,有了C++11 functional的支持,可以借助编译器进行严格的类型检查,明显是有利于调试了。
http://blog.csdn.net/goldenhawking/article/details/78766676
|
请发表评论