QHeaderView::ResizeToContent在QTableView中垂直标题的性能问题
Performance issue with QHeaderView::ResizeToContents for vertical header in QTableView
给定一个显示具有单列但数百行的自定义项目模型的QTableView
,将垂直标题的sectionResizeMode
设置为ResizeToContents
会对性能产生巨大的负面影响。
出于调试原因,我在项模型的::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
由于这些行现在的默认高度比以前略大,因此现在只有四行可见。更重要的是,现在总共只从模型中查询了八行。
为什么会有这种奇怪的行为?
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();
}
ResizeToContents
为所有行设置相同的高度,甚至更多,它设置最适合所有行的高度,因此它必须查询整个表。
如果行是常量,并且您可以手动确定其高度,则可以尝试存储所需的最小高度,然后安装事件过滤器以调整大小并手动设置高度。其他方案类似,但处理起来更复杂(在添加/删除/编辑行等时必须连接到信号)。
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 标题与标准标题具有相同名称但大小写不同的问题
- 为什么#Define会在标题中引起问题
- QHeaderView::ResizeToContent在QTableView中垂直标题的性能问题
- Visual SDKDDKVER.H缺少,但是安装了WinSDK?(C 标题问题)
- 标题文件问题中的类定义
- C++:标题问题
- 我在function.cpp文件中有我的标题问题
- Qt 5.0,包括个人标题问题