10

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

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)

我希望它打印“Hello World!” 当主窗口关闭时。但是,它不打印任何内容。

4

2 回答 2

10

经过几次尝试后,我发现如果您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 window之后添加一个简单的ret = app.exec_().
  2. WA_DeleteOnClose在主窗口(不是小部件)中设置属性:
    在程序顶部:

    from PyQt4 import QtCore
    

    改变的__init__功能:

    class MyWindow(QtGui.QMainWindow):
        def __init__(self):
            super(MyWindow, self).__init__()
            self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
            self.widget = MyWidget(self)
    
于 2013-05-30T18:08:59.663 回答
3

destroyed发出时,python 类实例(或至少 pyqt<->qt 链接)不存在。destroyed您可以通过在类上设置处理程序来解决此staticmethod问题。这样,当destroyed信号发出时,python 方法仍然存在。

class MyWidget(QWidget):

    def __init__(self, parent):
        super(MyWidget, self).__init__(parent)
        self.destroyed.connect(MyWidget._on_destroyed)

    @staticmethod
    def _on_destroyed():
        # Do stuff here
        pass

如果您需要特定于您可以使用的类实例的信息以及将该信息传递给销毁方法functools.partial的实例。__dict__

from functools import partial

class MyWidget(QWidget):

    def __init__(self, parent, arg1, arg2):
        super(MyWidget, self).__init__(parent)
        self.arg1 = arg1
        self.arg2 = arg2
        self.destroyed.connect(partial(MyWidget._on_destroyed, self.__dict__))

    @staticmethod
    def _on_destroyed(d):
        print d['arg1']
于 2016-02-09T23:45:06.397 回答