Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
None
-
5.6.0, 5.7.0, 5.7.1, 5.8.0
-
None
-
8de62d34321cd827e60b0a7b6e7434070de301ae (qt/qtbase/dev)
Description
If the topLeft index and bottomRight index received by the dataChanged slot in QAbstractItemView do not match then entire view is repainted rather than just the changed cells, if they do match only one the changed cell is repainted.
qabstractitemview.cpp
void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) { ... if (topLeft == bottomRight && topLeft.isValid()) { ... if (isVisible() && !d->delayedPendingLayout) { // otherwise the items will be update later anyway update(topLeft); } } else { ... if (isVisible() && !d->delayedPendingLayout) d->viewport->update(); } }
With a model containing around 200 rows and 50 columns, receiving approximately 10 updates a second where multiple adjacent columns on the same row were changing I was seeing a CPU load of 50%, when the QTableView was open, by changing the model to emit individual dataChanged calls even when all items are adjacent this load dropped to 5%.
Subclassing QTableView and implementing the following override also had the same effect.
void MyTableView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) { for(int row=topLeft.row(); row <= bottomRight.row(); ++row) { for(int column=topLeft.column(); column <= bottomRight.column(); ++column) { QModelIndex index = topLeft.sibling(row, column); QTableView::dataChanged(index, index, roles); } } }
This issue should impact QListView and QTreeView as well.
Attachments
For Gerrit Dashboard: QTBUG-58580 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
285280,17 | QAbstractItemView::dataChanged(): optimize call to QWidget::update() | dev | qt/qtbase | Status: MERGED | +2 | 0 |