2016-12-29 78 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设置所有行的高度相同,甚至更多,它设置的高度最适合的所有行,所以它必须查询整个表格。

如果行是恒定的,你可以手动确定自己的身高,你可能会尝试存储的最小需要的高度,然后再安装一个事件过滤器用于调整和手动设置的高度。其他的情况是类似的,但更复杂的处理(你有当添加/删除/编辑行等连接到信号)。