summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2019-12-23 15:44:48 +0100
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2020-03-28 09:03:18 +0100
commit8de62d34321cd827e60b0a7b6e7434070de301ae (patch)
tree048f18f000b6d9235057d800e5f3d79be35a5570 /tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
parentb8be5b4002bd6163851bbae397171ebbf632f02f (diff)
QAbstractItemView::dataChanged(): optimize call to QWidget::update()
When topLeft and bottomRight are different in QAIV::dataChanged(), the current implementation simply calls QWidget::update() without checking if the affected cells are visible. This results in a big performance hit when cells are updated frequently. Now try to compute the exact update rect by iterating through the modified indexes. Fixes: QTBUG-58580 Change-Id: I97de567d494e40ed8cdb1ea1f5b3cf3a2f60455e Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
Diffstat (limited to 'tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp')
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 7259fa1ab0..95501136cc 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -89,6 +89,13 @@ public:
QTreeView::paintEvent(event);
wasPainted = true;
}
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>()) override
+ {
+ QTreeView::dataChanged(topLeft, bottomRight, roles);
+ QTreeViewPrivate *av = static_cast<QTreeViewPrivate*>(qt_widget_private(this));
+ m_intersectecRect = av->intersectedRect(av->viewport->rect(), topLeft, bottomRight);
+ }
+ mutable QRect m_intersectecRect;
bool wasPainted = false;
public slots:
void handleSelectionChanged()
@@ -208,6 +215,8 @@ private slots:
void statusTip_data();
void statusTip();
void fetchMoreOnScroll();
+ void checkIntersectedRect_data();
+ void checkIntersectedRect();
// task-specific tests:
void task174627_moveLeftToRoot();
@@ -4832,6 +4841,111 @@ void tst_QTreeView::fetchMoreOnScroll()
QCOMPARE(im.item(19)->rowCount(), 20);
}
+void tst_QTreeView::checkIntersectedRect_data()
+{
+ auto createModel = [](int rowCount)
+ {
+ QStandardItemModel *model = new QStandardItemModel;
+ for (int i = 0; i < rowCount; ++i) {
+ const QList<QStandardItem *> sil({new QStandardItem(QLatin1String("Row %1 Item").arg(i)),
+ new QStandardItem(QLatin1String("2nd column"))});
+ model->appendRow(sil);
+ }
+ for (int i = 2; i < 4; ++i) {
+ const QList<QStandardItem *> sil({new QStandardItem(QLatin1String("Row %1 Item").arg(i)),
+ new QStandardItem(QLatin1String("2nd column"))});
+ model->item(i)->appendRow(sil);
+ }
+ return model;
+ };
+ QTest::addColumn<QStandardItemModel *>("model");
+ QTest::addColumn<QVector<QModelIndex>>("changedIndexes");
+ QTest::addColumn<bool>("isEmpty");
+ {
+ auto model = createModel(5);
+ QTest::newRow("multiple columns") << model
+ << QVector<QModelIndex>({model->index(0, 0),
+ model->index(0, 1)})
+ << false;
+ }
+ {
+ auto model = createModel(5);
+ QTest::newRow("multiple rows") << model
+ << QVector<QModelIndex>({model->index(0, 0),
+ model->index(1, 0),
+ model->index(2, 0)})
+ << false;
+ }
+ {
+ auto model = createModel(5);
+ const QModelIndex idxRow2(model->indexFromItem(model->item(2)));
+ QTest::newRow("child row") << model
+ << QVector<QModelIndex>({model->index(0, 0, idxRow2),
+ model->index(0, 1, idxRow2)})
+ << false;
+ }
+ {
+ auto model = createModel(5);
+ QTest::newRow("hidden row") << model
+ << QVector<QModelIndex>({model->index(3, 0),
+ model->index(3, 1)})
+ << true;
+ }
+ {
+ auto model = createModel(5);
+ const QModelIndex idxRow3(model->indexFromItem(model->item(3)));
+ QTest::newRow("hidden child row") << model
+ << QVector<QModelIndex>({model->index(0, 0, idxRow3),
+ model->index(0, 1, idxRow3)})
+ << true;
+ }
+ {
+ auto model = createModel(50);
+ QTest::newRow("row outside viewport") << model
+ << QVector<QModelIndex>({model->index(49, 0),
+ model->index(49, 1)})
+ << true;
+ }
+}
+
+void tst_QTreeView::checkIntersectedRect()
+{
+ QFETCH(QStandardItemModel *, model);
+ QFETCH(const QVector<QModelIndex>, changedIndexes);
+ QFETCH(bool, isEmpty);
+
+ TreeView view;
+ model->setParent(&view);
+ view.setModel(model);
+ view.resize(400, 400);
+ view.show();
+ view.expandAll();
+ view.setRowHidden(3, QModelIndex(), true);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ view.m_intersectecRect = QRect();
+ emit view.model()->dataChanged(changedIndexes.first(), changedIndexes.last());
+ if (isEmpty) {
+ QVERIFY(view.m_intersectecRect.isEmpty());
+ } else if (!changedIndexes.first().isValid()) {
+ QCOMPARE(view.m_intersectecRect, view.viewport()->rect());
+ } else {
+ const auto parent = changedIndexes.first().parent();
+ const int rCount = view.model()->rowCount(parent);
+ const int cCount = view.model()->columnCount(parent);
+ for (int r = 0; r < rCount; ++r) {
+ for (int c = 0; c < cCount; ++c) {
+ const QModelIndex &idx = view.model()->index(r, c, parent);
+ const auto rect = view.visualRect(idx);
+ if (changedIndexes.contains(idx))
+ QVERIFY(view.m_intersectecRect.contains(rect));
+ else
+ QVERIFY(!view.m_intersectecRect.contains(rect));
+ }
+ }
+ }
+}
+
static void fillModeltaskQTBUG_8376(QAbstractItemModel &model)
{
model.insertRow(0);