一些网页说QTreeWidgetItem
可以通过删除或删除QTreeWidget.clear
荷兰国际集团。 但我的代码示例如下似乎并没有这样做。 难道我做错了什么?
#!/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
获取过程中,没有任何的缺失我在行动终止删除。
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()
是好的。 它将从树中删除所有的顶级项目。
通过调用del i
你只是删除它指的是,不是对象本身的引用而不是实际的C ++对象( 所指 )。
更改TreeWidgetItemChild.__del__
功能:
def __del__(self):
treeWidget = self.treeWidget()
#removing the QTreeItemWidget object
treeWidget.takeTopLevelItem(treeWidget.indexOfTopLevelItem(self))
print 'TreeWidgetItemChild del'
你混淆树项目(即树的节点)与给定的项目可以包含的部件。
下面的示例创建一个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
功能。
作为尾声阿瓦里斯 “ 出色答卷 ,让我们鞭打适用于所有控件和控件项目(而不是仅仅顶级树控件项目)一个更加通用的做法。 这是所谓的香格里拉太好了,是真的吗?
为了答曰马里奥: “Waaaa Let's-A-去!”
在这里,我们-A-围棋
特别是,如果你的项目利用:
PySide2,导入shiboken2
模块,并通过每个树插件项目被删除到shiboken2.delete()
函数的ala:
# Well, isn't that nice. Thanks, Qt Company. from PySide2 import shiboken2 # Add this item to this tree. tree = QTreeWidget() item = TreeWidgetItemChild() tree.addTopLevelItem(item) # Remove this item from this tree. We're done here, folks. shiboken2.delete(item)
PyQt5,导入sip
模块,并通过每个树插件项目被删除到sip.delete()
函数的ala:
# Well, isn't that not-quite-so-nice. You are now required to import any # arbitrary PyQt5 submodule *BEFORE* importing "sip". Hidden side effects are # shameful, of course, but we don't make the rules. We only enforce them. For # detailed discussion, see: # # http://pyqt.sourceforge.net/Docs/PyQt5/incompatibilities.html#pyqt-v5-11 # # If your project requires PyQt5 >= 5.11, the following compatibility hack may # be safely reduced to the following one-liner: # # from PyQt5 import sip from PyQt5 import QtCore import sip # Add this item to this tree. tree = QTreeWidget() item = TreeWidgetItemChild() tree.addTopLevelItem(item) # Remove this item from this tree. sip.delete(item)
没有什么可能出问题
是的,这表现在所有的平台和预期(PyQt5 | PySide2)版本。 具体Python的sip.delete()
和shiboken2.delete()
方法是底层的C左右的高级别包装++ delete
操作员-和准确的操作相同。 在的情况下QTreeWidgetItem
情况下,这立即再现从其父树移除通过项目的C ++行为。
是的,这是既光荣而粗略。 由于alexisdm的其他地方相关答案为此寝食难安答案背后的动机动力。 荣耀归于alexisdm 。