connect(pointer1, pointer2, pointer3, pointer4);
pointer1:指向发送信号的对象的指针
pointer2:发送信号的对象所对应的类的成员函数的指针
pointer3:接收信号的对象的指针
pointer4:接收信号的对象所对应对象的槽函数指针
总结下来就是:
信号:只需声明无需实现,且没有返回值;槽函数:QT5类中任意成员函数,静态函数,全局函数,lambda表达式,槽函数可以有返回值,但只有在作为普通函数调用时才能接受,信号触发调用时无法接受;信号与槽使用函数指针形式传入时格式必须是类名::成员函数名(信号或槽);信号和槽的参数列表顺序必须一致;信号和槽的参数个数可以不一致,但要满足信号的参数个数大于等于槽函数参数个数,槽函数会忽略信号传递的多余参数。例如:
MainWidget.h文件:
class MainWidget : public QWidget { Q_OBJECT public: explicit MainWidget(QWidget *parent = 0); QPushButton * pushButton; SubWidget * subWidget; signals: public slots: void switchWinSlot(); };MainWidget.cpp文件:
MainWidget::MainWidget(QWidget *parent) : QWidget(parent), pushButton(new QPushButton(this)) { pushButton->setText(QStringLiteral("切换至子窗口")); subWidget = new SubWidget; connect(pushButton, &QPushButton::clicked, this, &MainWidget::switchWinSlot); connect(subWidget, &SubWidget::switchWin, this, &MainWidget::switchWinSlot); subWidget->setWindowTitle("sub"); this->setWindowTitle("parent"); this->resize(400, 300); subWidget->resize(400, 300); } void MainWidget::switchWinSlot() { this->setVisible(!this->isVisible()); this->subWidget->setVisible(!subWidget->isVisible()); }subwidget.h文件:
class SubWidget : public QWidget { Q_OBJECT public: explicit SubWidget(QWidget *parent = 0); QPushButton * pushButton; signals: void switchWin(); public slots: };subwidget.cpp文件:
SubWidget::SubWidget(QWidget *parent) : QWidget(parent) { pushButton = new QPushButton(this); pushButton->setText(QStringLiteral("切换至父窗口")); connect(pushButton, &QPushButton::clicked, this, &SubWidget::switchWin); }此例子是子窗口产生clicked信号时会同时产生自定义的switchWin信号,用来实现主窗口与子窗口之间的切换
信号和槽函数可以进行重载,利用Qt5格式连接重载的信号和槽时,应该使用函数指针变量对重载信号或槽进行区分
subwidget.h文件:
class SubWidget : public QWidget { Q_OBJECT public: explicit SubWidget(QWidget *parent = 0); QPushButton * pushButton; signals: void switchWin(); void switchWin(bool); public slots: };subwidget.cpp文件:
SubWidget::SubWidget(QWidget *parent) : QWidget(parent) { pushButton = new QPushButton(this); pushButton->setText(QStringLiteral("切换至父窗口")); void (SubWidget::* pfun)() = &SubWidget::switchWin; void (SubWidget::* pfun2)(bool) = &SubWidget::switchWin; connect(pushButton, &QPushButton::clicked, this, pfun); connect(pushButton, &QPushButton::clicked, this, pfun2); }上述函数指针涉及到类成员函数的函数指针,详见:
http://blog.csdn.net/xiaoyink/article/details/79439676
这是我们对SubClass的switchWin进行了重载,所以也要对mainwidget.cpp中connect连接switchWin信号的代码进行修改,这里我们用另一种方法,使用static_cast<>运算符对函数指针进行类型转换来区别switchWin的重载;
mainwidget.cpp修改如下:
#include "mainwidget.h" #include <QPushButton> #include "subwidget.h" MainWidget::MainWidget(QWidget *parent) : QWidget(parent), pushButton(new QPushButton(this)) { pushButton->setText(QStringLiteral("切换至子窗口")); subWidget = new SubWidget; connect(pushButton, &QPushButton::clicked, this, &MainWidget::switchWinSlot); //connect(subWidget, &SubWidget::switchWin, this, &MainWidget::switchWinSlot);//修改之前 connect(subWidget, static_cast<void(SubWidget::*)()>(&SubWidget::switchWin), this, &MainWidget::switchWinSlot); subWidget->setWindowTitle("sub"); this->setWindowTitle("parent"); this->resize(400, 300); subWidget->resize(400, 300); } void MainWidget::switchWinSlot() { subWidget->setVisible(!subWidget->isVisible()); this->setVisible(!this->isVisible()); }上述涉及到的函数指针和重载函数的结合使用可以参考:
http://blog.csdn.net/xiaoyink/article/details/79441277
也可以利用Qt4中的信号与槽连接机制对重载进行区分,但不推荐使用,因为qt4使用宏定义会将函数名转化成字符串,所以并不会提供编译的错误检查,并且,SLOT()宏要求所有的槽函数必须使用xxx(public) slots:关键字进行修饰,qt4格式如下:
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
connect函数还可以使用lambda表达式,在pro文件中加入CONFIG+=c++11,上述connect语句可以换成
connect(pushButton, &QPushButton::clicked, [=](){ emit switchWin(); });或者
connect(pushButton, &QPushButton::clicked, [this](){ emit this->switchWin(); });关于lambda表达式的用法详见:
http://blog.csdn.net/xiaoyink/article/details/79351350
connect()函数可以自己设置第5个参数:
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)最后一个参数取值及其含义如下:
Qt::AutoConnection (默认)Qt::DirectConnectionQt::QueuedConnectionQt::BlockingQueuedConnection
Qt::UniqueConnection
Qt::AutoConnection:如果信号发送者和接受者在同一个线程,则选用Qt::DirectConnection,如果不在同一个线程,则使用Qt::QueuedConnection做参数;
Qt::DirectConnection:信号发送后,槽函数立即执行,且会将槽函数拉倒信号发送者所在线程执行,所以,发送者和接收者不在同一个线程时,使用此参数要考虑好后果,除非槽函数应该是可重入的,一般禁用这种情况;
Qt::QueuedConnection:信号发送后立即返回,不等槽函数执行完毕,槽函数在接收者所在线程执行,按照接收者线程的正常事件循环队列执行;(The slot is invoked when control returns to the event loop of the receiver's thread.)
Qt::BlockingQueuedConnection:类似Qt::QueuedConnection,只是信号发送后,发送者所在线程阻塞,等待槽函数返回,当发送者和接受者在同一个线程时,应该禁用这种方式,因为他会导致线程死锁,另外如果接收信号的对象所在线程没有事件循环,也会导致发送信号对象所在线程死锁,因为发送的信号无法被事件循环处理,而发送信号的线程却在等待处理结果,所以死锁;
Qt::UniqueConnection:这个标识可以和其他任何标示联合使用(用按位或操作符),它保证一个信号和一个槽之间只能调用一次connect()函数,如果连接已经存在,则调用失败。
