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:
parent
778c70c84c
commit
d61a15d043
@ -163,6 +163,8 @@ static auto parse_scope(QByteArrayView qualifiedKey) noexcept
|
|||||||
std::optional<QByteArrayView> scope;
|
std::optional<QByteArrayView> scope;
|
||||||
QByteArrayView key;
|
QByteArrayView key;
|
||||||
};
|
};
|
||||||
|
if (qualifiedKey.startsWith("QFlags<") && qualifiedKey.endsWith('>'))
|
||||||
|
qualifiedKey.slice(7, qualifiedKey.length() - 8);
|
||||||
const auto scopePos = qualifiedKey.lastIndexOf("::"_L1);
|
const auto scopePos = qualifiedKey.lastIndexOf("::"_L1);
|
||||||
if (scopePos < 0)
|
if (scopePos < 0)
|
||||||
return R{std::nullopt, qualifiedKey};
|
return R{std::nullopt, qualifiedKey};
|
||||||
|
@ -41,6 +41,7 @@ class tst_QMetaProperty : public Base
|
|||||||
Q_PROPERTY(QMap<int, int> map MEMBER map)
|
Q_PROPERTY(QMap<int, int> map MEMBER map)
|
||||||
Q_PROPERTY(CustomType custom MEMBER custom)
|
Q_PROPERTY(CustomType custom MEMBER custom)
|
||||||
Q_PROPERTY(int propWithInheritedSig READ propWithInheritedSig NOTIFY baseSignal)
|
Q_PROPERTY(int propWithInheritedSig READ propWithInheritedSig NOTIFY baseSignal)
|
||||||
|
Q_PROPERTY(QFlags<Qt::AlignmentFlag> qflags_value MEMBER qflags_value)
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void hasStdCppSet();
|
void hasStdCppSet();
|
||||||
@ -52,6 +53,7 @@ private slots:
|
|||||||
void conversion();
|
void conversion();
|
||||||
void enumsFlags();
|
void enumsFlags();
|
||||||
void notifySignalIndex();
|
void notifySignalIndex();
|
||||||
|
void qflags();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum EnumType { EnumType1 };
|
enum EnumType { EnumType1 };
|
||||||
@ -71,6 +73,7 @@ public:
|
|||||||
QString value7;
|
QString value7;
|
||||||
QMap<int, int> map;
|
QMap<int, int> map;
|
||||||
CustomType custom;
|
CustomType custom;
|
||||||
|
QFlags<Qt::AlignmentFlag> qflags_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QMetaProperty::hasStdCppSet()
|
void tst_QMetaProperty::hasStdCppSet()
|
||||||
@ -112,6 +115,16 @@ void tst_QMetaProperty::isFinal()
|
|||||||
QVERIFY(!prop.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 {
|
class MyGadget {
|
||||||
Q_GADGET
|
Q_GADGET
|
||||||
Q_PROPERTY(QString value READ getValue WRITE setValue RESET resetValue)
|
Q_PROPERTY(QString value READ getValue WRITE setValue RESET resetValue)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user