如何从 QML 访问 C 枚举?

新手上路,请多包涵
class StyleClass : public QObject {
public:
    typedef enum
        {
            STYLE_RADIAL,
            STYLE_ENVELOPE,
            STYLE_FILLED
        }  Style;

    Style m_style;
    //...
};

.h 文件具有上述代码。 如何通过 QML 访问上述枚举?

原文由 Aquarius_Girl 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答

您可以将枚举包装在派生自 QObject 的类中(并且将其公开给 QML):

样式.hpp:

 #ifndef STYLE_HPP
#define STYLE_HPP

#include <QtGlobal>
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
    // Qt 4
    #include <QDeclarativeEngine>
#else
    // Qt 5
    #include <QQmlEngine>
#endif

// Required derivation from QObject
class StyleClass : public QObject
{
    Q_OBJECT

    public:
        // Default constructor, required for classes you expose to QML.
        StyleClass() : QObject() {}

        enum EnStyle
        {
            STYLE_RADIAL,
            STYLE_ENVELOPE,
            STYLE_FILLED
        };
        Q_ENUMS(EnStyle)

        // Do not forget to declare your class to the QML system.
        static void declareQML() {
            qmlRegisterType<StyleClass>("MyQMLEnums", 13, 37, "Style");
        }
};

#endif    // STYLE_HPP

主.cpp:

 #include <QApplication>
#include "style.hpp"

int main (int argc, char ** argv) {
    QApplication a(argc, argv);

    //...

    StyleClass::declareQML();

    //...

    return a.exec();
}

QML 代码:

 import MyQMLEnums 13.37
import QtQuick 2.0    // Or 1.1 depending on your Qt version

Item {
    id: myitem

    //...

    property int item_style: Style.STYLE_RADIAL

    //...
}

原文由 air-dex 发布,翻译遵循 CC BY-SA 3.0 许可协议

我在这里找到了一个非常好的解决方案,可以在 QML 中使用 C++ 类中的 ENUM: Enums in Qt QML - qml.guide 。这篇文章太好了,我觉得有义务在这里与 SO 社区分享。恕我直言,应始终进行归属,因此添加了帖子的链接。

该帖子基本上描述了:

  1. 如何在 Qt/C++ 中创建 ENUM 类型:
 // statusclass.h

#include <QObject>

class StatusClass
{
    Q_GADGET
public:
    explicit StatusClass();

    enum Value {
        Null,
        Ready,
        Loading,
        Error
    };
    Q_ENUM(Value)
};

  1. 如何使用 QML 引擎将类注册为“不可创建类型”:

(这是使这个解决方案变得漂亮和独特的部分。)

 // main.cpp

...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
                                        "Not creatable as it is an enum type.");
...

使用 qmlRegisterUncreatableType 可以防止在 QML 中实例化 StatusClass 。如果用户尝试实例化此类,将记录一个警告:

 qrc:/main.qml:16 Not creatable as it is an enum type.

3)最后,如何在QML文件中使用ENUM:

 // main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

import qml.guide 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Component.onCompleted: {
        console.log(StatusClass.Ready); // <--- Here's how to use the ENUM.
    }
}

重要的提示:

ENUM 应该通过使用类名引用它来使用,例如 StatusClass.Ready 。如果在 QML 中也使用相同的类作为上下文属性……

 // main.cpp

...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
                                        "Not creatable as it is an enum type.");

StatusClass statusClassObj; // Named such (perhaps poorly) for the sake of clarity in the example.
engine.rootContext()->setContextProperty("statusClassObj", &statusClassObj); // <--- like this
...

…然后,有时人们不小心将 ENUM 与上下文属性而不是类名一起使用。

 // main.qml

...
Component.onCompleted: {
    // Correct
    console.log(StatusClass.Ready);    // 1

    // Wrong
    console.log(statusClassObj.Ready); // undefined
}
...

人们倾向于犯这个错误的原因是因为 Qt Creator 的自动完成功能将 ENUM 列为选项,无论是在使用类名引用时还是上下文属性。因此,在这种情况下,请谨慎行事。

原文由 zeFree 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题