新的Qt5连接语法

示例

connect使用SIGNAL和SLOT宏的常规语法完全在运行时起作用,这有两个缺点:它具有一些运行时开销(也导致二进制大小的开销),并且没有编译时正确性检查。新语法解决了这两个问题。在检查示例中的语法之前,我们最好了解具体情况。

假设我们正在盖房子,并希望连接电缆。这正是connect函数的作用。信号和插槽是需要此连接的。关键是,如果您进行一个连接,则需要注意进一步重叠的连接。每当将信号连接到插槽时,您都试图告诉编译器,只要信号发出,就只需调用插槽函数即可。这正是发生的情况。

这是一个示例main.cpp

#include <QApplication>
#include <QDebug>
#include <QTimer>

inline void onTick()
{
   qDebug() << "onTick()";
}

struct OnTimerTickListener {
   void onTimerTick()
   {
       qDebug() << "OnTimerTickListener::onTimerTick()";
   }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    OnTimerTickListener listenerObject;

    QTimer timer;
    // 连接到非成员函数
    QObject::connect(&timer, &QTimer::timeout, onTick);
    // 连接到对象成员方法
    QObject::connect(&timer, &QTimer::timeout, &listenerObject, &OnTimerTickListener::onTimerTick);
    // 连接到Lambda
    QObject::connect(&timer, &QTimer::timeout, [](){
        qDebug() << "lambda-onTick";
    });    

    return app.exec();
}

提示:旧语法(SIGNAL/SLOT宏)要求Qt元编译器(MOC)必须针对具有插槽或信号的任何类运行。从编码的角度来看,这意味着此类需要具有Q_OBJECT宏(这表明必须在此类上运行MOC)。

另一方面,新语法仍然需要MOC才能使信号正常工作,但不需要插槽。如果一个类仅具有插槽且没有信号,则它不需要Q_OBJECT宏,因此可以不调用MOC,这不仅减小了最终二进制大小,还减少了编译时间(对于生成的*_moc.cpp文件,不进行MOC调用,也不进行后续的编译器调用)。