Fix QFlag properties built by QMetaObjectBuilder

When Q_PROPERTY is used to define a property with type (for example)
Qt::Alignment the name of the type stored in the meta-object is
"Qt::Alignment".

When QMetaObjectBuilder.addProperty() is used it will instead use the
name of the meta-type (ie. "QFlags<Qt::AlignmentFlag>") which it has
obtained from QMetaType::fromName("Qt::Alignment").name().

In the QMetaProperty ctor it tries to resolve the QMetaEnum for the
property and uses the internal parse_scope() to extract the scope and
qualified key from the name. However it does not handle template names
and so fails with dynamically created properties.

This change to parse_scope() removes the "QFlags<>" so that the
template type can then be parsed.

Another solution would be for addProperty() to always use the type name
it was given rather than use QMetaType::fromName(). That has the
advantage that the layout of the dynamic meta-object would match that
generated by moc.

Change-Id: Iac9e2db2f134029709158b4e500286922396501d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 5624060865e3ccd3c487f10355cb740b7322f93c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Phil Thompson 2024-10-23 16:28:27 +01:00 committed by Qt Cherry-pick Bot
parent 778c70c84c
commit d61a15d043
2 changed files with 15 additions and 0 deletions

View File

@ -163,6 +163,8 @@ static auto parse_scope(QByteArrayView qualifiedKey) noexcept
std::optional<QByteArrayView> scope;
QByteArrayView key;
};
if (qualifiedKey.startsWith("QFlags<") && qualifiedKey.endsWith('>'))
qualifiedKey.slice(7, qualifiedKey.length() - 8);
const auto scopePos = qualifiedKey.lastIndexOf("::"_L1);
if (scopePos < 0)
return R{std::nullopt, qualifiedKey};

View File

@ -41,6 +41,7 @@ class tst_QMetaProperty : public Base
Q_PROPERTY(QMap<int, int> map MEMBER map)
Q_PROPERTY(CustomType custom MEMBER custom)
Q_PROPERTY(int propWithInheritedSig READ propWithInheritedSig NOTIFY baseSignal)
Q_PROPERTY(QFlags<Qt::AlignmentFlag> qflags_value MEMBER qflags_value)
private slots:
void hasStdCppSet();
@ -52,6 +53,7 @@ private slots:
void conversion();
void enumsFlags();
void notifySignalIndex();
void qflags();
public:
enum EnumType { EnumType1 };
@ -71,6 +73,7 @@ public:
QString value7;
QMap<int, int> map;
CustomType custom;
QFlags<Qt::AlignmentFlag> qflags_value;
};
void tst_QMetaProperty::hasStdCppSet()
@ -112,6 +115,16 @@ void tst_QMetaProperty::isFinal()
QVERIFY(!prop.isFinal());
}
void tst_QMetaProperty::qflags()
{
const QMetaObject *mo = metaObject();
QMetaProperty prop = mo->property(mo->indexOfProperty("qflags_value"));
QVERIFY(prop.isEnumType());
QVERIFY(prop.isFlagType());
}
class MyGadget {
Q_GADGET
Q_PROPERTY(QString value READ getValue WRITE setValue RESET resetValue)