Handling Close Event in PyQt5 with QStackedWidget
-
Hello everyone,
I'm currently working on a PyQt5 project and encountered a challenge with handling the close event. I'm a beginner in PyQt5 and have successfully used the
closeEvent
method in a simple application to remind users to save their modifications when clicking the X button in the upper right corner. Here's a simplified example:class MainWindow(QWidget): def __init__(self): super().__init__() def closeEvent(self, event): print("close!") if __name__ == "__main__": app = QApplication(sys.argv) demo = MainWindow() demo.show() sys.exit(app.exec_())
Now, I'm extending my project with two widgets using a
QStackedWidget
to switch between them:MAINWINDOW_INDEX = 1 LOGINWINDOW_INDEX = 0 class MainWindow(QWidget): def __init__(self, widget): super().__init__() self.widget = widget def closeEvent(self, event): print("close!") class LoginWindow(QWidget): def __init__(self, widget): super().__init__() button = QPushButton("goto main window", self) button.clicked.connect(self.onNewButtonClicked) self.widget = widget def onNewButtonClicked(self): mainwindow = MainWindow(self.widget) self.widget.addWidget(mainwindow) self.widget.setCurrentIndex(MAINWINDOW_INDEX) def closeEvent(self, event): print("close!") if __name__ == "__main__": app = QApplication(sys.argv) widget = QStackedWidget() loginwindow = LoginWindow(widget) widget.addWidget(loginwindow) widget.setFixedHeight(600) widget.setFixedWidth(450) widget.show() sys.exit(app.exec_())
However, after this modification, the
closeEvent
in both functions is not being called when clicking on the X in the upper right corner. I suspect this may be due to thecloseEvent
that I need to override being in myQStackedWidget
. How can I resolve this issue and ensure that the user is prompted to save their modifications when exiting the application? All of the data that needs to be saved is inmainwindow
.I appreciate any guidance or solutions you can provide. Thanks in advance!
-
@codingIsSoHard said in Handling Close Event in PyQt5 with QStackedWidget:
All of the data that needs to be saved is in mainwindow
Then it should be enough to handle closeEvent in mainWindow, why do you need close events in other widgets?
-
@codingIsSoHard said in Handling Close Event in PyQt5 with QStackedWidget:
However, after this modification, the closeEvent in both functions is not being called when clicking on the X in the upper right corner. I suspect this may be due to the closeEvent that I need to override being in my QStackedWidget
It does indeed appear that once you have a
QStackedWidget
it receives anycloseEvent()
(from the window's X close box), and that is not delivered to any widgets on the stack (when current/open or not). You can verify by subclassingQStackedWidget
:class MyStackedWidget(QStackedWidget): def closeEvent(self, event): print("close MyStackedWidget!")
So do the subclass and, perhaps, have it go through all child widgets/windows calling
close()
on themclass MyStackedWidget(QStackedWidget): def closeEvent(self, event): print("close MyStackedWidget!") for i in range(self.count()): widget = self.widget(i) if widget: widget.close()
Or at least on any
MainWindow
instance (type(widget) is MainWindow
orisinstance(widget, MainWindow)
) if not all.P.S.
Additionally, you might not choose to use anyQStackedWidget
for this use case of swapping between a logon window and a main window. Especially if this is a "once-only" operation, i.e. you do not allow the user to "log off" and then be re-presented with the logon page. You might just have them as separate, unconnected windows with show/hide/open/close instead. (In that case, be careful toshow()
the new window before youhide()
/close()
the existing one, else by default Qt will close your application when the first and only visible window gets closed, before the other one gets opened.) -
-
@JonB
Thank you for your response. Everything appears to be functioning correctly after making the code modifications based on your suggestions. Also, thank you for your comments; I will reconsider whether it's possible to modify my program structure without using QStackedWidget. Wishing you a wonderful day!