Управление памятью Qt для контейнеров - PullRequest
5 голосов
/ 05 февраля 2012

Я знаю, что в Qt много вопросов об управлении памятью. Также я читаю эти вопросы:

Но в моем случае я снова запутался!

У меня есть QTableWidget с именем myTable. Я добавляю к нему виджеты времени выполнения setCellWidget:

void MyClass::build()
{
    for (int i=LOW; i<HIGH; i++)
    {
        QWidget *widget = new QWidget(myTable);
        //
        // ...
        //
        myTable->setCellWidget(i, 0, widget);
    }
}

Затем я удаляю все элементы, как показано ниже:

void MyClass::destroy()
{
    for (int i = myTable->rowCount(); i >= 0; --i)
        myTable->removeRow(i);
}

Эти методы вызывают много раз в течение длительного времени. И myTable как родитель этих виджетов будет жить в течение всей жизни программы.

Метод дозы destroy() полностью и автоматически освобождает память? Или я delete выделил виджеты сам, как показано ниже?

void MyClass::destroy2() // This maybe causes to crash !!
{
    for (int i = myTable->rowCount(); i >= 0; --i)
    {
        QWidget *w = myTable->cellWidget(i, 0);
        delete w;
        myTable->removeRow(i);
    }
}

Ответы [ 2 ]

5 голосов
/ 05 февраля 2012

Вообще говоря, если вы сомневаетесь или не понимаете, как использовать класс, обратитесь к документации, которая должна была прийти с ним. К счастью, QTableWidget::setCellWidget() действительно поставляется с документацией :

void QTableWidget :: setCellWidget (int-строка, int-столбец, QWidget * виджет)

Устанавливает данный виджет для отображения в ячейке в данная строка и столбец передают право собственности на виджет стол [акцент мой] . Если виджет ячейки A заменен на виджет ячейки B, виджет ячейки А будет удален. Например, в приведенном ниже фрагменте кода Объект QLineEdit будет удален.

    setCellWidget(index, new QLineEdit);
    ...
    setCellWidget(index, new QTextEdit);

После вызова myTable->setCellWidget() таблица теперь владеет виджетом, который вы в нее передали. Это означает, что myTable отвечает за удаление виджетов, которые вы передаете setCellWidget(). Вам не нужно делать delete w; при удалении строк. Ваша первая destroy() функция должна быть достаточной.

2 голосов
/ 05 февраля 2012

С документация :

void QTableWidget::setCellWidget ( int row, int column, QWidget * widget )

Устанавливает отображение указанного виджета в ячейке в заданной строке и столбце, передавая владение виджетом таблице.

Если виджет ячейки A заменен на виджет ячейки B, виджет ячейки A будет удален. Например, в приведенном ниже фрагменте кода объект QLineEdit будет удален.

То есть вы не выполняете очистку вручную, поскольку освобождение ресурсов происходит автоматически в дереве объектов Qt, частью которого является widget.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...