I want to send a structure with a signal in Qt. How can I do this? I know how to send integers, strings, Images etc with a signal but getting confused with the structure part. I read some posts and found out about Q_DECLARE_METATYPE() but I am not understanding how to use it.
typedef struct
{
int EmpId;
QString Name;
} StandardData;
class Data::public QObject
{
Q_DECLARE_METATYPE(StandardData);
signals:
void SignalData(const StandardData &f_objStandardCan);
}
The errors I get re
1.explicit specialization in non namespace scope class.
2.Specialization of template must appear at namespace scope
3. struct QMetaTypeId redeclared with a different access.
Can someone please tell me where I am going wrong.
The errors are because the use of Q_DECLARE_METATYPE is inside your class declaration. It must be outside any classes or namespaces. You just need to move it like this:
typedef struct
{
int EmpId;
QString Name;
} StandardData;
Q_DECLARE_METATYPE(StandardData);
As you have already found out, you must use Q_DECLARE_METATYPE
to make the type known to Qt.
struct StandardData {
int EmpId;
QString Name;
}; Q_DECLARE_METATYPE(StandardData)
Additionally, you might need to call qRegisterMetaType
. Specifically, the function have to be called before using the struct in a queued signal/slot connection or before using it with the QObject::property() API.
qRegisterMetaType<StandardData>();
Working Example
standarddata.h
struct StandardData {
int EmpId;
QString Name;
}; Q_DECLARE_METATYPE(StandardData)
main.cpp
int main(int argc, char *argv[])
{
// Register types on startup
qRegisterMetaType<StandardData>();
// Continue with the program
// ...
}
Trick with Static Initialization
There is a trick that can be used to call qRegisterMetaType
without modifying any non-related file (like main.cpp
). This trick uses static initialization. However, I did not find any documentation of Qt that state that this is supported. Additionally, this might cause trouble when using in dynamic libraries.
standarddata.h
// The header file looks the same as above
struct StandardData {
int EmpId;
QString Name;
}; Q_DECLARE_METATYPE(StandardData)
standarddata.cpp
// We don't need this global variable at all. We just want to ensure that
// qRegisterMetaType is called when the application starts.
static const int typeId = qRegisterMetaType<StandardData>();
Q_GADGET
Alternatively, you can use Q_GADGET
instead of Q_DECLARE_METATYPE
:
class StandardData {
Q_GADGET
public:
int EmpId;
QString Name;
};
// You still have to call qRegisterMetaType if used for queued signals or
// as property.
qRegisterMetaType<StandardData>();