Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to make a Enum known to QML if it is inside a QObject derived class



  • Hi,

    I have a Q_OBJECT derived class, which has several Q_PROPERTY values. One of them is an enum, defined in that class. In order to make it known to QML, I would need to do Q_DECLARE_METATYPE(MarkGui), but this is not possible as Q_DECLARE_METATYPE requires a copy constructor, which is forbidden for Q_OBJECT derived classes. What is the way to do it?


  • Moderators

    @maxwell31 said in How to make a Enum known to QML if it is inside a QObject derived class:

    I would need to do Q_DECLARE_METATYPE(MarkGui)

    No.
    Actually you need Q_ENUM

    enum MyEnum {
        ...
    };
    Q_ENUM(MyEnum)
    


  • Hm, I was using Q_ENUMS. But When I try to use it, I get the following error:

      QMetaProperty::read: Unable to handle unregistered datatype 'myEnumType' for property 'QQmlDMObjectData::myEnumType'.
    

    I also registered the class which hosts the enum:

      qmlRegisterType<MyClass>("MyClass",1,0,"MyClass");
    

    So the problem seems to be, that I use the enum as a property


  • Moderators

    @maxwell31
    how does your Q_PROPERTY declaration look like?
    Did you add the class namespace to the enum type in the property declaration?



  • Here the class:

    class MarkGui: public QObject {
      Q_OBJECT
      Q_PROPERTY(MarkType markType READ markType WRITE       setMarkType NOTIFY markTypeChanged)
    
    public:
      MarkGui(QObject *parent = 0);
      explicit MarkGui(Mark * m, QObject *parent = 0);
      enum MarkType {
        MOMENT,
        TIMERANGE,
      };
       Q_ENUM(MarkType);
    

    I tried with adding the class namespace, but it leads to the same result



  • Hm, it seems I need to register the enum seperatly
    qRegisterMetaTypeMarkGui::MarkType("MarkGui::MarkType");



  • This post is deleted!


  • Hi @maxwell31,

    Usually you have not to register the enum. This would be a pain when you have tens of enums declared.
    But you need to register the class hosting the enum, because you need a keyword to access the enum from QML side.

    So Q_ENUM(MarkType) more calling qmlRegisterType<MarkGui>("MarkGui",1,0,"MarkGui"); at runtime should be enough to retrieve the enum from QML.

    This works perfectly on my side:

    #ifndef MARKGUI_H
    #define MARKGUI_H
    
    #include <QObject>
    #include <QtQml>
    
    class MarkGui: public QObject {
        Q_OBJECT
        Q_PROPERTY(MarkType markType READ markType WRITE setMarkType NOTIFY markTypeChanged)
    
    public:
        MarkGui(QObject *parent = 0) : QObject(parent){};
    
        enum MarkType {
            MOMENT,
            TIMERANGE,
        };
        Q_ENUM(MarkType);
    
        MarkType markType() const
        {
            return m_markType;
        }
        static void declareQml(){
            qmlRegisterType<MarkGui>("MarkGui", 1, 0, "MarkGui");
        }
    public slots:
        void setMarkType(MarkType markType)
        {
            if (m_markType == markType)
                return;
    
            m_markType = markType;
            emit markTypeChanged(m_markType);
        }
    signals:
        void markTypeChanged(MarkType markType);
    private:
        MarkType m_markType;
    };
    #endif // MARKGUI_H
    
    //main()
    //...
        MarkGui markGui;
        MarkGui::declareQml();
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("markGui", &markGui);
    ...
    
    

    Then from QML:

         import MarkGui 1.0
         ...
         markGui.markType = MarkGui.MOMENT
         console.log(markGui.markType)
         markGui.markType = MarkGui.TIMERANGE
         console.log(markGui.markType)
    

    Output:

    qml: 0
    qml: 1
    


  • Ok, good to know.Thank you for your help!


Log in to reply