Performance issue with QHeaderView::ResizeToContents for vertical header in QTableView
<p>Given a <code>QTableView</code> that displays a custom item model with a single column but many hundreds of rows, setting the <code>sectionResizeMode</code> of the <strong>vertical</strong> header to <code>ResizeToContents</code> has a massive negative impact on performance.</p>

<p>For debug reasons I added some output in the item model's <code>::data</code> method to see which rows are actually queried by the view. It turns out that the table view actually queries every single row in the model as soon as it needs to render with the resize mode set to <code>ResizeToContents</code> -- no matter how many rows are even displayed.</p>

<p>The code example below gives the following output:</p>

<pre><code>*** show ***
query  0
query  1
query  2
query  3
  ... many lines trimmed ...
query  495
query  496
query  497
query  498
query  499
query  0
query  1
query  2
query  3
  ... many lines trimmed ...
query  495
query  496
query  497
query  498
query  499
query  0
query  1
query  2
query  3
query  4
query  5
query  6
query  0
query  1
query  2
query  3
query  4
query  5
query  6
</code></pre>

<p>That is, the view first seems to iterate twice over all the rows. It then iterates over the rows that are actually visible in the table view's viewport. As it happens to be on my screen, there are seven rows visible.</p>

<p>With the <em>line of interest</em> commented out, the example's output reduces to:</p>

<pre><code>*** show ***
query  0
query  1
query  2
query  3
query  0
query  1
query  2
query  3
</code></pre>

<p>As the rows now have their default height which is slightly larger than before, only four rows are visible now. More importantly, only eight rows are queried from the model in total now.</p>

<p>Why this strange behaviour?</p>

<h1>SCCE</h1>

<p><code>scce.pro</code>:</p>

<pre><code>QT += core gui widgets
CONFIG += c++11
TARGET = sscce
TEMPLATE = app
SOURCES += main.cpp
</code></pre>

<p><code>main.cc</code>:</p>

<pre><code>#include &lt;QAbstractItemModel&gt;
#include &lt;QApplication&gt;
#include &lt;QHeaderView&gt;
#include &lt;QTableView&gt;
#include &lt;QDebug&gt;

class Model: public QAbstractItemModel {
    public:
        int rowCount(const QModelIndex &amp;parent) const {
            return parent.isValid() ? 0 : 500;
        }

        int columnCount(const QModelIndex &amp;parent) const {
            return parent.isValid() ? 0 : 1;
        }

        QModelIndex parent(const QModelIndex &amp;/* child */) const {
            return QModelIndex();
        }

        QModelIndex index(int row, int column, const QModelIndex &amp;parent) const {
            return parent.isValid() ? QModelIndex() : createIndex(row, column, Q_NULLPTR);
        }

        QVariant data(const QModelIndex &amp;index, int role) const {
            if (role == Qt::DisplayRole)
                qDebug() &lt;&lt; "query " &lt;&lt; index.row();

            return (index.isValid() &amp;&amp; (role == Qt::DisplayRole)) ?
                QStringLiteral("Row %1").arg(index.row()) : QVariant();
        }

        QVariant headerData(int section, Qt::Orientation orientation, int role) const {
            return ((orientation == Qt::Vertical) &amp;&amp; (role == Qt::DisplayRole)) ? section : QVariant();
        }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QTableView view;
    view.setModel(new Model());

    /* Line of interest: */
    view.verticalHeader()-&gt;setSectionResizeMode(QHeaderView::ResizeToContents);

    qDebug() &lt;&lt; "*** show ***";
    view.show();
    return app.exec();
}
</code></pre>