I want to close all other windows opened by the main window when the main window is closed.
Please find below the min. code that I was testing:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget
import sys
class AnotherWindow(QWidget):
"""
This "window" is a QWidget. If it has no parent, it
will appear as a free-floating window as we want.
"""
def __init__(self):
super().__init__()
layout = QVBoxLayout()
self.label = QLabel("Another Window")
layout.addWidget(self.label)
self.setLayout(layout)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.button = QPushButton("Push for Window")
self.button.clicked.connect(self.show_new_window)
self.setCentralWidget(self.button)
def show_new_window(self, checked):
self.w = AnotherWindow()
self.w.show()
def close_another_window(self):
if self.w:
self.w.close()
app = QApplication(sys.argv)
w = MainWindow()
app.aboutToQuit.connect(w.close_another_window)
w.show()
app.exec()
As shown above I tried using the aboutToQuit option of the QApplication, but it only gets called when the another window also is closed.
I want to close the another window automaticaly when the mainwindow is closed.
Implement the closeEvent:
class MainWindow(QMainWindow):
w = None
# ...
def closeEvent(self, event):
if self.w:
self.w.close()
Note that you can also use QApplication.closeAllWindows() to close any top level window, even without having any direct reference, but if any of those windows ignores the closeEvent() the function will stop trying to close the remaining.
To avoid that, you can cycle all windows using QApplication.topLevelWidgets(); windows ignoring the closeEvent will still keep themselves open, but all the others will be closed:
def closeEvent(self, event):
for window in QApplication.topLevelWidgets():
window.close()
Note that the above may seem to apparently cause a recursion, since the "self" window is obviously part of the top level widgets.
Nonetheless, the close() slot of QWidget sets an internal variable, but it also checks if it's already been set before and eventually stops going further in the "close process": this prevents multiple close() calls to trigger more than one QCloseEvent if called within the same event handler, so it's safe to assume that window.close() won't call a further closeEvent() on the same window, whenever window is self.
In any case, if you really want to be sure, it won't be such a bad idea to change the above to:
def closeEvent(self, event):
for window in QApplication.topLevelWidgets():
if window != self:
window.close()