代码:
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/