python – 没有用父窗口删除QWidget

使用下面的代码,我的Preview小部件的__del__方法永远不会被调用.如果我取消注释“del window”行,它会.为什么?

#!/usr/bin/env python

from PyQt4 import QtGui

class Preview(QtGui.QWidget):
  def __init__(self, parent):
    QtGui.QWidget.__init__(self, parent)

  def __del__(self):
    print("Deleting Preview")

class PreviewWindow(QtGui.QMainWindow):
  def __init__(self):
    QtGui.QMainWindow.__init__(self)

    self.widget = Preview(self)
    self.setCentralWidget(self.widget)

  def __del__(self):
    print("Deleting PreviewWindow")

if __name__ == "__main__":
  app = QtGui.QApplication(["Dimension Preview"])
  window = PreviewWindow()
  window.show()
  app.exec()
  # del window

最佳答案 如果QObject子类具有父级,则Qt将在删除父级时将其删除.另一方面,如果QObject子类没有父类,它将(最终)被python删除.

希望这个例子能让事情变得更加清晰:

from PyQt4 import QtGui

class Widget(QtGui.QWidget):
    def __init__(self, parent):
        QtGui.QWidget.__init__(self, parent)
        self.destroyed.connect(self.handleDestroyed)

    def __del__(self):
        print ('__del__:', self)

    def handleDestroyed(self, source):
        print ('destroyed:', source)

class Foo(Widget):
    def __init__(self, parent):
        Widget.__init__(self, parent)

class Bar(Widget):
    def __init__(self, parent):
        Widget.__init__(self, parent)

class Window(Widget):
    def __init__(self, parent=None):
        Widget.__init__(self, parent)
        self.foo = Foo(self)
        self.bar = Bar(None)

if __name__ == "__main__":

    app = QtGui.QApplication([__file__, '-widgetcount'])
    window = Window()
    window.show()
    app.exec_()

哪个输出:

__del__: <__main__.Window object at 0x88f514c>
destroyed: <__main__.Foo object at 0x88f5194>
__del__: <__main__.Bar object at 0x88f51dc>
Widgets left: 0    Max widgets: 4 

编辑

再想一想,似乎某些版本的PyQt4可能存在错误(或至少存在行为上的差异).

作为一种可能的解决方法,似乎为主窗口小部件创建两个python名称然后显式删除它们中的每一个可能有助于确保对象的C和python两个方面都被销毁.

如果以下行添加到上面的脚本:

tmp = window; del tmp, window

然后输出变为:

__del__: <__main__.Window object at 0x8d3a14c>
__del__: <__main__.Foo object at 0x8d3a194>
__del__: <__main__.Bar object at 0x8d3a1dc>
Widgets left: 0    Max widgets: 4
点赞