diff options
| author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2023-11-06 14:06:43 +0100 |
|---|---|---|
| committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2023-11-09 13:08:05 +0100 |
| commit | bff7aca8695e4cacc252d0235dc70cf3a46c032e (patch) | |
| tree | 5343d8e1fe2b13ee67c53a091a053ef0be6e86ac /src/quick/items/qquicktableview.cpp | |
| parent | 425c65a27b1c712226697bed8709705b9914cc8a (diff) | |
TableView: don't emit rows and columns changed while rebuilding
We should be careful about emitting signals while we do a rebuild.
The reason is that the application might listen to those signals
and change Flickable properties (especially contentX/Y) behind
TableView's back.
A bug is seen from this if the application is setting a very
large contentY upon receiving rowsChanged(). In that case
TableView will not detect that it should do a "fast-flick"
directly to the new contentY, but instead start to
loadAndUnloadVisibleEdges() until it reaches the current
viewport. And this can take a really long time, and therefore
block the UI.
This patch will wait to emit rows/columnsChanged until we're
done rebuilding. At that point, it's safe to change properties
such as contentX/Y from the application.
The main usecase this patch is solving, is to be able to
always position the viewport on the last row as new rows
are added to the model. This can now be done by listening
to onRowsChanged or onContentHeightChanged, and position
the viewport at the end. The included auto test will
therefore test this exact use case.
Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-118897
Change-Id: I6124fbd0e7097a2bbb89c887fe594c3028726aa7
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
Diffstat (limited to 'src/quick/items/qquicktableview.cpp')
| -rw-r--r-- | src/quick/items/qquicktableview.cpp | 22 |
1 files changed, 6 insertions, 16 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 8376e092af..5c1355de9c 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -2773,21 +2773,6 @@ qreal QQuickTableViewPrivate::sizeHintForRow(int row) const return rowHeight; } -void QQuickTableViewPrivate::updateTableSize() -{ - // tableSize is the same as row and column count, and will always - // be the same as the number of rows and columns in the model. - Q_Q(QQuickTableView); - - const QSize prevTableSize = tableSize; - tableSize = calculateTableSize(); - - if (prevTableSize.width() != tableSize.width()) - emit q->columnsChanged(); - if (prevTableSize.height() != tableSize.height()) - emit q->rowsChanged(); -} - QSize QQuickTableViewPrivate::calculateTableSize() { QSize size(0, 0); @@ -3330,6 +3315,7 @@ void QQuickTableViewPrivate::processRebuildTable() Q_TABLEVIEW_UNREACHABLE(rebuildOptions); } + tableSizeBeforeRebuild = tableSize; edgesBeforeRebuild = loadedItems.isEmpty() ? QMargins() : QMargins(q->leftColumn(), q->topRow(), q->rightColumn(), q->bottomRow()); } @@ -3398,6 +3384,10 @@ void QQuickTableViewPrivate::processRebuildTable() } if (rebuildState == RebuildState::Done) { + if (tableSizeBeforeRebuild.width() != tableSize.width()) + emit q->columnsChanged(); + if (tableSizeBeforeRebuild.height() != tableSize.height()) + emit q->rowsChanged(); if (edgesBeforeRebuild.left() != q->leftColumn()) emit q->leftColumnChanged(); if (edgesBeforeRebuild.right() != q->rightColumn()) @@ -3547,7 +3537,7 @@ void QQuickTableViewPrivate::calculateTopLeft(QPoint &topLeftCell, QPointF &topL void QQuickTableViewPrivate::loadInitialTable() { - updateTableSize(); + tableSize = calculateTableSize(); if (positionXAnimation.isRunning()) { positionXAnimation.stop(); |
