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

How to access a Q_ENUM declared in C++ class from QML?

我在 MyClass 中声明了一个 Q_ENUM,如下所示:

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

    Q_OBJECT
    Q_PROPERTY(MyClass::Enum_Test enumTest READ GetEnumTest WRITE SetEnumTest )
}

我已经 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());

如何从 QML 访问 Q_ENUM Enum_Test

您的 class 需要进行两次调整。

  1. 正如JarMan所指出的,它需要一个metaObject,可以通过从QObject派生并添加Q_OBJECT:

    来获得
    class MyClass : public QObject
    {
        Q_Object
        ...
    }
    

    其实用Q_GADGET也是可以的,不过你好像已经倾向于Q_OBJECT了。但是,按照要求,我们开始吧:

    class 我的班级 { Q_GADGET

    public:
      enum Enum_Test {
          ETestA,
          ETestB
      }
      Q_ENUM(Enum_Test)
    

    };

    请记住 Q_GADGET cannot have signals,所以我省略了 属性,只有这个 class 作为“枚举占位符”。

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

    enum Enum_Test {
        ETestA,
        ETestB
    }
    Q_ENUM(Enum_Test)
    

然后您可以在 QML 中将其用作:

     QtObject {
         property int myEnumVal: MyClass.ETestA
     }

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

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

您只需要包含 header,定义您的枚举值,例如:

L_DECLARE_ENUM(Enum_Test,
    ETestA,
    ETestB
)

并在您喜欢的地方注册:

Enum_Test::qmlRegisterMySharedEnum("some.uri", 1, 0);

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

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

qDebug() << "Value:" << Enum_Test::ETestA;

得到:

Value: Enum_Test::ETestA

而不是简单的整数。