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

时间:2017-04-28 18:34:25

标签: c++ qt dll qmetatype

我有一个有几个dll的QT项目。

Dlls: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。

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

但是要归功于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逐个注册这些类型,它真的不是一种乐趣。

1 个答案:

答案 0 :(得分:1)

仔细查看以下文档:

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

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

现在回到你的代码:

您在班级math.pi中宣布Q_ENUM(B_Enum);

B_Custom声明了enum的属性。

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

因此,要将class Aenum中声明的property一起使用,您必须先在class A构造函数或main函数中注册元类型使用它(你做过和工作)。

您可能会对此产生疑问,为什么我们需要在另一个班级再次注册。

请看下面的陈述:似乎您必须在所有类中注册该类型,而不仅仅是在您声明的类中。

&#34;如果枚举类型已在另一个类中声明,则需要其完全限定名称(即OtherClass :: Priority),而其他类也必须继承QObject并注册枚举使用Q_ENUM()宏键入那里。&#34; http://doc.qt.io/qt-5/properties.html