5

我创建了一个QVBoxLayout包含多个其他小部件的。当QVBoxLayout(当前为 a QDialog)的父窗口关闭时,我需要通知所有小部件关闭事件,以便它们可以删除临时文件。这是惯用的,我该怎么做?

在我的应用程序中,我QLabel使用一个类进行子类化,该类允许我存储对构成它的 pixMap 的临时文件的引用。当它的父窗口关闭时,我需要能够关闭文件。

编辑:我已经尝试过处理关闭事件:

def closeEvent(self, event):
    self.imgFile.close()
4

1 回答 1

3

这里有几种方法可以实现这一点,使用我认为是惯用的 Qt。

  1. 使用closeEvent父级直接对每个子级执行清理。
  2. 使用destroyed父级上的信号间接调用每个子级上的清理
  3. 从父节点发出自定义信号closeEvent,直接连接到子节点的清理。

选项 #2/#3 在下面被注释掉:

from PyQt4 import QtCore, QtGui


class MainWidget(QtGui.QDialog):

    # Option #3 - Custom signal
    closing = QtCore.pyqtSignal()

    def __init__(self):
        super(MainWidget, self).__init__()

        self.layout = QtGui.QVBoxLayout(self)

        for i in xrange(5):
            label = ResourceLabel('label%02d' % i)
            self.layout.addWidget(label)

            # option #2
            # Let a signal trigger the cleanup on the children
            # self.destroyed.connect(label.close)

            # option #3
            # Use a custom signal emitted from the closeEvent,
            # wired directly to the cleanup slot on the object
            # self.closing.connect(label.close)

    def closeEvent(self, event):
        print "Closing main window"

        # option #1
        # if you want to trigger a cleanup specifically when
        # this widget is closed, as opposed to destroyed
        for i in xrange(self.layout.count()):
            item = self.layout.itemAt(i)
            widget = item.widget()       
            if widget:
                try:
                    widget.close()
                except:
                    pass

        # Or Option #3 - emit a custom signal
        self.closing.emit()

        super(MainWidget, self).closeEvent(event)


class ResourceLabel(QtGui.QLabel):

    def __init__(self, *args, **kwargs):
        super(ResourceLabel, self).__init__(*args, **kwargs)
        self.aResource = "FOO"

    def close(self):
        print "Cleaning up", self
        self.aResource = None


if __name__ == "__main__":
    app = QtGui.QApplication([])
    win = MainWidget()
    win.show()
    win.raise_()
    app.exec_()

任何一个都可以。我更喜欢选项#2,因为它让父窗口对其子窗口保持一点不可知论,并在构建时简单地将正确的窗口连接到将清理它们的插槽。

选项 #3 的原因是基于您在下面的评论。在您发布的代码中,我的猜测是您的对话框并没有真正被删除。它仍然存在,只是被关闭了。所以应该触发关闭事件而不是破坏信号。因此,选项 3 将自定义信号放入 closeEvent 中,该信号准确地模拟了destroyed信号在被删除时会做什么。

于 2012-12-24T05:16:00.077 回答