新的 Qt5 连接语法

使用 SIGNALSLOT 宏的传统 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;
    // Connecting to a non-member function
    QObject::connect(&timer, &QTimer::timeout, onTick);
    // Connecting to an object member method
    QObject::connect(&timer, &QTimer::timeout, &listenerObject, &OnTimerTickListener::onTimerTick);
    // Connecting to a lambda
    QObject::connect(&timer, &QTimer::timeout, [](){
        qDebug() << "lambda-onTick";
    });    

    return app.exec();
}

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

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