在Qt中注册自定义MetaType的别名类型

问题描述 投票:2回答:1

我的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::GyrRealimu_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文档和几个主题,但没有找到解决方案或任何示例。

qt typedef qt-signals qmetatype
1个回答
0
投票

据我了解,此处const char * typeNameqRegisterMetaType自变量非常必要。同样,它在名称空间方面也要保持一致性。

假设您在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,对于每种可能的别名以及每种可能的命名空间组合,都可以注册一次。

© www.soinside.com 2019 - 2024. All rights reserved.