Isa*_*acS 9 python qt qtreewidget qtreewidgetitem pyside
有几个网页说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()
Run Code Online (Sandbox Code Playgroud)
印刷为:
TreeWidgetItemChild init
Before clearing
After clearing
TreeWidgetItemChild del
Run Code Online (Sandbox Code Playgroud)
对我来说TreeWidgetItemChild
,在流程终止时会删除,而不是通过我的任何删除操作.
Ava*_*ris 10
在内存管理/删除对象的意义上,Python与C++不同.Python有一个垃圾收集器(GC),可以自动管理对象的销毁.当对象的引用计数达到零时发生这种情况.
del i
仅表示'将参考计数减1'.它永远不会导致直接调用__del__
.__del__
只有当引用计数达到零并且即将被垃圾收集时才调用对象.(虽然CPython也是如此,但并不能保证每个实现都有.这取决于GC的实现.所以你根本不应该依赖它__del__
)
保持故事简短,通话时间__del__
不明确.你不应该直接打电话__del__
(或任何其他__foo__
特殊方法).事实上,由于上述原因,你应该完全避免使用__del__
(通常).
除此之外,还有另一个问题.
tree.removeItemWidget(i, 0)
Run Code Online (Sandbox Code Playgroud)
这不会删除项目QTreeWidget
.顾名思义,它从项目中删除了一个小部件,而不是QTreeWidgetItem
.它与setItemWidget
方法相对应,而不是addTopLevelItem
方法.
如果需要从树中删除特定项,则应使用takeTopLevelItem
.
tree.takeTopLevelItem(tree.indexOfTopLevelItem(i))
Run Code Online (Sandbox Code Playgroud)
tree.clear()
很好.它将从树中删除每个顶级项目.
作为Avaris优秀答案的尾声,让我们提出一种适用于所有小部件和小部件项(而不仅仅是顶级树小部件项)的更通用的方法。这所谓的香格里拉是不是好得令人难以置信?
\n\n用马里奥的话来说:“Waaaa!Let\'sa-go!”
\n\n具体来说,如果您的项目利用:
\n\nPySide2,导入shiboken2
模块并将每个要删除的树小部件项传递给函数shiboken2.delete()
ala:
# Well, isn\'t that nice. Thanks, Qt Company.\nfrom PySide2 import shiboken2\n\n# Add this item to this tree.\ntree = QTreeWidget()\nitem = TreeWidgetItemChild()\ntree.addTopLevelItem(item)\n\n# Remove this item from this tree. We\'re done here, folks.\nshiboken2.delete(item)\n
Run Code Online (Sandbox Code Playgroud)PyQt5,导入sip
模块并将每个要删除的树小部件项传递给函数sip.delete()
ala:
# Well, isn\'t that not-quite-so-nice. You are now required to import any\n# arbitrary PyQt5 submodule *BEFORE* importing "sip". Hidden side effects are\n# shameful, of course, but we don\'t make the rules. We only enforce them. For\n# detailed discussion, see:\n#\n# http://pyqt.sourceforge.net/Docs/PyQt5/incompatibilities.html#pyqt-v5-11\n#\n# If your project requires PyQt5 >= 5.11, the following compatibility hack may\n# be safely reduced to the following one-liner:\n#\n# from PyQt5 import sip\nfrom PyQt5 import QtCore\nimport sip\n\n# Add this item to this tree.\ntree = QTreeWidget()\nitem = TreeWidgetItemChild()\ntree.addTopLevelItem(item)\n\n# Remove this item from this tree.\nsip.delete(item)\n
Run Code Online (Sandbox Code Playgroud)是的,这在所有平台和 (PyQt5|PySide2) 版本下的行为都符合预期。Python 特有的sip.delete()
和shiboken2.delete()
方法是底层 C++ 运算符 \xe2\x80\x93 的高级包装器delete
,并且操作完全相同。在实例的情况下QTreeWidgetItem
,这会重现立即从其父树中删除传递的项的 C++ 行为。
是的,它既辉煌又粗略。感谢alexisdm在其他地方的相关答案,为这个过度紧张的答案背后提供了动力。荣耀归于亚历克西斯。
\n