2016-12-29 79 views
0

ResizeToContents垂直頭部中給出一個QTableView顯示與一列,但數百行的自定義項目模型,設置垂直頭的sectionResizeModeResizeToContents有巨大的負面影響性能。性能問題與QHeaderView ::在QTableView中

調試的原因,我加入了項目模型的方法::data一些輸出,看看哪些行實際上是由視圖查詢。事實證明,表視圖實際上儘快查詢模型中的每一行,因爲它需要渲染設置爲ResizeToContents的調整模式 - 無論有多少行甚至被顯示。下面

的代碼示例給出下面的輸出:

*** 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 

即,視圖第一似乎在所有的行進行迭代兩次。然後它遍歷表視圖的視口中實際可見的行。正好在我的屏幕上,有七行可見。

隨着行註釋掉興趣,在這個例子的輸出減少到:

*** show *** 
query 0 
query 1 
query 2 
query 3 
query 0 
query 1 
query 2 
query 3 

由於行現在有自己的默認高度比之前略大,僅四大行現在是可見的。更重要的是,現在只有8行被查詢。

爲什麼這種奇怪的行爲?

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(); 
} 

回答

0

ResizeToContents設置所有行的高度相同,甚至更多,它設置的高度最適合的所有行,所以它必須查詢整個表格。

如果行是恆定的,你可以手動確定自己的身高,你可能會嘗試存儲的最小需要的高度,然後再安裝一個事件過濾器用於調整和手動設置的高度。其他的情況是類似的,但更復雜的處理(你有當添加/刪除/編輯行等連接到信號)。