c++ - 为什么没有 qRegisterMetaType q_enum 无法获得正确的类型值?

标签 c++ qt dll qmetatype

我有一个包含多个 dll 的 QT 项目。

动态链接库:A、B、C

A 依赖于 B 和 C。而 B 和 C 没有任何依赖关系。

B 导出自定义类 B_Custom。 B_Custom 类派生自 QObject。

Dll A:

Class Exported A : public C
{
    ...
    Q_PROPERTY(B_Custom:B_Enum b_enum READ GetBEnum WRITE SetBEnum NOTIFY BEnumChanged);

    void DoSomething()
    {
        SomethingElse("b_enum");
    }

    ....
}

Dll B:

class Exported B_Custom: public QObject
{
    Q_OBJECT;
    public:
        enum B_Enum {
            ...
        };
        Q_ENUM(B_Enum);
    ...
}

Dll C:

Class C : public QObject
{
    virtual void SomethingElse(const QByteArray &propName)
    {
        auto type = property(propName).userType();
    }
}    

主要内容:

A * a = new A();
a->DoSomething();

问题出在C类,SomethingElse函数的类型值为QMetaType::UnknownType。

但是如果我手动注册 Dll B 中的 B_Enum

qRegisterMetaType<B_Custom::B_Enum>() 

在调用 A::DoSomething() 之前, SomethingElse 函数的类型值不会是 QMetaType::UnknownType。

它将返回正确的类型值,如 1230,用于类 C 的函数 SomethingElse 中的类型。

但根据QT文档@http://doc.qt.io/qt-5/qobject.html#Q_ENUM ,

用 Q_ENUM 声明的枚举在封闭的 QMetaObject 中注册了它们的 QMetaEnum。 您还可以使用 QMetaEnum::fromType() 来获取 QMetaEnum。

注册的枚举也会自动注册到 Qt 元类型系统,使它们为 QMetaType 所知而无需使用 Q_DECLARE_METATYPE()。

那么为什么我需要调用 qRegisterMetaType() 才能让 C 类的 SomethingElse 函数中的类型获得正确的类型值?

dll B中有很多类似的类型,需要获取类C中的类型信息。

如果我需要用qRegisterMetaType把这些类型一一注册起来,那实在是太不愉快了。

最佳答案

仔细查看以下文档:

“此外,要将类型 T 与 QObject::property() API 一起使用,必须在使用之前调用 qRegisterMetaType(),通常是在使用 T 的类的构造函数中,或者在 main( ) 函数。”

http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1 中提到了这一点.

现在回到您的代码:

您在 B_Custom 类中声明了 Q_ENUM(B_Enum);

但是 enum 的属性是在 class A 中声明的。

现在再次回顾上面指定的文档声明。

因此,要将 enumclass A 中声明的 property 一起使用,要么必须在 中注册元类型>class A 构造函数或在使用它之前的 main 函数中(您已经完成并正在工作)。

说多了你可能会有疑问,为什么我们需要在不同的类(class)重新注册。

看看下面的声明:似乎你必须在所有类中注册类型,无论你在哪里使用,而不仅仅是在你声明的类中。

“如果在另一个类中声明了枚举类型,则需要其完全限定名(即 OtherClass::Priority),并且该其他类也必须继承 QObject 并在其中注册枚举类型,使用Q_ENUM() 宏。” ( http://doc.qt.io/qt-5/properties.html )

关于c++ - 为什么没有 qRegisterMetaType q_enum 无法获得正确的类型值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43686802/

相关文章:

c++ - 如何使数据结构在 C++ 中持久化?

.net - DLL 被标记为 DELETEPENDING

c++ - CMapStringToString 无法处理 Unicode?

c++ - 使用 C 字符串时出错

c++ - 如何在 DLL 中隐藏导出函数

windows - 如何在Windows中检查注册的dll?

browser - 在 Inno Setup 中嵌入 Internet Explorer 窗口(Web 浏览器控件)

c++ - 查找 zlib 压缩流的结尾

c++ - 从指向基对象的指针初始化派生对象

qt - 在 QT 的不同线程中运行函数