如何在PyQT中检测父窗口小部件?

时间:2012-12-24 04:33:30

标签: python qt pyqt

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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

  1. 使用父项上的closeEvent直接对每个孩子执行清理。
  2. 使用父级的destroyed信号间接呼叫每个孩子的清理
  3. 从父母的closeEvent发出自定义信号,直接连接到孩子的清理工作。
  4. 选项#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信号在被删除时的确切行为。