我的XyztReal
头文件中有一个简单的自定义类型datamodel.h
及其别名:
#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
和源datamodel.cpp
中的注册功能:
void registerTypes()
{
qRegisterMetaType<XyztReal>("XyztReal"); // or qRegisterMetaType<XyztReal>();
qRegisterMetaType<GyrReal >("GyrReal" );
qRegisterMetaType<AccReal >("AccReal" );
qRegisterMetaType<MagReal >("MagReal" );
}
所以我在程序中的适当位置调用了此函数,并尝试在不同的线程中连接某些对象的signals / slots,例如:
Qt::ConnectionType ct = static_cast<Qt::ConnectionType>(Qt::BlockingQueuedConnection | Qt::UniqueConnection);
connect(data_ctrl, &imu_controller::DataController::gyrRealReady, this, &MainWindow::someSlot, ct);
其中signal / slot分别具有imu_controller::data::GyrReal
和imu_controller::data::XyztReal
自变量类型,或者:
Qt::ConnectionType ct = static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection);
connect(data_ctrl, &imu_controller::DataController::gyrRealReady, this, &MainWindow::onImuGyrRealReceived, ct);
其中信号/插槽具有两个imu_controller::data::GyrReal
参数,但是程序不起作用并且调试器将打印:
QObject :: connect:无法排队'imu_controller :: data :: GyrReal'类型的参数(确保已使用qRegisterMetaType()注册了'imu_controller :: data :: GyrReal'。)
对于所有XyztReal
别名类型。
重要:如果将imu_controller::DataController
类信号类型更改为XyztReal
类型,则程序可以运行!
PS:我认为类型注册时存在问题。我阅读了qt文档和几个主题,但没有找到解决方案或任何示例。
据我了解,此处const char * typeName
的qRegisterMetaType
自变量非常必要。同样,它在名称空间方面也要保持一致性。
假设您在DataController
类中有此信号:
signals:
void some_signal(data::AccReal);
由于类位于imu_controller
命名空间中,因此只需在参数类名称之前添加data
命名空间。
现在,在您的registerTypes
功能中,应该这样注册:
qRegisterMetaType<AccReal >("data::AccReal");
换句话说, [看起来一个人可以多次注册一个类型,并指定不同的类型名称,即typeName
字符串必须与信号参数在此处写入的参数]的类型完全匹配。] >>
qRegisterMetaType<AccReal >("AccReal"); qRegisterMetaType<AccReal >("data::AccReal"); qRegisterMetaType<AccReal >("imu_controller::data::AccReal");
很奇怪,如果您有
using WhatEver = imu_controller::data::AccReal;
某个地方,您可以有
signals: void some_signal(WhatEver);
只要您有
qRegisterMetaType<AccReal >("WhatEver");
总结起来,您的注册功能可能像:
QString aliases[] = {"XyztReal", "GyrReal", "AccReal", "MagReal" }; for(auto a : aliases) { qRegisterMetaType<XyztReal>(a.toLatin1()); a.prepend("data::"); qRegisterMetaType<XyztReal>(a.toLatin1()); a.prepend("imu_controller::"); qRegisterMetaType<XyztReal>(a.toLatin1()); }
即您可以多次注册
XyztReal
,对于每种可能的别名以及每种可能的命名空间组合,都可以注册一次。