Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Different property type for enum in 5.15/6.5
QtWS25 Last Chance

Different property type for enum in 5.15/6.5

Scheduled Pinned Locked Moved Unsolved General and Desktop
enumpropertyqvariantqt5qt6
9 Posts 4 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    crueegg
    wrote on 25 Apr 2023, 04:05 last edited by
    #1

    If I have an enum as property, Qt6 has a different property type than Qt5.
    My serialization will fail in Qt6 because the property type is a QString and not an int anymore.
    Is this a bug or do I miss something to get the enum property as int (type 2) for all Qt versions?

    Using Q_DECLARE_METATYPE(MyQClass::MyEnum) or qRegisterMetaType<MyQClass::MyEnum>("MyQClass::MyEnum"); didn't made any difference.

    MyQClass.hpp

    #pragma once
    #include <QObject>
    
    class MyQClass : public QObject
    {
      Q_OBJECT
      Q_PROPERTY(MyEnum myEnum READ getMyEnum WRITE setMyEnum)
    public:
      explicit MyQClass(QObject *parent = nullptr) : QObject{parent} {}
    
      enum MyEnum { EnumVal0, EnumVal1, EnumVal2, EnumVal3 };
      Q_ENUM(MyEnum)
    
      void setMyEnum(MyEnum myEnum) { _myEnum = myEnum; }
      MyEnum getMyEnum() const { return _myEnum; }
    
    private:
      MyEnum _myEnum { EnumVal1 };
    };
    

    main.cpp

    #include <QCoreApplication>
    #include <QMetaProperty>
    #include <QVariant>
    #include "MyQClass.hpp"
    
    
    int main(int argc, char *argv[])
    {
      QCoreApplication a(argc, argv);
      qInfo("Qt %s", QT_VERSION_STR);
    
      MyQClass myClass;
    
      const QMetaObject *meta = myClass.metaObject();
      int id = meta->indexOfProperty("myEnum");
      QMetaProperty p = meta->property(id);
      QVariant v(p.read(&myClass));
      qInfo("MetaProperty name=%s, value=%s, typename=%s type=%d, userType=%d, isEnumType=%d",
            p.name(), qPrintable(v.toString()), p.typeName(), p.type(), p.userType(),
            p.isEnumType());
      return 0;
    }
    

    Outputs (value and type is different):

    Qt 5.15.2
    MetaProperty name=myEnum, value=1, typename=MyEnum type=2, userType=2, isEnumType=1
    
    Qt 6.5.0
    MetaProperty name=myEnum, value=EnumVal1, typename=MyQClass::MyEnum type=65536, userType=65537, isEnumType=1
    

    Qt 6.4.2 has the same output as 6.5.0.
    Qt 5.9.7 has the same output as 5.15.2

    Test.pro:

    QT = core
    CONFIG += c++17 cmdline
    HEADERS +=  MyQClass.hpp
    SOURCES += main.cpp
    
    S 1 Reply Last reply 25 Apr 2023, 06:19
    0
    • C crueegg
      25 Apr 2023, 04:05

      If I have an enum as property, Qt6 has a different property type than Qt5.
      My serialization will fail in Qt6 because the property type is a QString and not an int anymore.
      Is this a bug or do I miss something to get the enum property as int (type 2) for all Qt versions?

      Using Q_DECLARE_METATYPE(MyQClass::MyEnum) or qRegisterMetaType<MyQClass::MyEnum>("MyQClass::MyEnum"); didn't made any difference.

      MyQClass.hpp

      #pragma once
      #include <QObject>
      
      class MyQClass : public QObject
      {
        Q_OBJECT
        Q_PROPERTY(MyEnum myEnum READ getMyEnum WRITE setMyEnum)
      public:
        explicit MyQClass(QObject *parent = nullptr) : QObject{parent} {}
      
        enum MyEnum { EnumVal0, EnumVal1, EnumVal2, EnumVal3 };
        Q_ENUM(MyEnum)
      
        void setMyEnum(MyEnum myEnum) { _myEnum = myEnum; }
        MyEnum getMyEnum() const { return _myEnum; }
      
      private:
        MyEnum _myEnum { EnumVal1 };
      };
      

      main.cpp

      #include <QCoreApplication>
      #include <QMetaProperty>
      #include <QVariant>
      #include "MyQClass.hpp"
      
      
      int main(int argc, char *argv[])
      {
        QCoreApplication a(argc, argv);
        qInfo("Qt %s", QT_VERSION_STR);
      
        MyQClass myClass;
      
        const QMetaObject *meta = myClass.metaObject();
        int id = meta->indexOfProperty("myEnum");
        QMetaProperty p = meta->property(id);
        QVariant v(p.read(&myClass));
        qInfo("MetaProperty name=%s, value=%s, typename=%s type=%d, userType=%d, isEnumType=%d",
              p.name(), qPrintable(v.toString()), p.typeName(), p.type(), p.userType(),
              p.isEnumType());
        return 0;
      }
      

      Outputs (value and type is different):

      Qt 5.15.2
      MetaProperty name=myEnum, value=1, typename=MyEnum type=2, userType=2, isEnumType=1
      
      Qt 6.5.0
      MetaProperty name=myEnum, value=EnumVal1, typename=MyQClass::MyEnum type=65536, userType=65537, isEnumType=1
      

      Qt 6.4.2 has the same output as 6.5.0.
      Qt 5.9.7 has the same output as 5.15.2

      Test.pro:

      QT = core
      CONFIG += c++17 cmdline
      HEADERS +=  MyQClass.hpp
      SOURCES += main.cpp
      
      S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 25 Apr 2023, 06:19 last edited by
      #2

      I think the difference you are measuring here is in QVariant (which did see major changes between Qt5 and Qt6), not QProperty.

      Can you show your serialization code? It's hard to say anything about why it fails without the code :-)

      (Z(:^

      C 1 Reply Last reply 25 Apr 2023, 08:26
      0
      • S sierdzio
        25 Apr 2023, 06:19

        I think the difference you are measuring here is in QVariant (which did see major changes between Qt5 and Qt6), not QProperty.

        Can you show your serialization code? It's hard to say anything about why it fails without the code :-)

        C Offline
        C Offline
        crueegg
        wrote on 25 Apr 2023, 08:26 last edited by
        #3

        @sierdzio I can fix the Serialization quite easy with a if (p.isEnumType()) out << v.toInt(); switch. What worries me more are the 100 other cases, which are difficult to detect.

        For backward compatibility it would be better to have the enums stored as an int inside the Property/QVariant.

        In Qt5.15 the debugger shows me for the v: Value=1, Type=QVariant (int).
        In Qt6.5 the debugger shows me for the v: Value=MyQClass:EnumVal1 (1), Type=QVariant (MyQClass::MyEnum).

        K 1 Reply Last reply 25 Apr 2023, 13:18
        0
        • C crueegg
          25 Apr 2023, 08:26

          @sierdzio I can fix the Serialization quite easy with a if (p.isEnumType()) out << v.toInt(); switch. What worries me more are the 100 other cases, which are difficult to detect.

          For backward compatibility it would be better to have the enums stored as an int inside the Property/QVariant.

          In Qt5.15 the debugger shows me for the v: Value=1, Type=QVariant (int).
          In Qt6.5 the debugger shows me for the v: Value=MyQClass:EnumVal1 (1), Type=QVariant (MyQClass::MyEnum).

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 25 Apr 2023, 13:18 last edited by
          #4

          @crueegg said in Different property type for enum in 5.15/6.5:

          For backward compatibility it would be better to have the enums stored as an int inside the Property/QVariant.

          That would prevent changes that are good and necessary. Since Qt5 and Qt6 are major releases, you're not guaranteed that breaking changes won't occur, especially if you rely on an implementation detail. People've waited to push such changes for ~3 years, so they don't break your 5.x -> 5.y transitions, so I think your request that the internal structure of QVariant should stay the same is unreasonable. You simply will need to adjust your code to match.

          Read and abide by the Qt Code of Conduct

          C 1 Reply Last reply 25 Apr 2023, 16:46
          2
          • K kshegunov
            25 Apr 2023, 13:18

            @crueegg said in Different property type for enum in 5.15/6.5:

            For backward compatibility it would be better to have the enums stored as an int inside the Property/QVariant.

            That would prevent changes that are good and necessary. Since Qt5 and Qt6 are major releases, you're not guaranteed that breaking changes won't occur, especially if you rely on an implementation detail. People've waited to push such changes for ~3 years, so they don't break your 5.x -> 5.y transitions, so I think your request that the internal structure of QVariant should stay the same is unreasonable. You simply will need to adjust your code to match.

            C Offline
            C Offline
            crueegg
            wrote on 25 Apr 2023, 16:46 last edited by
            #5

            @kshegunov For a new project it's fantastic to have the enums inside the properties, but for a migration it's a nightmare (did I catch all locations?).

            I'm looking for a configuration where the enum-feature is "disabled".

            S K 2 Replies Last reply 25 Apr 2023, 19:12
            0
            • C crueegg
              25 Apr 2023, 16:46

              @kshegunov For a new project it's fantastic to have the enums inside the properties, but for a migration it's a nightmare (did I catch all locations?).

              I'm looking for a configuration where the enum-feature is "disabled".

              S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 25 Apr 2023, 19:12 last edited by
              #6

              Hi,

              Are you using QDataStream ? If so, are you explicitly setting the version ?

              It's a good idea to do so in any case so you can easily keep backward compatibility and decide yourself when you want to migrate (and apply the migration on your terms).

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              C 1 Reply Last reply 26 Apr 2023, 08:37
              3
              • C crueegg
                25 Apr 2023, 16:46

                @kshegunov For a new project it's fantastic to have the enums inside the properties, but for a migration it's a nightmare (did I catch all locations?).

                I'm looking for a configuration where the enum-feature is "disabled".

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 26 Apr 2023, 07:05 last edited by
                #7

                @crueegg said in Different property type for enum in 5.15/6.5:

                For a new project it's fantastic to have the enums inside the properties, but for a migration it's a nightmare (did I catch all locations?).

                I don't follow. QVariant coerces the types when necessary, so I really have no idea what the problem is here. Why do you want and expect this enum to be stored in some specific way? You'd stream out the QVariant and then when you read it, you'd get a representation that should be compatible. A call to QVariant::convert should be just about enough to change the type from int to enum or vice versa.

                Read and abide by the Qt Code of Conduct

                C 1 Reply Last reply 26 Apr 2023, 09:21
                0
                • S SGaist
                  25 Apr 2023, 19:12

                  Hi,

                  Are you using QDataStream ? If so, are you explicitly setting the version ?

                  It's a good idea to do so in any case so you can easily keep backward compatibility and decide yourself when you want to migrate (and apply the migration on your terms).

                  C Offline
                  C Offline
                  crueegg
                  wrote on 26 Apr 2023, 08:37 last edited by
                  #8

                  @SGaist Yes, I'm using a QDataStream with version 4.8.

                  1 Reply Last reply
                  0
                  • K kshegunov
                    26 Apr 2023, 07:05

                    @crueegg said in Different property type for enum in 5.15/6.5:

                    For a new project it's fantastic to have the enums inside the properties, but for a migration it's a nightmare (did I catch all locations?).

                    I don't follow. QVariant coerces the types when necessary, so I really have no idea what the problem is here. Why do you want and expect this enum to be stored in some specific way? You'd stream out the QVariant and then when you read it, you'd get a representation that should be compatible. A call to QVariant::convert should be just about enough to change the type from int to enum or vice versa.

                    C Offline
                    C Offline
                    crueegg
                    wrote on 26 Apr 2023, 09:21 last edited by
                    #9

                    @kshegunov I have ~80 classes, each with 5-10 different properties (enums, POD, custom types, containers). The problem are all implicit (in a loop) conversions of these properties.

                    1 Reply Last reply
                    0

                    9/9

                    26 Apr 2023, 09:21

                    • Login

                    • Login or register to search.
                    9 out of 9
                    • First post
                      9/9
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved