Widget的"被破坏"信号未被触发(PyQT)

Sci*_*llo 7 python pyqt pyqt4 python-3.x

我有一个小部件,它必须在它被销毁后做一些手动清理(停止一些线程).但是由于某种原因,小部件的"被破坏"信号没有被触发.我已经做了一个小例子来演示这个问题.

import sys
from PyQt4 import QtGui

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

        def doSomeDestruction():
            print('Hello World!')

        self.destroyed.connect(doSomeDestruction)


class MyWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()

        self.widget = MyWidget(self)

app = QtGui.QApplication(sys.argv)
window = MyWindow()
window.show()
ret = app.exec_()
sys.exit(ret)
Run Code Online (Sandbox Code Playgroud)

我希望它能打印出"Hello World!" 当主窗口关闭时.但是,它不会打印任何内容.

Tob*_*arg 7

经过几次尝试后,我发现如果你在doSomeDestruction课外宣布它是有效的.(见底部)
但我不知道为什么.正如在这个答案中写的,这是因为At the point destroyed() is emitted, the widget isn't a QWidget anymore, just a QObject (as destroyed() is emitted from ~QObject).
这意味着当您的函数被调用时,如果您在类中编写它,它已被删除.(也期待在这里的QT-interest邮件列表:Ok , I am sorry for stupid question. The signal is emitted, but the slot is not called for the obvious reason, that is because object is already deleted. )

编辑:我发现了两种让它真正起作用的方法:

  1. 添加一个简单的del windowret = app.exec_().
  2. WA_DeleteOnClose在主窗口(而不是小部件)中设置属性:
    在程序的顶部:

    from PyQt4 import QtCore
    
    Run Code Online (Sandbox Code Playgroud)

    改变的__init__功能:

    class MyWindow(QtGui.QMainWindow):
        def __init__(self):
            super(MyWindow, self).__init__()
            self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
            self.widget = MyWidget(self)
    
    Run Code Online (Sandbox Code Playgroud)