Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] QDialog::exec() makes QApplication::exec() to block for ever.
Qt 6.11 is out! See what's new in the release blog

[Solved] QDialog::exec() makes QApplication::exec() to block for ever.

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 8.7k Views 1 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.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    Hello QTers!

    I Have a simple problem with Qt. At the start of my application I create a QApplication object.
    Durring the application startup, in a particular case (but not always), before creating any windows and before calling QApplication::exec() I create QDialog, I call QDialog::exec() and then I exit the application. But just before I exit the application, I call QApplication::exec(). This will make my application to block and stay there forever. If I use the debugger I can see that it is blocked in file "qeventdispatcher_win.cpp" at the function: MsgWaitForMultipleObjectsEx(.....). Why is this happening? I know that I could remove the QApplication::exec() because after calling QDialog::exec(), I always want to quit the application. But isn't this a bad Qt practice? Why the blocking occurs? Any idea? Thanks a lot for your time!

    Cheers,
    Bekos

    1 Reply Last reply
    0
    • D Offline
      D Offline
      d2uriel
      wrote on last edited by
      #2

      The question is why do you pop up a QDialog before running your application? QApplication::exec() is starting an event loop and that's why it's blocking your app. If you don't have a normal GUI where user can do stuff then you probably don't need to run the exec() method of your QApplication object.

      "Do not judge, and you will never be mistaken." - Jean-Jacques Rousseau

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dbzhang800
        wrote on last edited by
        #3

        [quote author="Bekos" date="1335802143"] Why is this happening?

        Why the blocking occurs?
        [/quote]

        You should know that, QDialog::exec()/QMenu::exec()/QCoreApplication::exec()/... are used to start eventloop. A eventloop is an infinit loop.

        so, your code will looks like this:
        @
        while(1) //QDialog::exec()
        {
        //...
        }

        while(1) //QApplication::exec()
        {
        //...
        }
        @

        [quote author="Bekos" date="1335802143"] But isn't this a bad Qt practice?
        [/quote]

        Yes, it a bad Qt practice.

        You should use QDialog::show() or QDialog::open() instead of QDialog::exec() in most cases.

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          The QApplication event loop should be the first one to be started. For your use case, I would utilize a zero timeout, single shot timer:

          @
          QApplication a(argc, argv);

          MyDialog dlg;
          QTimer::singleShot(0, &dlg, SLOT(exec()));

          a.exec();
          @

          The timer fires only when the application event loop has started and calls exec() on your dialog.

          1 Reply Last reply
          0
          • D Offline
            D Offline
            dbzhang800
            wrote on last edited by
            #5

            Yes, more or less that will look like this,
            @
            while(1) //QApplication::exec()
            {
            //...
            //...
            while(1) //QDialog::exec()
            {
            //...
            }
            //...
            }
            @
            but seems
            "this is one of the patterns that can lead to unpredictable flow of logic"

            http://labs.qt.nokia.com/2010/02/23/unpredictable-exec/

            1 Reply Last reply
            0
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              Hello everyone,

              Thank you so much for your replies. I have a better understanding of how the QApplication::exec() works. But still, I do not understand is why when I close the dialog box (by clicking the ok/cancel button or the 'X' button) this will NOT block:

              @
              QDialog myDialog;
              myDialog.show();
              myQApplicationObject.exec();
              @

              While this will block at QApplication::exec():

              @
              QDialog myDialog;
              myDialog.exec();
              myQApplicationObject.exec();
              @

              By the way, the reason I use QDialog::exec() is because it returns the selection (OK/Canel) of the user.

              Thanks a lot!

              Cheers,
              Bekos

              1 Reply Last reply
              0
              • D Offline
                D Offline
                dbzhang800
                wrote on last edited by
                #7

                If your
                @
                myDialog
                @
                is your only Widget.

                When it's closed, your application will be marked as finished. so QApplication::exec() will exit ASAP.


                In addition, you can give a try to QDialog::open() , which is more prefer to QDialog::exec().

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  dbzhang800
                  wrote on last edited by
                  #8

                  [quote author="Bekos" date="1335887145"]Hello everyone,

                  By the way, the reason I use QDialog::exec() is because it returns the selection (OK/Canel) of the user.
                  [/quote]

                  You can get accepted() and rejected() too when you using QDialog::show() or QDialog::open().

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    d2uriel
                    wrote on last edited by
                    #9

                    [quote author="1+1=2" date="1335894356"]
                    [quote author="Bekos" date="1335887145"]Hello everyone,

                    By the way, the reason I use QDialog::exec() is because it returns the selection (OK/Canel) of the user.
                    [/quote]

                    You can get accepted() and rejected() too when you using QDialog::show() or QDialog::open().[/quote]
                    But for that you need to have an event loop stared within the QApplication object, right?

                    "Do not judge, and you will never be mistaken." - Jean-Jacques Rousseau

                    1 Reply Last reply
                    0
                    • ? Offline
                      ? Offline
                      A Former User
                      wrote on last edited by
                      #10

                      In both cases I close the dialog. But only the one using QDialog::show() will NOT block at QApplication::exec(). I read somewhere that this happens because my QDialog has no parent widget assigned.

                      [quote author="1+1=2" date="1335891728"]If your
                      @
                      myDialog
                      @
                      is your only Widget.

                      When it's closed, your application will be marked as finished. so QApplication::exec() will exit ASAP.
                      [/quote]

                      The reason I use exec() and not show() or open() is because the call is inside a loop like this:

                      @
                      bool keepLooping = true;
                      do
                      {
                      QDialog myDialog
                      int result = myDialog.exec();
                      if(result) {
                      if(something) keepLooping = false;
                      } else {
                      keepLooping = false;
                      }
                      } while(keepLooping);

                      myQApplication.exec();

                      // The application exits now
                      @

                      This will only work with QDialog::exec().
                      I guess the QApplication::exec() at the end of the code above is reduntant at this particular case because the application is going to quit anyway. To be honset I do not know why it is there at first place (it is a big project I am not the one who wrote this code). An alternative solution would be to add:

                      @
                      QTimer::singleShot(0, &myQApplication, SLOT(quit()));
                      @

                      ..before calling QApplication::exec();

                      Thanks a lot for your help guys!

                      Cheers,
                      Bekos

                      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
                      • Unsolved