Qt學習記錄--02 Qt的信號槽機制介紹(含Qt5與Qt4的差別對比)

一 閒談:編程

        熟悉Window下編程的小夥伴們,對其消息機制並不陌生, 話說:一切皆消息。它能夠很方便實現不一樣窗體之間的通訊,然而MFC庫將不少底層的消息都屏蔽了,儘管使用戶更加方便、簡易地處理消息,但也讓人特別是沒有Win32編程基的人感到迷茫,不是爲什麼,筆者也是深受其害的。設計模式

        詳細描述就不在此展開,感興趣的請查閱浩瀚如海的資料。。。多線程

 

二 簡要介紹:函數

        基於Qt開發,信號槽是確保正常通訊的主要機制,特別是在多線程開發中,線程函數與界面的通訊是沒法直接進行的,會存在程序崩潰的問題,筆者在實際開發過程當中也遇到過此問題,利用Qt的信號槽機制能夠避免。this

        所謂信號槽,相似於設計模式中的觀察者模式。當某一事件發生以後,好比,點擊了一下PushButton,它就會發出一個信號(signal)。需注意,這種發出是沒有目的的,相似廣播。若是有對象對這個信號感興趣,可使用鏈接(connect)函數進行二者之間的關聯,即:發送者發送信號(signal),接收者(感興趣對象)用本身的一個函數(稱之爲槽(slot))來處理這個信號。同觀察者同樣,一個signal能夠關聯(註冊)多個slot,當信號發出時,被鏈接的槽函數會自動被回調。spa

        connect()函數是信號槽機制的關鍵,下面介紹。線程

 

三 connect()函數:設計

        Qt5與Qt4中對connect()函數的實現有所差別。指針

        首先,看Qt4對其實現的定義:code

bool connect(const QObject *, const char *,
             const QObject *, const char *,
             Qt::ConnectionType);
 
bool connect(const QObject *, const QMetaMethod &,
             const QObject *, const QMetaMethod &,
             Qt::ConnectionType);
 
bool connect(const QObject *, const char *,
             const char *,
             Qt::ConnectionType) const

介紹定義1,參數分別爲:發送者sender信號signal接收者receiver槽slot,最後一個基本不用。sender 類型是const QObject *,signal 的類型是const char *,receiver 類型是const QObject *,slot 類型是const char *。這個函數將 signal 和 slot 做爲字符串處理。

        Qt4使用了SIGNAL和SLOT這兩個宏,將信號和槽的函數名轉換成了字符串。注意,不能將全局函數或者 Lambda 表達式傳入connect()。使用字符串致使了Qt4有如下缺點:一旦出現鏈接不成功的狀況,Qt 4 是沒有編譯錯誤的(由於一切都是字符串,編譯期是不檢查字符串是否匹配),而是在運行時給出錯誤。這無疑會增長程序的不穩定性。

        下面,看Qt5對其實現的定義:

QMetaObject::Connection connect(const QObject *, const char *,
                                const QObject *, const char *,
                                Qt::ConnectionType);
 
QMetaObject::Connection connect(const QObject *, const QMetaMethod &,
                                const QObject *, const QMetaMethod &,
                                Qt::ConnectionType);
 
QMetaObject::Connection connect(const QObject *, const char *,
                                const char *,
                                Qt::ConnectionType) const;
 
QMetaObject::Connection connect(const QObject *, PointerToMemberFunction,
                                const QObject *, PointerToMemberFunction,
                                Qt::ConnectionType)
 
QMetaObject::Connection connect(const QObject *, PointerToMemberFunction,
                                Functor);

第一個,sender 類型是const QObject *,signal 的類型是const char *,receiver 類型是const QObject *,slot 類型是const char *。這個函數將 signal 和 slot 做爲字符串處理,與Qt4相同,應該是爲了兼容性而予以保留的。

        第二個,sender 和 receiver 一樣是const QObject *,可是 signal 和 slot 都是const QMetaMethod &。咱們能夠將每一個函數看作是QMetaMethod的子類。所以,這種寫法可使用QMetaMethod進行類型比對。

        第三個,sender 一樣是const QObject *,signal 和 slot 一樣是const char *,可是卻缺乏了 receiver。這個函數實際上是將 this 指針做爲 receiver,與Qt4相同,應該是爲了兼容性而予以保留的。

        第四個,sender 和 receiver 也都存在,都是const QObject *,可是 signal 和 slot 類型則是PointerToMemberFunction。看這個名字就應該知道,這是指向成員函數的指針。

       第五個,前面兩個參數沒有什麼不一樣,最後一個參數是Functor類型。這個類型能夠接受static 函數、全局函數以及 Lambda 表達式。

       Qt5相比較於Qt4的優點是添加了第4和第5種的重載形式,使得Qt能夠在編譯期進行錯誤檢查,及早發現問題。

相關文章
相關標籤/搜索