I have a QTreeWidget
with two columns: one for property name and one for property value. The value can be edited via a widget. For example one property is Animal. When you double click the property value column I make a (custom) combobox with different animal types via this code:
QTreeWidgetItemComboBox* comboBox = new QTreeWidgetItemComboBox(treeItem, 1);
// treeitem is a pointer to the row that is double clicked
comboBox->addItems(QStringList() << "Bird" << "Fish" << "Ape");
ui.treeWidget->setItemWidget(treeItem, 1, comboBox);
When the row loses focus I remove the widget again (and the value is put as text of the QTreeWidgetItem
). For removing I use
ui.treeWidget->removeItemWidget(treeItem, 1);
Now I'm wondering, since I've used new
, do I neww to also delete
the widget. I know this is the case if you use takeChild(i)
for example. But I didn't see something similar for an itemWidget.
Do I need to delete it what would be the right order?
QTreeWidgetItemComboBox* comboBox = ui.treeWidget->itemWidget(treeItem,1);
// Do I need a cast here since the return type is QWidget*
ui.treeWidget->removeItemWidget(treeItem, 1);
delete comboBox;
or
QTreeWidgetItemComboBox* comboBox = ui.treeWidget->itemWidget(treeItem,1);
// Do I need a cast here since the return type is QWidget*
delete comboBox;
ui.treeWidget->removeItemWidget(treeItem, 1);
When the widget is added ot the QTreeWidget
, it indeed takes ownership of the widget. But it only implies that the widget will be deleted when the parent is destroyed.
So if you just want to remove the widget while keeping the parent QTreeWidget
alive, you indeed have to delete it manually.
The correct solution is the first one, remove the widget from the QTreeWidget
first, and then delete it with one of the following ways:
delete comboBox;
comboBox = nullptr;
or:
comboBox.deleteLater();
The second one is preferred.
EDIT:
I don't change the answer since it could be a dishonest to change what was already accepted, ...
But as @Scopchanov mentioned, by reading the source code, the QTreeWidget::removeItemWidget()
already calls the deleteLater()
method on the old widget. We don't have to do it manually.
Anyway, the documentation says it is safe to call deleteLater()
more than once:
Note: It is safe to call this function more than once; when the first deferred deletion event is delivered, any pending events for the object are removed from the event queue.
Therefore, manually deleting the widget after calling QTreeWidget::removeItemWidget()
becomes useless.
You are not allowed to delete the item widget as the tree is the owner of the widget once it has been passed to the tree with setItemWidget()
.
From the documentation of setItemWidget()
:
Note: The tree takes ownership of the widget.
EDIT: In case you want a new widget, simply call setItemWidget()
once more or call removeItemWidget()
in case you do not need the widget anymore. The tree will ensure that no memory gets lost.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With