I have a simple custom type XyztReal and its aliases in my datamodel.h header file:
#ifndef IMUCONTROLLERDATAMODEL_H
#define IMUCONTROLLERDATAMODEL_H
#include <QMetaType>
namespace imu_controller {
namespace data {
// some code
struct __attribute__((__packed__)) XyztReal {
qreal x ;
qreal y ;
qreal z ;
qreal ts;
};
typedef XyztReal GyrReal;
typedef XyztReal AccReal;
typedef XyztReal MagReal;
void registerTypes();
}
}
Q_DECLARE_METATYPE(imu_controller::data::XyztReal)
#endif // IMUCONTROLLERDATAMODEL_H
and registering function in source datamodel.cpp:
void registerTypes()
{
qRegisterMetaType<XyztReal>("XyztReal"); // or qRegisterMetaType<XyztReal>();
qRegisterMetaType<GyrReal >("GyrReal" );
qRegisterMetaType<AccReal >("AccReal" );
qRegisterMetaType<MagReal >("MagReal" );
}
So i call this function in proper place in programm and try to connect signals/slots of some objects in different thread like this:
Qt::ConnectionType ct = static_cast<Qt::ConnectionType>(Qt::BlockingQueuedConnection | Qt::UniqueConnection);
connect(data_ctrl, &imu_controller::DataController::gyrRealReady, this, &MainWindow::someSlot, ct);
where signal/slot has imu_controller::data::GyrReal and imu_controller::data::XyztReal arguments type respectively, or:
Qt::ConnectionType ct = static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection);
connect(data_ctrl, &imu_controller::DataController::gyrRealReady, this, &MainWindow::onImuGyrRealReceived, ct);
where signal/slot has imu_controller::data::GyrReal arguments type both, But program does not works and debuger prints:
QObject::connect: Cannot queue arguments of type 'imu_controller::data::GyrReal' (Make sure 'imu_controller::data::GyrReal' is registered using qRegisterMetaType().)
for all XyztReal aliases types.
Important:
The program works if imu_controller::DataController class signals type changed to XyztReal types!
PS: I think the problem at types registering. I read qt docs and several topics but i don't found a solution or any examples.
As far as I understand, the
const char * typeNameargument ofqRegisterMetaTypeis quite necessary here. Also it takes consistency in terms of namespaces.Say you have this signal in your
DataControllerclass:Since the class lies in the
imu_controllernamespace, you just add thedatanamespace before the argument class name.Now, in your
registerTypesfunction, it should be registered like this:In other words, the
typeNamestring must match exactly the type of the signal argument as it is written there.It looks like one can register a type more than once, specifying different typenames, i.e.
Curiously, if you have a
somewhere, then you can have
as long as you have
To summarize things up, your register function could be like:
i.e. you can register
XyztRealseveral times, one for each possible alias with every possible combination of namespaces.