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. does not return from exec()
Forum Updated to NodeBB v4.3 + New Features

does not return from exec()

Scheduled Pinned Locked Moved Unsolved General and Desktop
27 Posts 5 Posters 2.8k Views 3 Watching
  • 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.
  • E explorer100

    why some dialogs remain visible even after program terminates?

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #15

    @explorer100 said in does not return from exec():

    why some dialogs remain visible even after program terminates?

    No dialog or window could remain visible if your program terminates. If you still see them that means your program has not terminated, even if you think it has. For example, just because your main window closes does not automatically mean your program has terminated. By default a Qt UI application closes when the last top-level window closes. If your windows all have that as an ancestor they will close too, and the application will exit. But if, say, you create a modeless, non-parented top-level window that will not close when the main window does, and the application will not close while that is still open.

    1 Reply Last reply
    1
    • E Offline
      E Offline
      explorer100
      wrote on last edited by
      #16

      "But if, say, you create a modeless, non-parented top-level window that will not close when the main window does, and the application will not close while that is still open."

      I think I have done exactly that. using:

      if name == "main":

      app = QApplication(sys.argv)
      window = MainWindow()
      window.show()
      sys.exit(app.exec())
      

      How else would you do it?

      JonBJ 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #17

        By default, the application should quit after the last top level window is closed.
        You can change that behaviour but it's an explicit thing you have to code.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • E explorer100

          "But if, say, you create a modeless, non-parented top-level window that will not close when the main window does, and the application will not close while that is still open."

          I think I have done exactly that. using:

          if name == "main":

          app = QApplication(sys.argv)
          window = MainWindow()
          window.show()
          sys.exit(app.exec())
          

          How else would you do it?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #18

          @explorer100
          If that code is all you have, and you do not change default quitOnLastWindowClosed to False, your application should fully exit when you close your window. Why don't you test just that program as it is with nothing else? But if you have been doing the sort of things you were talking about with other dialogs then it depends what you did with them.

          1 Reply Last reply
          0
          • E Offline
            E Offline
            explorer100
            wrote on last edited by explorer100
            #19

            The main window goes invisible, but the other dialogs who have main window as a parent but are non-modal. They stay visible. what I am doing is pressing the X on the top right of the window to test this. and as you said, the app does not actually close (I can see from the IDE that it did not actually close).

            JonBJ 1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #20

              Closing a window does not mean it gets destroyed immediately. You have multiple top level windows hence your application is still alive due to these other windows.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • E explorer100

                The main window goes invisible, but the other dialogs who have main window as a parent but are non-modal. They stay visible. what I am doing is pressing the X on the top right of the window to test this. and as you said, the app does not actually close (I can see from the IDE that it did not actually close).

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #21

                @explorer100 said in does not return from exec():

                . its the other dialogs who have main window as a parent but are non-modal.

                But you haven't shown what you do in the code you posted, there are no other dialogs. So we don't know what you do with them. If instead of calling exec() on them you call show() you may have to close them yourself explicitly, I can't recall. QDialog uses its parent parameter differently from other widgets/windows, per the docs for it.

                https://doc.qt.io/qt-6/qdialog.html#details

                A dialog window is a top-level window mostly used for short-term tasks and brief communications with the user. QDialogs may be modal or modeless.

                Note that QDialog (and any other widget that has type Qt::Dialog) uses the parent widget slightly differently from other classes in Qt. A dialog is always a top-level widget, but if it has a parent, its default location is centered on top of the parent's top-level widget (if it is not top-level itself). It will also share the parent's taskbar entry.

                So QDialogs are always top-level windows, regardless of parent, IIRC. In which case you would need to close any modeless dialogs you created before app.exec() will return. QDialog::exec() works because it waits for the dialog to be exited and then closes it; QDialog::open() does not wait or close, so the dialog stays around.

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  explorer100
                  wrote on last edited by explorer100
                  #22

                  OK. If I understand it correctly, modeless dialogs that are activated using show() stay around and need to be closed explicitly. But it seems they are holding the app from closing. Is there a way (a slot like approach) to catch the exit/reject from main window and do some cleanups? Like closing open dialogs? I am using dialogs almost as permanent fixtures that also talk to each other (and in some cases also open and close each other) while the application is running. It's just the nature of the application... Lots of decentralized displays that will be laid out on multiple large screens. Without dialogs, the application closes completely just fine. It is the dialogs that are holding it up.

                  JonBJ 1 Reply Last reply
                  0
                  • E explorer100

                    OK. If I understand it correctly, modeless dialogs that are activated using show() stay around and need to be closed explicitly. But it seems they are holding the app from closing. Is there a way (a slot like approach) to catch the exit/reject from main window and do some cleanups? Like closing open dialogs? I am using dialogs almost as permanent fixtures that also talk to each other (and in some cases also open and close each other) while the application is running. It's just the nature of the application... Lots of decentralized displays that will be laid out on multiple large screens. Without dialogs, the application closes completely just fine. It is the dialogs that are holding it up.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by JonB
                    #23

                    @explorer100
                    Having subclassed QMainWindow, you can override its virtual closeEvent() to detect the user is closing it.

                    From there you could close all open dialogs. You should presumably have a kept an array of the ones you opened as you opened them? https://doc.qt.io/qt-6/qtwidgets-tutorials-widgets-toplevel-example.html

                    If a widget is created without a parent, it is treated as a window, or top-level widget, when it is shown. Since it has no parent object to ensure that it is deleted when no longer needed, it is up to the developer to keep track of the top-level widgets in an application.

                    Or you can probably use QWindowList QGuiApplication::topLevelWindows() to look through and close them (perhaps checking if they are QDialogs, certainly don't try to close the MainWindow from within its own closeEvent()!).

                    Or from MainWindow::closeEvent() you might be able to call QApplication::exit() or quit() directly, instead of waiting for Qt to see that all top-level windows or closed. Though this one might be a bit "abrupt" (quit() might be better than exit()), maybe it's better to actually close your dialogs per the previous approaches.

                    1 Reply Last reply
                    1
                    • E Offline
                      E Offline
                      explorer100
                      wrote on last edited by explorer100
                      #24

                      Thank you so much for the information and suggestions. will try some of these approaches and report back on what worked best and why.

                      1 Reply Last reply
                      0
                      • E Offline
                        E Offline
                        explorer100
                        wrote on last edited by explorer100
                        #25

                        Apparently, another interesting way is to use:
                        app.aboutToQuit.connect(myExitHandler)
                        and do the closings in the myExitHandler routine

                        But overriding the closeEvent() seems to be the most straight forward method.

                        Thanks again for the advice!

                        JonBJ 1 Reply Last reply
                        0
                        • E explorer100

                          Apparently, another interesting way is to use:
                          app.aboutToQuit.connect(myExitHandler)
                          and do the closings in the myExitHandler routine

                          But overriding the closeEvent() seems to be the most straight forward method.

                          Thanks again for the advice!

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #26

                          @explorer100 said in does not return from exec():

                          app.aboutToQuit.connect(myExitHandler)

                          I don't think so for your case. That will only be called if Qt is "about to quit" your application. But your whole problem is that closing the main window will not cause quit of the application precisely because you have other top-level window/dialogs open. I don't think it will hit that for your case, until after you have closed all windows.

                          1 Reply Last reply
                          0
                          • E Offline
                            E Offline
                            explorer100
                            wrote on last edited by explorer100
                            #27

                            you are absolutely right! just tried it and it didn't work as I thought it would.
                            the closeEvent() override works very nicely!

                            The quit() override seems to work very well in closing all dialogs and the application without needing to loop through open dialogs.

                            Thanks again for the advice!

                            1 Reply Last reply
                            0

                            • Login

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