如何从 QML 访问 C++ 类中声明的 Q_ENUM?

Gam*_*ads 5 qt qml qt-quick qenum

我有如下Q_ENUM声明:MyClass

class MyClass {
public:
    enum Enum_Test {
        eTestA,
        eTestB
    }
    Q_ENUM(Enum_Test)

    Q_OBJECT
    Q_PROPERTY(MyClass::Enum_Test enumTest READ GetEnumTest WRITE SetEnumTest )
}
Run Code Online (Sandbox Code Playgroud)

我已经MyClass在 QML 端注册,如下所示,并且能够访问它。

auto my_class = std::make_shared<MyClass>();
qmlRegisterUncreatableType<MyClass>("MyClass", 1,0, "MyClass","Cannot create type MyClass in QML");
rootContext()->setContextProperty("my_class", my_class.get());
Run Code Online (Sandbox Code Playgroud)

如何从 QML 访问Q_ENUM Enum_Test

Amf*_*sis 8

你的班级需要进行两次调整。

  1. 正如 JarMan 指出的,它需要一个元对象,可以通过从 QObject 派生并添加 Q_OBJECT 来获得:

    class MyClass : public QObject
    {
        Q_OBJECT
        ...
    };
    
    Run Code Online (Sandbox Code Playgroud)

    实际上,也可以使用,Q_GADGET但您似乎已经倾向于使用Q_OBJECT. 但是,根据要求,我们开始:

    class MyClass
    {
      Q_GADGET
    
    public:
      enum Enum_Test {
          ETestA,
          ETestB
      };
      Q_ENUM(Enum_Test)
    };
    
    Run Code Online (Sandbox Code Playgroud)

    请记住,Q_GADGET不能有信号,因此我省略了该属性,仅将此类作为“枚举占位符”。

  2. 枚举值名称需要大写:

    enum Enum_Test {
        ETestA,
        ETestB
    };
    Q_ENUM(Enum_Test)
    
    Run Code Online (Sandbox Code Playgroud)

然后你可以在 QML 中使用它:

     QtObject {
         property int myEnumVal: MyClass.ETestA
     }
Run Code Online (Sandbox Code Playgroud)

请注意,由于与 JavaScript 混合,对枚举的支持有所限制。这些值将转换为整数。此外,当在 JavaScript switch 语句中使用时,QtCreator 不会警告拼写错误(假设版本为 4.14)


Luc*_*lon 5

@Amfasis 提供的答案已经很好了。由于我经常这样做,因此我编写了一个小快捷方式来定义具有 Qt 提供的所有功能的枚举,包括此处 QML 中的可用性:https: //github.com/carlonluca/lqtutils#lqtutils_enumh

您只需要包含标题,定义枚举值,例如:

L_DECLARE_ENUM(Enum_Test,
    ETestA,
    ETestB
)
Run Code Online (Sandbox Code Playgroud)

并在您喜欢的位置注册:

Enum_Test::qmlRegisterMySharedEnum("some.uri", 1, 0);
Run Code Online (Sandbox Code Playgroud)

此外,这还使用简单的命名空间,这比使用 QObject 或小工具更轻。

实际上,当我使用 Qt 时,我习惯了总是这样声明我的枚举,因为我也可以从QMetaEnum中受益。例如,我真的很喜欢能够像这样登录:

qDebug() << "Value:" << Enum_Test::ETestA;
Run Code Online (Sandbox Code Playgroud)

得到:

Value: Enum_Test::ETestA
Run Code Online (Sandbox Code Playgroud)

而不是一个简单的整数。