ein QTableView
Da ein Modell benutzerdefinierte Element zeigt mit einer einzigen Spalte aber viele Hunderte von Zeilen, die sectionResizeMode
des vertikalen Kopf ResizeToContents
Einstellung eine massive negative Auswirkungen hat auf Leistung.Performance-Problem mit QHeaderView :: ResizeToContents für vertikale Header in QTableView
Aus Debug-Gründen habe ich eine Ausgabe in der Methode des Elementmodells hinzugefügt, um zu sehen, welche Zeilen tatsächlich von der Ansicht abgefragt werden. Es stellt sich heraus, dass die Tabellenansicht tatsächlich jede einzelne Zeile in dem Modell abfragt, sobald es mit dem Resize-Modus zu ResizeToContents
gesetzt zu machen braucht - egal, wie viele Zeilen selbst angezeigt.
Das folgende Codebeispiel gibt die folgende Ausgabe:
*** 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
Das heißt, der Blick scheint zunächst zweimal über alle Zeilen zu durchlaufen. Es iteriert dann über die Zeilen, die im Ansichtsfenster der Tabellenansicht tatsächlich sichtbar sind. Wie es zufällig auf meinem Bildschirm ist, sind sieben Reihen sichtbar.
Mit der Linie von Interesse Kommentar gesetzt, der Ausgang des Beispiel reduziert sich auf:
*** show ***
query 0
query 1
query 2
query 3
query 0
query 1
query 2
query 3
Da die Zeilen jetzt ihre Standardhöhe haben, die als vorher etwas größer ist, nur vier Reihen jetzt sichtbar sind. Noch wichtiger ist, dass jetzt insgesamt nur acht Zeilen vom Modell abgefragt werden.
Warum dieses seltsame Verhalten?
SCCE
scce.pro
:
QT += core gui widgets
CONFIG += c++11
TARGET = sscce
TEMPLATE = app
SOURCES += main.cpp
main.cc
:
#include <QAbstractItemModel>
#include <QApplication>
#include <QHeaderView>
#include <QTableView>
#include <QDebug>
class Model: public QAbstractItemModel {
public:
int rowCount(const QModelIndex &parent) const {
return parent.isValid() ? 0 : 500;
}
int columnCount(const QModelIndex &parent) const {
return parent.isValid() ? 0 : 1;
}
QModelIndex parent(const QModelIndex &/* child */) const {
return QModelIndex();
}
QModelIndex index(int row, int column, const QModelIndex &parent) const {
return parent.isValid() ? QModelIndex() : createIndex(row, column, Q_NULLPTR);
}
QVariant data(const QModelIndex &index, int role) const {
if (role == Qt::DisplayRole)
qDebug() << "query " << index.row();
return (index.isValid() && (role == Qt::DisplayRole)) ?
QStringLiteral("Row %1").arg(index.row()) : QVariant();
}
QVariant headerData(int section, Qt::Orientation orientation, int role) const {
return ((orientation == Qt::Vertical) && (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()->setSectionResizeMode(QHeaderView::ResizeToContents);
qDebug() << "*** show ***";
view.show();
return app.exec();
}