resizeToContents - QTableView - faster hint when view is hidden

In some situations we can get into resizeSections in a hidden
QHeaderView. If the headerView is hidden then we look at all the
rows, and that can be extemely expensive for a large model.

This patch limits the sizeHint with only looking at a maximum
1000 rows. Though this is more inaccurate it is also faster -
and it is not much different from what QTreeView does.

Change-Id: Ief4b54c5a3c5a0db02e8b595c9b9b3162633ee67
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
bb10
Thorbjørn Martsum 2013-03-09 21:15:28 +01:00 committed by The Qt Project
parent 929e08a3d6
commit 03c5eacfbb
2 changed files with 31 additions and 0 deletions

View File

@ -2180,6 +2180,7 @@ int QTableView::sizeHintForRow(int row) const
return -1;
ensurePolished();
const int maximumProcessCols = 1000; // To avoid this to take forever.
int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
@ -2190,6 +2191,7 @@ int QTableView::sizeHintForRow(int row) const
int hint = 0;
QModelIndex index;
int columnsProcessed = 0;
for (int column = left; column <= right; ++column) {
int logicalColumn = d->horizontalHeader->logicalIndex(column);
if (d->horizontalHeader->isSectionHidden(logicalColumn))
@ -2211,6 +2213,9 @@ int QTableView::sizeHintForRow(int row) const
}
hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).height());
++columnsProcessed;
if (columnsProcessed == maximumProcessCols)
break;
}
return d->showGrid ? hint + 1 : hint;
@ -2239,6 +2244,7 @@ int QTableView::sizeHintForColumn(int column) const
return -1;
ensurePolished();
const int maximumProcessRows = 1000; // To avoid this to take forever.
int top = qMax(0, d->verticalHeader->visualIndexAt(0));
int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
@ -2248,6 +2254,7 @@ int QTableView::sizeHintForColumn(int column) const
QStyleOptionViewItem option = d->viewOptions();
int hint = 0;
int rowsProcessed = 0;
QModelIndex index;
for (int row = top; row <= bottom; ++row) {
int logicalRow = d->verticalHeader->logicalIndex(row);
@ -2264,6 +2271,9 @@ int QTableView::sizeHintForColumn(int column) const
}
hint = qMax(hint, itemDelegate(index)->sizeHint(option, index).width());
++rowsProcessed;
if (rowsProcessed == maximumProcessRows)
break;
}
return d->showGrid ? hint + 1 : hint;

View File

@ -44,6 +44,8 @@
#include <QTableView>
#include <QImage>
#include <QPainter>
#include <QHeaderView>
#include <QStandardItemModel>
class QtTestTableModel: public QAbstractTableModel
{
@ -149,6 +151,7 @@ private slots:
void columnInsertion();
void columnRemoval_data();
void columnRemoval();
void sizeHintForColumnWhenHidden();
private:
static inline void spanInit_helper(QTableView *);
};
@ -361,5 +364,23 @@ void tst_QTableView::columnRemoval()
}
}
void tst_QTableView::sizeHintForColumnWhenHidden()
{
QTableView view;
QStandardItemModel model(12500, 6);
for (int r = 0; r < model.rowCount(); ++r)
for (int c = 0; c < model.columnCount(); ++c) {
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(r).arg(c));
model.setItem(r, c, item);
}
view.horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
view.setModel(&model);
QBENCHMARK_ONCE {
view.horizontalHeader()->resizeSection(0, 10); // this force resizeSections - on a hidden view.
}
}
QTEST_MAIN(tst_QTableView)
#include "tst_qtableview.moc"