I am attempting to send a structure via signals/slots between two threads, my signals/slots are connected properly and I have been able to send QStrings containing parts of my data but now I need to send the whole thing and Structures seem most sensible. However when I try the signal is not sent/recieved. The problem seems to be only with sending/receiving the structure, the processing before and after I have tried many ways.
I cannot use pointers such here or here as my data is generated too fast and memory gets over written or freed (I have tried with pointers and assume references will be similarly effected).
I have already added the Q_DECLARE_METATYPE to my structure. My structure is only a small test for now (to be enlarged later) and is in its own header file.
#ifndef RETURNSTRUCT_H
#define RETURNSTRUCT_H
struct Datastruct
{
int markeridone;
};
Q_DECLARE_METATYPE(Datastruct);
#endif //RETURNSTRUCT_H
Why might my program be unable to send/receive structures? any help is much appreciated.
I am using windows 7, MinGW 32bit, Qt 5.7.0, Qt Creator 4.0.3
Your debug-log should warn you about it - you can only send types known to the meta-system of qt. Using Q_REGISTER_METATYPE you end up registering types associated with the namespace where the definition was made.
Fortunately you can tell Qt about your struct like this:
// after QApplication was instantiated
qRegisterMetaType<Datastruct>("Datastruct");
// but before any class is instantiated that connects signals with this type
And it will not try to infer a namespace by looking at the code. Make sure to re-run qmake (or better yet do a clean), or it might be overlooked when building with QtCreator.
If you later happen to pass template-classes of your types via signals, make sure to register them as well, because even if Qt knows about QList, it doesnt know about QList of your type:
qRegisterMetaType<QList<Datastruct>>("QList<Datastruct>");
On another note: if you #define class aliases, make sure to register them with their real names.
#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>");
In moment, when You declare structure known to QMetaType using macro Q_DECLARE_METATYPE
struct Datastruct
{
int markeridone;
};
Q_DECLARE_METATYPE(Datastruct)
you can send this structure via QVariant. Is nice and simply.
In Your headers declare:
signals:
void sendDatastruct(QVariant data);
public slots:
void getDatastruct(QVariant data);
Using signal in Your code:
.....
Datastruct ds;
.....
QVariant data;
data.setValue(ds);
emit sendDatastruct(data); // now send signal
.....
Using slot:
void MyObject::getDatastruct(QVariant data)
{
Datastruct ds = data.value<Datastruct>();
.....
// now You can use structure in Your code
}