如果要在Qt信號槽中使用自定義類型,需要注意使用qRegisterMetaType對自定義類型進行註冊,當然在不跨線程時使用自定義類型signal/slot來傳遞,可能不會出現什麼問題;一旦涉及跨線程就很容易出錯,回想下信號槽的作用就是用來對象與對象之間通信的,難免會跨線程,建議在使用自定義類型利用信號槽通信時,最好先通過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
- 在類型定義完成後,加入聲明
Q_DECLARE_METATYPE(TextAndNumber);
- 在類型定義完成後,加入聲明:
Q_DECLARE_METATYPE(TextAndNumber);
- 如果還希望使用這種類型的引用,可同樣要註冊:
qRegisterMetaType<TextAndNumber>("TextAndNumber&");