//!!! Qt5
#include <QObject>
// newspaper.h
class Newspaper : public QObject
{
Q_OBJECT
public:
Newspaper(const QString & name) :
m_name(name)
{
}
void send() const
{
emit newPaper(m_name);
}
signals:
void newPaper(const QString &name) const;
private:
QString m_name;
};
// reader.h
#include <QObject>
#include <QDebug>
class Reader : public QObject
{
Q_OBJECT
public:
Reader() {}
void receiveNewspaper(const QString & name) const
{
qDebug() << "Receives Newspaper: " << name;
}
};
// main.cpp
#include <QCoreApplication>
#include "newspaper.h"
#include "reader.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Newspaper newspaper("Newspaper A");
Reader reader;
QObject::connect(&newspaper, &Newspaper::newPaper,
&reader, &Reader::receiveNewspaper);
newspaper.send();
return app.exec();
}
上面connect()函数可以正常绑定信号槽,但是信号如同普通成员函数一样也支持重载,添加如下信号:
void newPaper(const QString &name, const QDate &date);
按照前面的写法,编译器会报出一个错误:由于这个函数(注意,信号实际也是一个普通的函数)有重载,因此不能用一个取址操作符获取其地址。在 Qt 4 中,我们使用SIGNAL和SLOT两个宏来连接信号槽。如果有一个带有两个参数的信号,由于其信号槽的连接是带参数的,所以connect()函数使用Qt4的风格编写是没有问题的,代码如下:
QObject::connect(&newspaper, SIGNAL(newPaper(QString, QDate)),
&reader, SLOT(receiveNewspaper(QString, QDate)));
但Qt5信号槽连接不带参数,此种场景下,之前讲述的类成员(非静态)函数指针便派上用场了:
void (Newspaper:: *newPaperNameDate)(const QString &, const QDate &) = &Newspaper::newPaper;
QObject::connect(&newspaper, newPaperNameDate,
&reader, &Reader::receiveNewspaper);
根本原因是,我们指明了函数类型,使编译器能够准确定位。当然你也可以直接声明(类型转换):
QObject::connect(&newspaper, (void (Newspaper:: *)(const QString &, const QDate &))&Newspaper::newPaper,
&reader, &Reader::receiveNewspaper);