2016-09-14 22 views
2

我試圖通過兩個線程之間的信號/插槽發送結構,我的信號/插槽連接正確,我已經能夠發送QStrings包含我的數據的一部分,但現在我需要發送整個事物和結構似乎最明智。但是,當我嘗試不發送/接收信號。這個問題似乎只與發送/接收結構,我嘗試了很多方法之前和之後的處理。Qt信號/插槽發送一個完整的結構

我不能使用指針等here或作爲我的數據生成速度過快,內存越過書面或釋放here(我曾嘗試使用指針,並承擔引用將以類似的影響)。

我已將Q_DECLARE_METATYPE添加到我的結構中。我的結構現在只是一個小測試(稍後放大),並且在它自己的頭文件中。

#ifndef RETURNSTRUCT_H 
#define RETURNSTRUCT_H 

struct Datastruct 
{ 
    int markeridone; 
}; 

Q_DECLARE_METATYPE(Datastruct); 

#endif //RETURNSTRUCT_H 

爲什麼我的程序無法發送/接收結構?任何幫助深表感謝。

我使用Windows 7,32位的MinGW,QT 5.7.0,Qt Creator的4.0.3

回答

7

您的調試日誌應該提醒你一下吧 - 你只能發送已知的Qt元系統類型。使用Q_REGISTER_METATYPE最終註冊與定義所在的名稱空間相關的類型。

幸運的你可以告訴Qt的關於你的結構是這樣的:

// after QApplication was instantiated 
qRegisterMetaType<Datastruct>("Datastruct"); 
// but before any class is instantiated that connects signals with this type 

,它不會試圖通過看代碼來推斷一個命名空間。確保重新運行qmake(或者更好但乾淨利落),或者在使用QtCreator構建時可能會忽略它。

如果以後發生的通過信號來傳遞你的類型的模板類,確保它們註冊爲好,因爲即使Qt的知道的QList,它不知道你的類型的QList:

qRegisterMetaType<QList<Datastruct>>("QList<Datastruct>"); 

另一個說明:如果你#define類別名,確保註冊他們的真實姓名。

#define std::shared_ptr model_ptr 
// you can declare your signals like this: 
void my_signal(model_ptr<my_model>); 
// but have to register the type like this: 
qRegisterMetaType<std::shared_ptr<my_model>>("std::shared_ptr<my_model>"); 
+1

爲什麼啊,爲什麼你會永遠在這裏建議使用'#define'?即使在C中也沒有必要(你有typedef)!在C++中,你應該使用類型別名:'using model_ptr = std :: shared_ptr '。只要使用別名,而不是底層類型名稱,只要你始終在任何地方使用它,也是完全正確的。 –

+0

我正在給我一個例子,它與我的情況類似,如果您已經在使用#define ** - 而不是_suggesting_來使用#define –

+0

註冊一個* template *類可能無法正常工作,您可能需要先「typedef」或「using」,然後註冊別名。另外請注意,模板類型末尾的雙角花括號只允許** C++ 11及以上版本**。如果你也爲其他項目工作,不要讓這個習慣成爲你的習慣! – iksemyonov

1

在那一刻,當你使用宏Q_DECLARE_METATYPE

struct Datastruct 
{ 
    int markeridone; 
}; 

Q_DECLARE_METATYPE(Datastruct) 

,您可以通過發送的QVariant這種結構聲明已知QMetaType結構。很好,很簡單。 在你的頭文件中聲明:

signals: 
    void sendDatastruct(QVariant data); 

public slots: 
    void getDatastruct(QVariant data); 

在代碼中使用信號:

..... 
Datastruct ds; 
..... 
QVariant data; 
data.setValue(ds); 
emit sendDatastruct(data); // now send signal 
..... 

使用插槽:

void MyObject::getDatastruct(QVariant data) 
{ 
    Datastruct ds = data.value<Datastruct>(); 
    ..... 
    // now You can use structure in Your code 
}