線程中通過信號和槽函數傳遞信息的時候,由於用到了自己定義的參數結構,所以使用qRegisterMetaType

如果是自己定義的類型如果想使用signal/slot來傳遞的話,則沒有這麼簡單。直接使用的話,會產生下面這種錯誤:

QObject::connect: Cannot queue arguments of type 'TextAndNumber' (Make sure 'TextAndNumber' is registed using qRegisterMetaType().) 

原因:當一個signal被放到隊列中(queued)時,它的參數(arguments)也會被一起一起放到隊列中(queued起來),這就意味着參數在被傳送到slot之前需要被拷貝、存儲在隊列中(queue)中;爲了能夠在隊列中存儲這些參數(argument),Qt需要去construct、destruct、copy這些對象,而爲了讓Qt知道怎樣去作這些事情,參數的類型需要使用qRegisterMetaType來註冊(如錯誤提示中的說明)

步驟:(以自定義TextAndNumber類型爲例)

自定一種類型,在這個類型的頂部包含:#include <QMetaType>

在類型定義完成後,加入聲明:Q_DECLARE_METATYPE(TextAndNumber);

在main()函數中註冊這種類型:qRegisterMetaType<TextAndNumber>("TextAndNumber");

如果還希望使用這種類型的引用,可同樣要註冊:qRegisterMetaType<TextAndNumber>("TextAndNumber&");

#include <QMetaType>     
//必須包含QMetaType,否則會出現下面錯誤:     
//error: expected constructor, destructor, or type conversion before ‘;’ token     
#include <QString>     
class TextAndNumber {     
public:     
    TextAndNumber();     
    TextAndNumber(int, QString);     
    int count();     
    QString text();     
private:     
    int m_count;     
    QString m_text;     
};     
Q_DECLARE_METATYPE(TextAndNumber);     
#endif // TEXTANDNUMBER_H    

int main(int argc, char *argv[])     
{     
QApplication app(argc, argv); 
    qRegisterMetaType<TextAndNumber>("TextAndNumber");     
    qRegisterMetaType<TextAndNumber>("TextAndNumber&");     
    TextDevice device;     
    TextThread foo("foo"), bar("bar");     
    QObject::connect(&foo, SIGNAL(writeText(TextAndNumber&)), &device, SLOT(write(TextAndNumber&)));     
    QObject::connect(&bar, SIGNAL(writeText(TextAndNumber&)), &device, SLOT(write(TextAndNumber&)));    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章