我有一个班级(例如MyEnumClass
,Q_GADGET
),其中我定义了enum
,例如MyEnum
。
我调用Q_ENUM(MyEnum)
将它注册到元对象,并将整个类注册为QML。
在我的第二课(MyObject : QObject
with macro Q_OBJECT
)中,我有一个使用MyEnum
作为参数的插槽。此对象作为常规类型注册到QML(可创建)。
我想使用MyEnum
中的值来调用QML中的插槽 - 这会失败,因为类型MyEnumClass::MyEnum
似乎未知。
当使用插槽在类中定义枚举时,它可以正常工作。
MVCE
class MyEnumClass {
Q_GADGET
public:
enum MyEnum {
E1,
E2,
E3
};
Q_ENUM(MyEnum)
};
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject* parent = nullptr) : QObject(parent) {}
enum TestEnum {
V1,
V2,
V3
};
Q_ENUM(TestEnum)
public slots:
void testFun1(MyEnumClass::MyEnum val) { qDebug() << val; }
void testFun2(TestEnum val) { qDebug() << val; }
};
在main.cpp中:
qmlRegisterUncreatableType<MyEnumClass>("MyObject", 1, 0, "MyEnum", "Uncreatable");
qmlRegisterType<MyObject>("MyObject", 1, 0, "MyObject");
在main.qml中:
import MyObject 1.0
ApplicationWindow {
id: window
visible: true
width: 600
height: 600
MyObject {
id: obj
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log(MyObject.V2)
console.log(MyEnum.E2)
obj.testFun2(MyObject.V2)
obj.testFun1(MyEnum.E1)
}
}
}
我尝试继承MyEnumClass
中的MyObject
来制作MyObject
的枚举部分,我尝试使用不同的宏和函数来使枚举在MetaObjectSystem中更加可用...无济于事。
我还尝试将枚举放在here所描述的命名空间中 - 它也无法用于插槽。
我发现调用插槽的唯一方法是删除枚举并使用int作为参数的类型 - 这不是那么好......
我怎样才能做到这一点?
我缺少任何技巧吗?
答案 0 :(得分:7)
qRegisterMetaType<MyEnumClass::MyEnum>();
来自Q_ENUM( ...)文档:
此宏使用元对象系统注册枚举类型。它必须 在具有Q_OBJECT的类中的枚举声明之后放置 或者Q_GADGET宏。对于名称空间,请改用Q_ENUM_NS()。
...
注册的枚举也会自动注册到Qt 元类型系统,使它们无需知道QMetaType 使用Q_DECLARE_METATYPE()。
使用Q_ENUM
自动将枚举与元对象系统注册,因此您无需添加
Q_DECLARE_METATYPE(MyEnum)
但是要在排队的信号槽连接中使用枚举,属性......你需要注册元类型。
如int qRegisterMetaType()文件中所述:
要在QVariant中使用类型T,请使用Q_DECLARE_METATYPE() 足够。要在排队信号和插槽连接中使用类型T, 必须在第一个连接之前调用qRegisterMetaType() 建立的。
此外,要将类型T与QObject :: property()API一起使用, qRegisterMetaType()必须在使用之前调用,通常在 使用T的类的构造函数,或者在main()函数中。