Different property type for enum in 5.15/6.5
-
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 aQString
and not anint
anymore.
Is this a bug or do I miss something to get the enum property asint
(type 2) for all Qt versions?Using
Q_DECLARE_METATYPE(MyQClass::MyEnum)
orqRegisterMetaType<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.2QT = core CONFIG += c++17 cmdline HEADERS += MyQClass.hpp SOURCES += main.cpp
-
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 :-)
-
@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)
. -
@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. -
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).
-
@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 theQVariant
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 fromint
toenum
or vice versa.