Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Handling Close Event in PyQt5 with QStackedWidget
Servers for Qt installer are currently down

Handling Close Event in PyQt5 with QStackedWidget

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 2.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    codingIsSoHard
    wrote on 23 Nov 2023, 03:26 last edited by
    #1

    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 the closeEvent that I need to override being in my QStackedWidget. 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 in mainwindow.

    I appreciate any guidance or solutions you can provide. Thanks in advance!

    J J 2 Replies Last reply 23 Nov 2023, 07:29
    0
    • C codingIsSoHard
      23 Nov 2023, 03:26

      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 the closeEvent that I need to override being in my QStackedWidget. 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 in mainwindow.

      I appreciate any guidance or solutions you can provide. Thanks in advance!

      J Online
      J Online
      jsulm
      Lifetime Qt Champion
      wrote on 23 Nov 2023, 07:29 last edited by
      #2

      @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?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      C 1 Reply Last reply 23 Nov 2023, 13:26
      1
      • C codingIsSoHard
        23 Nov 2023, 03:26

        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 the closeEvent that I need to override being in my QStackedWidget. 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 in mainwindow.

        I appreciate any guidance or solutions you can provide. Thanks in advance!

        J Offline
        J Offline
        JonB
        wrote on 23 Nov 2023, 09:20 last edited by JonB
        #3

        @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 any closeEvent() (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 subclassing QStackedWidget:

        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 them

        class 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 or isinstance(widget, MainWindow)) if not all.

        P.S.
        Additionally, you might not choose to use any QStackedWidget 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 to show() the new window before you hide()/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.)

        C 1 Reply Last reply 23 Nov 2023, 13:41
        1
        • J jsulm
          23 Nov 2023, 07:29

          @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?

          C Offline
          C Offline
          codingIsSoHard
          wrote on 23 Nov 2023, 13:26 last edited by
          #4

          @jsulm You are correct; only the mainWindow needs to be saved. I was just testing whether a closeEvent would be called at all. I apologize for any confusion.

          1 Reply Last reply
          0
          • C codingIsSoHard has marked this topic as solved on 23 Nov 2023, 13:34
          • J JonB
            23 Nov 2023, 09:20

            @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 any closeEvent() (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 subclassing QStackedWidget:

            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 them

            class 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 or isinstance(widget, MainWindow)) if not all.

            P.S.
            Additionally, you might not choose to use any QStackedWidget 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 to show() the new window before you hide()/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.)

            C Offline
            C Offline
            codingIsSoHard
            wrote on 23 Nov 2023, 13:41 last edited by
            #5

            @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!

            1 Reply Last reply
            0

            1/5

            23 Nov 2023, 03:26

            • Login

            • Login or register to search.
            1 out of 5
            • First post
              1/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved