在定義信號槽的時候,傳遞的參數類型如果是自定義類型(自定義class類,或者enum類等),
並且涉及跨線程時,最好先通過qRegisterMetaType()將自定義類型進行注冊,否則會報錯:
QObject::connect: Cannot queue arguments of type 'XXXXXXX'
(Make sure 'ERROR_LEVEL' is registered using qRegisterMetaType().)
1.為什么自定義類型信號槽在跨線程會報錯?
因為跨線程時,當發送方信號發出時,此時接受對象所在的線程未取得控制權,所以需要發送方需要將
信號放在信號隊列中儲存發送的參數,QT就會去construct構造對象,而我們定義的是自定義類型,所以需要使用qRegisterMetaType()來注冊,告訴QT怎么去構造對象.
2.如果傳遞的參數類型是指針類型?
不需要進行注冊,因為指針實際傳遞的是指針地址,QT無需去從新construct構造對象,但是需要注意的是,指針指向的地址不能發送完立馬釋放.
3.步驟 (以自定義Text類型為例)
#include <QString> #include <QMetaType> #include <QDebug> class Text { public: Text() { qDebug()<<"Text"; } Text(const Text& t) { this->m_str = t.m_str; } QString m_str; }; Q_DECLARE_METATYPE(Text); //聲明該類
在connect連接信號槽之前調用RegisterMetaType<Text>("Text");告訴QT,Text類型的別名為"Text",當然也可以改為其他別名.
比如:
int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; qRegisterMetaType<Text>("Text"); MyThread t; QObject::connect(&t,SIGNAL(send(Text)),&w,SLOT(recv(Text))); t.start(); w.show(); return a.exec(); }
