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

原文地址:https://www.cnblogs.com/findumars/p/8260905.html

时间: 2024-10-16 16:47:29

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

QT5信号和槽机制(新手日记)

信号和槽是 Qt 编程的一个重要部分. 槽和普通的 c++成员函数很像.它们可以是虚函数(virtual),也可被重载(overload),可 以是公有的(public ),保护的( protective ),也可是私有的( private ),它们可以象任何 c++成员函数一样被调用,可以传递任何类型的参数.不同在于一个槽函数能和一个信号相连接,只 要信号发出了,这个槽函数就会自动被调用. connect 函数语法如下: connect(Obeject1, SIGNAL(signal), Ob

PyQt5信号与槽详解

1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(QWidget): def __init__(self): super(signal,self).__init__() self.initUI() #编辑控件及其关联的信号 def initUI(self): self.resize(300,200) self.setWindowTitle("信号与槽

PyQt 5信号与槽的几种高级玩法

PyQt 5信号与槽的几种高级玩法 http://www.broadview.com.cn/article/824 在Qt中,每一个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制.当信号发射时,连接的槽函数将会自动执行.在PyQt 5中信号与槽通过object.signal.connect()方法连接. PyQt的窗口控件类中有很多内置信号,开发者也可以添加自定义信号.信号与槽具有如下特点. 一个信号可以连接多个槽. 一个信号可以

QT学习小结之信号与槽

信号与槽函数是我们学习QT必备的基础知识,今天跟大家分享我学习QT的一些总结吧. 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯. 槽函数和普通的C++成员函数没有很大的区别.它们也可以使virtual的:可以被重写:可以使public.protected或者private的:可以由其它的C++函数调用:参数可以是任何类型的.如果要说区别,那就是,槽函数可以和一个信号相连接,当这个信号发生时,它可以被自动调用. 信号与槽函数的连接我们可以用connect

Qt Quick快速入门之信号、槽

信号和槽主要用于组件之间的通信,类似于.net和java中的委托. 使用QObject::connect方法将信号与槽关联起来,然后信号的发起者发出信号,接受者中的槽函数就会执行. 比如connect(this,SIGNAL(start()),worker,SLOT(Start())),将当前类中start信号关联到worker对象的Start函数,当我们调用emit this->start()时就发出信号,槽函数就会收到这个信号. connect函数还有第五个参数,这个参数决定信号何时传给槽,

Qt学习总结(C鱼)之信号与槽01

自动关联 第一种自然是手动关联了,只要调用connect函数就能实现自动关联.这里重点讲第二种,自动关联:为了实现槽函数自动进行关联,对于Qt窗口部件已经提供的信号,可按照以下规范命名:void on_<窗口部件名称>_<信号名称>_(<信号参数>); 自动关联只适用于Qt部件已经定义好的信号,如果是程序员自己定义的信号则必须手动关联.还有,对于是在Qt设计器往界面添加的部件,那么就可以直接写上面函数格式,以实现自动关联.但是对于不是在Qt设计器往界面添加的部件,我们就

Qt5 UI信号、槽自动连接的控件重名

Qt5 UI信号.槽自动连接的控件重名 来源 http://blog.csdn.net/goldenhawking/article/details/51865909 对Qt5稍有熟悉的童鞋都知道信号.槽的自动连接机制.该机制使得qt designer 设计的UI中包含的控件,可以不通过显式connect,直接和cpp中的相应槽相关联.该机制的详细文章见 http://doc.qt.io/qt-5/designer-using-a-ui-file.html#automatic-connection

QT5中的信号与槽与C++ 11的function的配合

最近将公司的界面开发库从WX转换到了QT,有了信号和槽,原本我们在使用WX的时候,为了使用信号,我们是使用BOOST的signal2库,到了QT有了信号槽,这个就没什么必要了 但是前段时间使用QT发现QT的信号和槽没有placeholder,也就是占位符,于是信号和槽声明只能严格地一样,比如 void slot(int val); void signal( int val); 但是在signals2,我们可用利用placeholder,及时函数声明不一样,也可用进行connect void sl

第81课 信号与槽的连接方式

1. QObject::connect函数 bool connect(const QObject* sender, //发送者 const char* signal, //信号 const QObject* receiver, //接收者 const char* method, //槽函数 Qt::ConnectionType type = Qt::AutoConnection);//连接方式 2. 深入信号与槽的连接方式 (1)Qt::DirectConnection(直接连接,立即调用):直