C++ 如何访问C++;来自QML的枚举?

C++ 如何访问C++;来自QML的枚举?,c++,qt,qml,qtquick2,C++,Qt,Qml,Qtquick2,.h文件具有上述代码如何通过QML访问上述枚举?使用Q_ENUMS宏使moc了解您的枚举,如中所述。在使用枚举之前,必须注册“拥有”该枚举的类,如中所述 Ashif的quote块仅在枚举是全局的或由非QObject派生类拥有时有效。您可以将枚举包装在从QObject派生的类中(并且您公开给QML): style.hpp: class StyleClass : public QObject { public: typedef enum { STYLE

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

使用
Q_ENUMS
宏使
moc
了解您的枚举,如中所述。在使用枚举之前,必须注册“拥有”该枚举的类,如中所述


Ashif的quote块仅在枚举是全局的或由非
QObject
派生类拥有时有效。

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

style.hpp:

class StyleClass : public QObject {
public:
    typedef enum
        {
            STYLE_RADIAL,
            STYLE_ENVELOPE,
            STYLE_FILLED
        }  Style;

    Style m_style;
    //...
};
其他信息(之前未记录):

枚举值名称必须以大写字母开头

这将有助于:

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

    //...
}
这并不是:

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

编译时不会出现任何类型的错误,它们只是被QML引擎忽略。

从Qt 5.8开始,您可以从
命名空间中公开枚举:

定义命名空间和枚举:

enum EnStyle
{
    styleRADIAL,
    styleENVELOPE,
    styleFILLED
};
Q_ENUMS(EnStyle)
在QML文件中使用它:

qmlRegisterUncreatableMetaObject(
  MyNamespace::staticMetaObject, // meta object created by Q_NAMESPACE macro
  "my.namespace",                // import statement (can be any string)
  1, 0,                          // major and minor version of the import
  "MyNamespace",                 // name in QML (does not have to match C++ name)
  "Error: only enums"            // error in case someone tries to create a MyNamespace object
);
qrc:/main.qml:16 Not creatable as it is an enum type.
参考资料:


自Qt版本5.10以来,Qt还支持QML定义的枚举类型。作为air dex基于C++的答案的替代方案,您现在还可以使用QML创建枚举类型:

Style.qml:

import QtQuick 2.0
import my.namespace 1.0

Item {
    Component.onCompleted: console.log(MyNamespace.STYLE_RADIAL)
}
如果只打算在QML代码中使用枚举,则此解决方案要简单得多。您可以使用qml中的样式类型访问上述枚举,例如:

import QtQuick 2.0

QtObject {
  enum EnStyle {
    STYLE_RADIAL,
    STYLE_ENVELOPE,
    STYLE_FILLED
  }
}

有关基于QML的枚举类型的另一个使用示例,请参阅。

无法启用所有这些解决方案,请将此枚举类用作信号/插槽的参数。此代码可编译,但不能在QML中工作:

import VPlayApps 1.0
import QtQuick 2.9

App {

  property int enStyle: Style.EnStyle.STYLE_RADIAL

  Component.onCompleted: {
    if(enStyle === Style.EnStyle.STYLE_ENVELOPE)
      console.log("ENVELOPE")
    else
      console.log("NOT ENVELOPE")
  }
}
QML部分:

class DataEmitter : public QObject
{
    Q_OBJECT

public:
    ...
signals:
    void setStyle(StyleClass::EnStyle style);
}

...

emit setStyle(StyleClass.STYLE_RADIAL);
此代码生成运行时错误,如下所示:

Connections {
    target: dataEmitter
    onSetStyle: {
         myObject.style=style
    }
}
要使此代码正常工作,必须添加注册表Qt元对象类型:

IndicatorArea.qml:124: Error: Cannot assign [undefined] to int
qRegisterMetaType(“StyleClass.EnStyle”);

<这里有更多的细节:(RUS)

< P> >我在QML发现C++中使用ENUMs的一个非常好的解决方案: . 这篇文章很好,我觉得有义务在这里与so社区分享。而且IMHO的归属应该总是这样做的,因此添加了该帖子的链接

这篇文章主要描述了:

1) 如何在Qt/C++中创建枚举类型:

qRegisterMetaType<StyleClass::EnStyle>("StyleClass.EnStyle");
3) 最后,如何在QML文件中使用枚举:

qmlRegisterUncreatableMetaObject(
  MyNamespace::staticMetaObject, // meta object created by Q_NAMESPACE macro
  "my.namespace",                // import statement (can be any string)
  1, 0,                          // major and minor version of the import
  "MyNamespace",                 // name in QML (does not have to match C++ name)
  "Error: only enums"            // error in case someone tries to create a MyNamespace object
);
qrc:/main.qml:16 Not creatable as it is an enum type.
…然后,有时人们会意外地将枚举与上下文属性一起使用,而不是使用类名

// 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
...

人们之所以会犯这种错误,是因为Qt-Creator的自动完成功能在使用类名以及上下文属性进行引用时,都会将ENUM列为选项。因此,在这种情况下请谨慎。

@big_gie我请这位尊敬的先生参考“发布截止日期”这句话,以及我当时所做的Qt bug报告。它现在被记录下来了,因为我采取了一些措施将它添加到文档中。感谢您向Qt报告它!多亏了你,这些文档现在状态更好了;)我只是想添加(并参考它现在被记录的确切位置)。几年前,我花了一天的大部分时间试图弄清楚为什么我的枚举没有出现在QML中,因为这个原因…想知道是否有一种方法可以让枚举不在QObject派生类中(例如,在UI下面没有Qt依赖项的软件层中)。注意:注册的类必须提供默认构造函数。您是对的。我刚刚编辑了我的答案,添加了更多细节。@DavidJ我们也在想同样的事情。据我所知,你不能这么做。现在我们正在这样做:
enum MyEnum{Foo=MyOtherEnum::Foo};Q_ENUMS(MyEnum)
@DavidJ从Qt v5.8开始,您可以对名称空间中的枚举执行此操作。这也似乎在这里被记录:在C++中使用这些枚举的任何方式,如果你想和我一样, StaseMeta对象>代码>是一个对象,被<代码> qyNealStsie< /Cord>宏添加到命名空间中。
// main.cpp

...
QQmlApplicationEngine engine;
qmlRegisterUncreatableType<StatusClass>("qml.guide", 1, 0, "StatusClass",
                                        "Not creatable as it is an enum type.");
...
qrc:/main.qml:16 Not creatable as it is an enum type.
// 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.
    }
}
// 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
...
// main.qml

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

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