我有一个包含多个 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
中声明的。
现在再次回顾上面指定的文档声明。
因此,要将 enum
与 class 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/