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);
|
||||
reuseItem(cacheItem, index, flags);
|
||||
cacheItem->referenceObject();
|
||||
|
||||
if (index == m_compositor.count(group) - 1)
|
||||
requestMoreIfNecessary();
|
||||
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 delegateContextHandling();
|
||||
void fetchMore_data();
|
||||
void fetchMore();
|
||||
|
||||
private:
|
||||
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)
|
||||
|
||||
#include "tst_qquicklistview2.moc"
|
||||
|
|
Loading…
Reference in New Issue