c++ - 第一次填充 QTableWidget 时,一切都很好,但是当我重新填充它时,速度明显变慢

标签 c++ qt qtablewidget qtablewidgetitem

代码:

populateTable()
{
  tableWidget->clearContents();
  tableWidget->setRowCount(stringList.size());

  for(int i = 0; i < stringList.size(); ++i)
  {
    tableWidget->setItem(i, 0, new QTableWidgetItem(stringList.at(i)));
  }
}

问题:

第一次运行 populateTable() 时,一切正常。但是接下来的时间,它的运行速度明显比以前慢。

讨论:

经过仔细测试后,我怀疑 clearContents() 是问题所在。因为简单地改变代码从

tableWidget->clearContents();

到:

tableWidget->setRowCount(0);

解决了这个问题,但现在又产生了另一个问题;将行计数设置为“0”似乎并没有删除分配给堆的 QTableWidgetItems,它似乎只是留下了项目的所有权,所以它留下了内存泄漏。 (或者至少我只是这么认为...)

Qt 在 QTableWidget 中的文档相当模糊,所以我不完全知道 clearContents() 到底做了什么。在文档中它说“从 View 中删除所有不在标题中的项目”所以我问,表格的内容只是隐藏了吗?它会被删除吗?我不太确定。我的理论是 clearContents() 仅隐藏项目,任何下一次填充表的尝试实际上会删除和删除每个项目,然后分配一个新项目以设置在表上,这反过来又是一项昂贵的操作。

另一个有趣的事情是,Qt 关于 QTableWidget 的文档建议填充 QTableWidget 的正确方法是在堆上分配一个 QTableWidgetItem,然后使用 setItem() 将它设置在一个表单元格上,就像我在上面的代码中介绍的那样,我发现很奇怪...

总结:

是否有替代方法来填充和重新填充 Qt 表而不会出现所有这些问题?如果没有,是否有解决这些问题的方法?

最佳答案

“Qt 关于 QTableWidget 的文档建议填充 QTableWidget 的正确方法是在堆上分配 QTableWidgetItem,然后使用 setItem() 将其设置在表格单元格上,就像我在上面的代码中介绍的那样,我发现变得很奇怪……”

考虑到 documentation for QTableWidget::setItem,我并不觉得这很奇怪明确表示小部件拥有该项目的所有权!

“将行计数设置为‘0’似乎并没有删除堆分配的 QTableWidgetItems,它似乎只是留下了项目的所有权,所以它留下了内存泄漏。(或者至少我只是这么认为...)”

与其猜测它是否泄漏,您可以创建自己的 QTableWidgetItem 子类...并将代码放入其析构函数中,以便您可以放置​​断点并确定。或者,Qt 源代码非常清晰。 setRowCount 调用 removeRows,它确实删除了 QTableWidgetItems:

http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/itemviews/qtablewidget.cpp#line370

http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/itemviews/qtablewidget.cpp#line100

但这再次与 documentation for QTableWidget::setRowCount 一致

Sets the number of rows in this model to rows. If this is less than rowCount(), the data in the unwanted rows is discarded.

您真的不应该看到 clearContents() 和 setRowCount(0) 之间有太大区别。您是否生成了一个可重现的小示例,而不是缠绕在任何更大的程序中,以证明这种现象?

关于c++ - 第一次填充 QTableWidget 时,一切都很好,但是当我重新填充它时,速度明显变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10192579/

相关文章:

c++ - Qt HBoxLayout - 将小部件转换到新行

c++ - 当您在检索到的值的表达式上进行分支时,是否有像 `if (Value * value = getValue())` 这样的习语?

qt - QTableWidget 中的自定义排序

c++ - 为什么 C++ 中的模板 mixin 不再是主流?

c++ - 为什么不允许在 const 非 volatile 成员函数上消除公共(public)子表达式?

c++ - 我应该在 C++11 中显式声明转换运算符吗?

python - QTableWidget 选择多个单元格永久与 Ctrl + MouseClick 相同

c++ - 如何创建新文件夹并将文件保存到其中?

qt - 如何在 Qt VirtualKeyboard 中捕获隐藏按键事件

python - QTableWidget:插入行使应用程序崩溃 python