我创建了一个QVBoxLayout包含多个其他小部件的。QVBoxLayout当(当前是 a )的父窗口QDialog关闭时,我需要向所有小部件通知关闭事件,以便它们可以删除临时文件。这是惯用的吗?我该怎么做?
在我的应用程序中,我使用QLabel一个类进行子类化,该类允许我存储对构成 pixMap 的临时文件的引用。当它的父窗口关闭时,我需要能够关闭该文件。
编辑:我已经尝试处理关闭事件:
def closeEvent(self, event):
self.imgFile.close()
Run Code Online (Sandbox Code Playgroud)
这里有几种方法可以实现这一点,使用我认为惯用的 Qt。
closeEvent直接对每个子级执行清理。destroyed父级上的信号间接调用每个子级上的清理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_()
Run Code Online (Sandbox Code Playgroud)
任何一个都会起作用。我更喜欢选项#2,因为它让父窗口对其子窗口保持一点不可知性,并且只需在构建时将正确的窗口连接到将清理它们的插槽。
选择#3 的原因是基于您下面的评论。在您发布的代码中,我的猜测是您的对话框根本没有真正被删除。它仍然存在并且刚刚被关闭。因此应该触发 close 事件而不是销毁信号。因此,选项 3 将一个自定义信号放入 closeEvent 中,该信号完全模仿destroyed信号被删除时会执行的操作。