首页 文章

如何从QML访问C enum?

提问于
浏览
31
class StyleClass : public QObject {
public:
    typedef enum
        {
            STYLE_RADIAL,
            STYLE_ENVELOPE,
            STYLE_FILLED
        }  Style;

    Style m_style;
    //...
};

.h文件包含上面的代码 . How to access the above enum through QML?

6 回答

  • 37

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

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

    main.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
    
        //...
    }
    
  • 15

    其他信息(未在Qt 5.5之前记录):

    您的枚举值名称 must 以大写字母开头 .

    这将有效:

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

    这不是:

    enum EnStyle
    {
        styleRADIAL,
        styleENVELOPE,
        styleFILLED
    };
    Q_ENUMS(EnStyle)
    

    你不会在编译时遇到任何错误,它们会被QML引擎忽略 .

  • 3

    使用 Q_ENUMS 宏使 moc 知道您的枚举,如docs中所述 . 如docs中所述,您必须在使用之前注册'owns'枚举的类 .

    只有当枚举是全局的或由非 QObject 派生类拥有时,Ashif的引用块才有效 .

  • 0

    所有这些解决方案都无法使用此枚举类作为信号/插槽的参数 . 这段代码编译,但在QML中不起作用:

    class DataEmitter : public QObject
    {
        Q_OBJECT
    
    public:
        ...
    signals:
        void setStyle(StyleClass::EnStyle style);
    }
    
    ...
    
    emit setStyle(StyleClass.STYLE_RADIAL);
    

    QML部分:

    Connections {
        target: dataEmitter
        onSetStyle: {
             myObject.style=style
        }
    }
    

    此代码生成运行时错误,如下所示:

    IndicatorArea.qml:124: Error: Cannot assign [undefined] to int
    

    要使此代码正常工作,您必须使用其他注册表Qt元对象类型:

    qRegisterMetaType<StyleClass::EnStyle>("StyleClass.EnStyle");
    

    更多细节写在这里:https://webhamster.ru/mytetrashare/index/mtb0/1535044840rbtgvfmjys(rus)

  • 17

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

    Style.qml:

    import QtQuick 2.0
    
    QtObject {
      enum EnStyle {
        STYLE_RADIAL,
        STYLE_ENVELOPE,
        STYLE_FILLED
      }
    }
    

    如果您只打算在QML代码中使用枚举,则此解决方案要简单得多 . 您可以使用qml中的Style类型访问上面的枚举,例如:

    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的枚举类型的另一个用法示例,请参阅here .

  • 5

    As of Qt 5.8 您可以从 namespace 公开枚举:

    定义命名空间和枚举:

    #include <QObject>
    
    namespace MyNamespace
    {
        Q_NAMESPACE         // required for meta object creation
        enum EnStyle {
            STYLE_RADIAL,
            STYLE_ENVELOPE,
            STYLE_FILLED
        };
        Q_ENUM_NS(EnStyle)  // register the enum in meta object data
    }
    

    在创建Qml视图/上下文之前注册命名空间(例如,在main()中):

    qmlRegisterUncreatableMetaObject(
      MyNamespace::staticMetaObject, // static meta object
      "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
    );
    

    在QML文件中使用它:

    import QtQuick 2.0
    import my.namespace 1.0
    
    Item {
        Component.onCompleted: console.log(MyNamespace.STYLE_RADIAL)
    }
    

    参考文献:

    https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/

    http://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterUncreatableMetaObject

    http://doc.qt.io/qt-5/qobject.html#Q_ENUM_NS

相关问题