Fix fetching data when reuseItems is true
QQmlDelegateModelPrivate::requestMoreIfNecessary() is called in various situations, including at startup, which calls QAIM::fetchMore() on the model if it supports that. But we need to do it in one more case: when delegates are being reused from the cache, the model could provide more rows even though we aren't instantiating new delegates. Amends1841a9e41d
Fixes: QTBUG-95107 Change-Id: I5b7ff48345ab78977cb03cfcf58ed96a57c831bd Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit589d0ee473
) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
1757054ff7
commit
0dd96b57b6
|
@ -1203,6 +1203,9 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
|
||||||
addCacheItem(cacheItem, it);
|
addCacheItem(cacheItem, it);
|
||||||
reuseItem(cacheItem, index, flags);
|
reuseItem(cacheItem, index, flags);
|
||||||
cacheItem->referenceObject();
|
cacheItem->referenceObject();
|
||||||
|
|
||||||
|
if (index == m_compositor.count(group) - 1)
|
||||||
|
requestMoreIfNecessary();
|
||||||
return cacheItem->object;
|
return cacheItem->object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import QtQuick
|
||||||
|
import org.qtproject.Test
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listView
|
||||||
|
width: 300
|
||||||
|
height: 150
|
||||||
|
flickDeceleration: 10000
|
||||||
|
|
||||||
|
model: FetchMoreModel
|
||||||
|
delegate: Text {
|
||||||
|
height: 50
|
||||||
|
text: model.display
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: "count " + listView.count
|
||||||
|
color: listView.moving ? "red" : "blue"
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,6 +57,8 @@ private slots:
|
||||||
void areaZeroviewDoesNotNeedlesslyPopulateWholeModel();
|
void areaZeroviewDoesNotNeedlesslyPopulateWholeModel();
|
||||||
|
|
||||||
void delegateContextHandling();
|
void delegateContextHandling();
|
||||||
|
void fetchMore_data();
|
||||||
|
void fetchMore();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
|
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
|
||||||
|
@ -1040,6 +1042,80 @@ void tst_QQuickListView2::delegateContextHandling()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestFetchMoreModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QVariant data(const QModelIndex& index, int role) const override
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return QString::number(index.row());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
int columnCount(const QModelIndex&) const override { return 1; }
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent) const override
|
||||||
|
{
|
||||||
|
return parent.isValid() ? 0 : m_lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex parent(const QModelIndex&) const override { return {}; }
|
||||||
|
|
||||||
|
bool canFetchMore(const QModelIndex &) const override { return true; }
|
||||||
|
|
||||||
|
void fetchMore(const QModelIndex & parent) override
|
||||||
|
{
|
||||||
|
if (Q_UNLIKELY(parent.isValid()))
|
||||||
|
return;
|
||||||
|
beginInsertRows(parent, m_lines, m_lines);
|
||||||
|
m_lines++;
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_lines = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_QQuickListView2::fetchMore_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<bool>("reuseItems");
|
||||||
|
QTest::addColumn<int>("cacheBuffer");
|
||||||
|
|
||||||
|
QTest::newRow("no reuseItems, default buffer") << false << -1;
|
||||||
|
QTest::newRow("reuseItems, default buffer") << true << -1;
|
||||||
|
QTest::newRow("no reuseItems, no buffer") << false << 0;
|
||||||
|
QTest::newRow("reuseItems, no buffer") << true << 0;
|
||||||
|
QTest::newRow("no reuseItems, buffer 100 px") << false << 100;
|
||||||
|
QTest::newRow("reuseItems, buffer 100 px") << true << 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QQuickListView2::fetchMore() // QTBUG-95107
|
||||||
|
{
|
||||||
|
QFETCH(bool, reuseItems);
|
||||||
|
QFETCH(int, cacheBuffer);
|
||||||
|
|
||||||
|
TestFetchMoreModel model;
|
||||||
|
qmlRegisterSingletonInstance("org.qtproject.Test", 1, 0, "FetchMoreModel", &model);
|
||||||
|
QQuickView window;
|
||||||
|
QVERIFY(QQuickTest::showView(window, testFileUrl("fetchMore.qml")));
|
||||||
|
auto *listView = qobject_cast<QQuickListView*>(window.rootObject());
|
||||||
|
QVERIFY(listView);
|
||||||
|
listView->setReuseItems(reuseItems);
|
||||||
|
if (cacheBuffer >= 0)
|
||||||
|
listView->setCacheBuffer(cacheBuffer);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
const int rowCount = listView->count();
|
||||||
|
if (lcTests().isDebugEnabled()) QTest::qWait(1000);
|
||||||
|
listView->flick(0, -5000);
|
||||||
|
QTRY_VERIFY(!listView->isMoving());
|
||||||
|
qCDebug(lcTests) << "after flick: contentY" << listView->contentY()
|
||||||
|
<< "rows" << rowCount << "->" << listView->count();
|
||||||
|
QCOMPARE_GT(listView->count(), rowCount);
|
||||||
|
QCOMPARE_GE(model.m_lines, listView->count()); // fetchMore() was called
|
||||||
|
}
|
||||||
|
}
|
||||||
QTEST_MAIN(tst_QQuickListView2)
|
QTEST_MAIN(tst_QQuickListView2)
|
||||||
|
|
||||||
#include "tst_qquicklistview2.moc"
|
#include "tst_qquicklistview2.moc"
|
||||||
|
|
Loading…
Reference in New Issue