c++ - 当许多单元格同时可见时,QTableView 滚动缓慢

标签 c++ performance qt qtableview

背景: 我正在使用 Qt 5.5.1 开发应用程序,并使用 msvc2013 进行编译。在这个应用程序中,我使用自己的 QTableView 实现,以及自定义 QStyledItemDelegate(需要自定义单元格编辑)和 QAbstractTableModel。我打算让这个 View 处理我包装在上述模型中的大量数据。我允许用户使用一些数据编辑选项、自定义排序、“无效”行结束等。

问题:我的 QTableView 子类的滚动速度很慢 - 显示的表格越多(通过调整窗口大小)滚动速度越慢,例如显示约 250 个单元格(全屏)= 慢,显示约 70 个单元格(小窗口)= 快。

到目前为止我尝试了什么:

  • 首先是检查我的模型是否正在减慢速度 - 我测量了读取 10k 个样本的时间(使用 QTime::elapsed()),结果显示为 0 或 1 毫秒。然后我简单地更改了 QTableView::data 方法以始终返回预定义的字符串而不获取任何实际数据。

    QVariant DataSet_TableModel::data(const QModelIndex &index, int role) 常量 { 如果(角色 == Qt::ItemDataRole::DisplayRole){ 返回 QVariant("aRatherLongString");//导致缓慢滚动 //返回 QVariant("a");//这会导致快速滚动 } 否则返回 QVariant(); } 如您所见,速度似乎受每个单元格查看的字符数的影响,而不是受与数据源的基础连接的影响。

  • 在我自定义的 QStyledItemDelegate 实现中,我尝试了与上面相同的“技巧”——这次覆盖了 displayText 方法:

    QString DataSet_TableModel_StyledItemDelegate::displayText(const QVariant &value, const QLocale &locale) const { 返回“a”//快 //返回 "aRatherLongString";//慢的 //返回 QStyledItemDelegate::displayText(value, locale);//默认 }

  • 在与一位 friend 思考后,我们得出结论,也许我们可以禁用单元格的绘图/绘画/更新,直到完成整个滚动操作。它可能会导致一些闪烁,但值得一试。不幸的是,我们真的不知道如何解决这个问题。我们曾经使用过 QTableView 方法:scrollContentsBy(int dx, int dy) 和 verticalScrollbarAction(int action) - 我们已经正确地捕获了滚动 Action (这两种方法都会拦截它)并尝试以某种方式禁用重新绘制,如下所示:

    void DataSet_TableView::verticalScrollbarAction(int action) { 这个->setUpdatesEnabled(false); QTableView::verticalScrollbarAction( Action ); 这个->setUpdatesEnabled(true); }

...但它没有任何可见的效果。 我们应该如何处理它?我们是否需要对直接放入单元格中的项目使用 setUpdatesEnabled()? (不确定那些是什么 - 小部件?)

以下是测试此问题时截取的屏幕截图:

Predefined text, no calls to underlying data structure - slow scrolling, 'full screen'

Predefined text, no calls to underlying data structure - fast scrolling, windowed

请求:您能否帮我查明此问题的原因并在可能的情况下提出解决方案?是我使用的类的限制吗?

最佳答案

首先,您还应该在 release 中运行您的应用程序模式来检查您的性能,根据我的经验,使用 debug 时性能会大大降低模式。

其次,您需要注意模型 data每次调整大小、滚动、聚焦、右键单击等时都会调用方法和委托(delegate)方法。这些操作会触发为每个显示的单元格调用这些方法,因此您需要确保不进行任何不必要的处理。

单元格内的项目是调用自己方法的委托(delegate)(例如:paint)。

一些特定于 C++ 的优化将有助于实现这些方法,例如使用 switch而不是 if声明,见解释herehere .使用条件(三元)运算符也可能会加快速度,更多信息 here , here以及一些关于昂贵支票的信息here .

此外,QVariant 以不同的方式处理文本,如下所示,您应该尝试两种方式并检查速度是否有任何差异。有些转化比其他转化更昂贵。

v = QVariant("hello");          // The variant now contains a QByteArray
v = QVariant(tr("hello"));      // The variant now contains a QString

关于c++ - 当许多单元格同时可见时,QTableView 滚动缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36828550/

相关文章:

由于使用存储函数进行 ORDER BY,MySQL 查询速度变慢

python - 使用 python 用分位数索引替换 numpy 数组中的条目

c++ - Qt Model-View框架中如何替换children?

c++ - 在运行时向对象添加函数集合

c++ - 继承 : call a derived class function from base class

performance - 为什么红黑树比 2-3 棵树更好?

c++ - 如何有效地在窗口中滚动 1024x90000 图像?

c++ - 错误 "token is not a valid binary operator in a preprocessor subexpression"

c++ - 在 Windows 中使用 OpenCV 3.0 从文件夹加载图像

c++ - bind 如何知道何时转换为指针?