В PyQt, в зависимости от того, как вы конфигурируете объект, вашим свойством может управлять C ++ или Python.В случае объекта QObject, такого как QMainWindow, если передается родительский объект, обработка памяти выполняется на C ++, и правило Qt указывает, что дочерний элемент умирает, только если родительский элемент умирает или дочерний элемент явно удаляется с помощью deleteLater.Итак, второй жизненный цикл зависит от первого, то есть даже когда вы закрываете окно, объект не удаляется.Чтобы окно было удалено при закрытии окна, вы должны активировать атрибут Qt :: WA_DeleteOnClose , поэтому решение состоит в том, чтобы добавить его во Второй класс:
class Second(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Second, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose) # <---
Если вы собираетесь использовать контейнер для сохранения ссылки на объекты, у вас могут возникнуть проблемы, потому что, когда C ++ удаляет объект, он не уведомляет контейнер.Таким образом, есть следующие варианты, чтобы избежать этих проблем:
- Не используйте контейнер.
- Используйте weakref.ref () , чтобы, когда объектудалено, оно также удаляется из контейнера:
def on_pushButton_clicked(self):
dialog = Second(self)
self.dialogs.append(weakref.ref(dialog, self.dialogs.remove))
dialog.show()
- Используйте уничтоженный сигнал для удаления объектов из контейнера:
import sip
# ...
class First(QtWidgets.QMainWindow):
# ...
def on_pushButton_clicked(self):
dialog = Second(self)
dialog.destroyed.connect(self.on_destroyed)
self.dialogs.append(dialog)
dialog.show()
@QtCore.pyqtSlot('QObject*')
def on_destroyed(self, obj):
self.dialogs = [dialog for dialog in self.dialogs if not sip.isdeleted(dialog)]