StatusQ(SubmodelProxyModel): Submodel type fixed
There was inconsistency in qvariant type of submodels depending if it was initial call for a given row (creating proxy) or further calls (returning cached object). It led to subtle issues in views - view was reporting type errors and failing assigning submodels properly when used with submodel proxy with already initialized and cached proxy submodels. Closes: #14507
This commit is contained in:
parent
bbd0e71fd6
commit
e8a78e21b8
|
@ -50,13 +50,13 @@ QVariant SubmodelProxyModel::data(const QModelIndex &index, int role) const
|
|||
context->setContextProperty(QStringLiteral("submodel"), submodel);
|
||||
|
||||
QObject* instance = m_delegateModel->create(context);
|
||||
|
||||
instance->setParent(submodelObj);
|
||||
|
||||
submodelObj->setProperty(attachementPropertyName,
|
||||
QVariant::fromValue(QPointer(instance)));
|
||||
QVariant wrappedInstance = QVariant::fromValue(instance);
|
||||
|
||||
return QVariant::fromValue(instance);
|
||||
submodelObj->setProperty(attachementPropertyName, wrappedInstance);
|
||||
|
||||
return QVariant::fromValue(wrappedInstance);
|
||||
}
|
||||
|
||||
return QIdentityProxyModel::data(index, role);
|
||||
|
|
|
@ -78,6 +78,50 @@ private slots:
|
|||
QQmlEngine::CppOwnership);
|
||||
}
|
||||
|
||||
void submodelTypeTest() {
|
||||
QQmlEngine engine;
|
||||
QQmlComponent delegate(&engine);
|
||||
|
||||
auto delegateData = R"(
|
||||
import QtQml 2.15
|
||||
QtObject {
|
||||
property var count: submodel.count
|
||||
}
|
||||
)";
|
||||
|
||||
delegate.setData(delegateData, QUrl());
|
||||
|
||||
SubmodelProxyModel model;
|
||||
|
||||
auto source = R"([
|
||||
{ balances: [ { balance: 4 } ], name: "name 1" }
|
||||
])";
|
||||
|
||||
ListModelWrapper sourceModel(engine, source);
|
||||
model.setSourceModel(sourceModel);
|
||||
model.setDelegateModel(&delegate);
|
||||
model.setSubmodelRoleName(QStringLiteral("balances"));
|
||||
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
|
||||
QVariant balances = model.data(model.index(0, 0),
|
||||
sourceModel.role("balances"));
|
||||
|
||||
QVERIFY(balances.isValid());
|
||||
|
||||
QVariant balances2 = model.data(model.index(0, 0),
|
||||
sourceModel.role("balances"));
|
||||
|
||||
// SubmodelProxyModel may create proxy objects on demand, then first
|
||||
// call to data(...) returns freshly created object, the next calls
|
||||
// related to the same row should return cached object. It's important
|
||||
// to have QVariant type identical in both cases. E.g. returning raw
|
||||
// pointer in first call and pointer wrapped into QPointer in the next
|
||||
// one leads to problems in UI components in some scenarios even if
|
||||
// those QVariant types are automatically convertible.
|
||||
QCOMPARE(balances2.type(), balances.type());
|
||||
}
|
||||
|
||||
void usingNonObjectSubmodelRoleTest() {
|
||||
QQmlEngine engine;
|
||||
QQmlComponent delegate(&engine);
|
||||
|
|
Loading…
Reference in New Issue