新的 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 檔案)。