小部件的“销毁”信号未被触发(PyQT)

2024-04-29 08:16:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个小部件,它将不得不做一些手工清理后,它被销毁(停止一些线程)。然而,由于某种原因,小部件的“破坏”信号没有触发。我举了一个小例子来说明这个问题。

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)

我想它会印上“你好,世界!”当主窗口关闭时。不过,它什么也没印。


Tags: importselfappinit部件defsyswindow
2条回答

经过几次尝试,我发现如果在类之外声明doSomeDestruction,它就可以工作 但我不知道为什么。this答案中所写,这是因为At the point destroyed() is emitted, the widget isn't a QWidget anymore, just a QObject (as destroyed() is emitted from ~QObject)
这意味着当您的函数被调用时,如果您在类中编写它,它已经被删除。(也可以查看qt兴趣邮件列表中的hereOk , 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. ret = app.exec_()之后添加一个简单的del window
  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)
    

python类实例(或者至少pyqt<;->;qt链接)在发出destroyed时不存在。您可以通过使类上的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']

相关问题 更多 >