这里有几种方法可以实现这一点,使用我认为是惯用的 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_()
任何一个都可以。我更喜欢选项#2,因为它让父窗口对其子窗口保持一点不可知论,并在构建时简单地将正确的窗口连接到将清理它们的插槽。
选项 #3 的原因是基于您在下面的评论。在您发布的代码中,我的猜测是您的对话框并没有真正被删除。它仍然存在,只是被关闭了。所以应该触发关闭事件而不是破坏信号。因此,选项 3 将自定义信号放入 closeEvent 中,该信号准确地模拟了destroyed
信号在被删除时会做什么。