7

假设我有一个充满数据的二维数组,比如 10 x 10。内容以及行数可以随时更改。现在我想在 QTableWidget 中显示这些数据。
我使用超时 1 秒的计时器来刷新表格内容。如果我使用超时槽

void slot_timeOut()
{
    //Iterate over the rows
    //and for each cell do something like
    ui->tw_data->setItem(row, 0, new TableWidgetItem(data[row][0]);
    ui->tw_data->setItem(row, 0, new TableWidgetItem(data[row][1]);
    //...
    ui->tw_data->setItem(row, 0, new TableWidgetItem(data[row][9]);
}

使用新的 TableWidgetItem 让我担心。我没有提及它,我从不删除它。
在一段时间内这是内存泄漏,还是由 Qt 管理,请帮助...

4

4 回答 4

7

没有泄漏,因为

该表拥有该项目的所有权。

(来自QTableWidget::setItem())。

这里的所有权意味着 QTableWidget 将在不再需要时删除该项目,或者 QTableWidget 本身被破坏。所有权通常记录在 Qt 文档中(如果没有,我认为这是一个 Qt 错误)。

一旦 setItem() 在同一个单元格上被调用返回,之前设置的 QTableWidgetItem 将被删除:

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QTableWidget widget(2, 1);
    QTableWidgetItem* foo = new QTableWidgetItem("Foo");
    widget.setItem(0, 0, foo);
    qDebug() << foo->text(); //works
    widget.setItem(0, 0, new QTableWidgetItem("Bar")); //replaces foo with bar and deletes foo
    qDebug() << foo->text(); // Undefined (usually, crash)
    widget.show();
    return app.exec();
}

如果您使用的是 Linux,您还可以通过在 valgrind 中使用 --leak-check=full 运行上述代码(没有第二个 qDebug())来验证行为。

于 2014-02-24T21:02:55.457 回答
3

从 Qt文档

void QTableWidget::setItem ( int row, int column, QTableWidgetItem * item ) 将给定行和列的项目设置为项目。该表拥有该项目的所有权。

这表明 Qt 将根据需要管理对象的内存。

于 2014-02-24T21:00:55.670 回答
2

当您将 Q 对象添加到单元格时,它将正确删除。我在牢房里推着成千上万的 C 弦,看着我的记忆爆炸了。使我的“原始文本数据”成为 QString,我的问题就解决了。

于 2016-11-10T09:40:11.560 回答
0

出现这样的问题是:Qt并没有真正清除通过QTableWidgetItem分配的内存。

for( int row = 0; row < 35; row++)
{
    for(int i = 0; i < 9; i++)
    {
        QTableWidgetItem* item = new QTableWidgetItem();
        item->setText(QString::number(i));
        ui->tableWidget->setItem(row, i, item);
    }
}

这段代码给出了 116 字节的泄漏。

我们找到了这个解决方案:您可以使用 QLineEdit 代替 QTableWidgetItem:

 QLineEdit* tableline = new QLineEdit();
 m_qtablewidget->setCellWidget(row, column, tableline);

ps 使用 Dr.memory 搜索泄漏

于 2019-08-20T12:21:19.893 回答