How to delete QTreeWidgetItem

pyside, python, qt, qtreewidget, qtreewidgetitem

Solution

Python is different from C++ in the sense of memory management/deleting objects. Python has a garbage collector (GC) that manages destroying of the objects automatically. That occurs when the reference count of an object reaches zero.

`del i` only means 'decrement the reference count by one'. It never results in a direct call to `__del__`. `__del__` of an object is only called when reference count reaches to zero and is about to be garbage collected. (Although this is true for CPython, it's not guaranteed for every implementation. It depends on the GC implementation. So you should not rely on `__del__` at all)

Keeping story short, the call time of `__del__` is ambiguous. You should never call `__del__` (or any other `__foo__` special methods) directly. In fact, for the reasons above you should rather avoid the use of `__del__` at all (usually).

Apart from that, there is another issue.

tree.removeItemWidget(i, 0)

This does not remove an item from `QTreeWidget`. As the name suggests, it removes a widget from an item, not the `QTreeWidgetItem`. It's counterpart to the `setItemWidget` method, not the `addTopLevelItem` method.

If you need to remove a specific item from the tree, you should use `takeTopLevelItem`.

tree.takeTopLevelItem(tree.indexOfTopLevelItem(i))

`tree.clear()` is fine. It will remove every top level item from the tree.

Problem

Several webpages say that `QTreeWidgetItem` can be deleted by deleting or `QTreeWidget.clear`ing. But my code sample below doesn't seem to do so. Am I doing anything wrong? ``` #!/usr/bin/python import sys from PySide.QtGui import QApplication, QWidget, QTreeWidget, QTreeWidgetItem #from PyQt4.QtGui import QApplication, QWidget, QTreeWidget, QTreeWidgetItem # Result was the same with `PySide` import time class TreeWidgetItemChild(QTreeWidgetItem): def __init__(self): super(TreeWidgetItemChild, self).__init__() print 'TreeWidgetItemChild init' def __del__(self): print 'TreeWidgetItemChild del' def test_QTree_clear_children(): tree = QTreeWidget() tree.setHeaderLabel('funksoul') i = TreeWidgetItemChild() tree.addTopLevelItem(i) print 'Before clearing' #tree.clear() # Didn't call destructor (__del__) #tree.removeItemWidget (i, 0) # Didn't call destructor #i.__del__() # Called destructor but it's called again afterward del i # Didn't call destructor time.sleep(1) print 'After clearing' if __name__ == '__main__': app = QApplication(sys.argv) test_QTree_clear_children() ``` Printed as: ``` TreeWidgetItemChild init Before clearing After clearing TreeWidgetItemChild del ``` Looks to me `TreeWidgetItemChild` gets deleted upon the termination of process, not by any of my deletion actions.

Original source

Related problems