有几个网页说,删除可以通过QTreeWidget.clear或QTreeWidgetItem来删除。但是我下面的代码样本似乎不能做到这一点。我做错什么了吗?
#!/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()打印为:
TreeWidgetItemChild init
Before clearing
After clearing
TreeWidgetItemChild del在我看来,TreeWidgetItemChild在进程终止时被删除,而不是通过我的任何删除操作。
发布于 2012-10-25 16:58:50
Python与C++在内存管理/删除对象方面有所不同。Python有一个垃圾收集器(GC),它自动管理对象的销毁。当对象的引用计数达到零时会发生这种情况。
del i只表示“将引用计数减一”。它不会导致对__del__的直接调用。仅当引用计数达到零且即将被垃圾回收时,才会调用对象的__del__。(虽然这对于CPython是正确的,但并不保证每个实现都是这样的。这取决于GC实现。所以你根本不应该依赖于__del__ )
简单来说,__del__的调用时间是模棱两可的。您永远不应该直接调用__del__ (或任何其他__foo__特殊方法)。事实上,由于上述原因,您应该完全避免使用__del__ (通常如此)。
除此之外,还有另一个问题。
tree.removeItemWidget(i, 0)这不会从QTreeWidget中删除项目。顾名思义,它从项目中删除小部件,而不是QTreeWidgetItem。它对应于setItemWidget方法,而不是addTopLevelItem方法。
如果需要从树中删除特定项目,则应使用takeTopLevelItem。
tree.takeTopLevelItem(tree.indexOfTopLevelItem(i))tree.clear()很好。它将从树中删除所有顶级项目。
发布于 2012-10-25 16:25:35
通过调用del i,您只是删除了引用,而不是它引用的实际C++对象(Referent),而不是对象本身。
将TreeWidgetItemChild.__del__函数更改为:
def __del__(self):
treeWidget = self.treeWidget()
#removing the QTreeItemWidget object
treeWidget.takeTopLevelItem(treeWidget.indexOfTopLevelItem(self))
print 'TreeWidgetItemChild del'发布于 2012-10-25 18:15:45
您将树项目(即树节点)与给定项目可以包含的小部件相混淆。
下面的示例创建一个QTreeWidget并向其中添加两个项:顶级项和嵌套项。删除注释,您可以看到它们都是如何从树中删除的。
#!/usr/bin/env python
import sys
from PyQt4.QtGui import *
class MyMainWindow(QMainWindow):
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.tree = QTreeWidget(self)
self.setCentralWidget(self.tree)
self.tree.setHeaderLabel('funksoul')
i = QTreeWidgetItem(self.tree, ['top level'])
self.tree.addTopLevelItem(i)
j = QTreeWidgetItem(i ,['nested level'])
#i.takeChild(0)
#self.tree.takeTopLevelItem(0)
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = MyMainWindow()
ui.show()
sys.exit(app.exec_())要从树中删除这两种类型的项目,您需要项目索引。如果您有对要删除的项的引用,则可以使用indexOfTopLevelItem和indexOfChild函数获取相应的索引。
https://stackoverflow.com/questions/13062327
复制相似问题