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. QMessageBox::warning replacement that wont process the event loop
Forum Updated to NodeBB v4.3 + New Features

QMessageBox::warning replacement that wont process the event loop

Scheduled Pinned Locked Moved Unsolved General and Desktop
40 Posts 9 Posters 5.3k Views 4 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.
  • J.HilkJ J.Hilk

    @stefanwoe said in QMessageBox::warning replacement that wont process the event loop:

    w can this be used as a modal dialog? Any references?

    :D

    setWindowModality(Qt::ApplicationModal);

    https://doc.qt.io/qt-5/qmessagebox.html#setWindowModality

    S Offline
    S Offline
    stefanwoe
    wrote on last edited by
    #11

    @J-Hilk
    i tried this here (of course a incomplete test):

    QMessageBox msgBox(this);
    msgBox.setText("My message");
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.setDefaultButton(QMessageBox::Yes);
    msgBox.setWindowModality(Qt::ApplicationModal);
    msgBox.show();
    

    show() now of course will not wait until the dialog is closed etc. How can i accomplish this? It seems like the correct way, but so far i dont get it.

    J.HilkJ 1 Reply Last reply
    0
    • S stefanwoe

      @J-Hilk
      i tried this here (of course a incomplete test):

      QMessageBox msgBox(this);
      msgBox.setText("My message");
      msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
      msgBox.setDefaultButton(QMessageBox::Yes);
      msgBox.setWindowModality(Qt::ApplicationModal);
      msgBox.show();
      

      show() now of course will not wait until the dialog is closed etc. How can i accomplish this? It seems like the correct way, but so far i dont get it.

      J.HilkJ Online
      J.HilkJ Online
      J.Hilk
      Moderators
      wrote on last edited by
      #12

      @stefanwoe
      make msgBox persistent, for example as a class member, then it should at least show.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      S 1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        @stefanwoe
        make msgBox persistent, for example as a class member, then it should at least show.

        S Offline
        S Offline
        stefanwoe
        wrote on last edited by
        #13

        @J-Hilk It shows - but i how can do i add a loop or the like to process the dialog until a button is pressed?

        J.HilkJ 1 Reply Last reply
        0
        • S stefanwoe

          @J-Hilk It shows - but i how can do i add a loop or the like to process the dialog until a button is pressed?

          J.HilkJ Online
          J.HilkJ Online
          J.Hilk
          Moderators
          wrote on last edited by J.Hilk
          #14

          @stefanwoe you can't that's why I wrote:

          but, this will result in your having to refactor stuff, as the show() call does not "wait" inplace on the user input!

          your code/ function block will have to end on the show() call of your message box, and than you "continue" in a slot/function connected to one of its signals, for example
          https://doc.qt.io/qt-5/qdialog.html#finished


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          S 1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @stefanwoe you can't that's why I wrote:

            but, this will result in your having to refactor stuff, as the show() call does not "wait" inplace on the user input!

            your code/ function block will have to end on the show() call of your message box, and than you "continue" in a slot/function connected to one of its signals, for example
            https://doc.qt.io/qt-5/qdialog.html#finished

            S Offline
            S Offline
            stefanwoe
            wrote on last edited by
            #15

            @J-Hilk That i understand - but this will continue code execution after the msgBox.show() statement - as it wont block control flow. So the code after msgBox.show() will be executed while the dialog is shown. But what i want, is a replacement for QMessageBox::warning which blocks further execution while the dialog is shown.
            How can that be done?

            J.HilkJ JonBJ 2 Replies Last reply
            0
            • S stefanwoe

              @J-Hilk That i understand - but this will continue code execution after the msgBox.show() statement - as it wont block control flow. So the code after msgBox.show() will be executed while the dialog is shown. But what i want, is a replacement for QMessageBox::warning which blocks further execution while the dialog is shown.
              How can that be done?

              J.HilkJ Online
              J.HilkJ Online
              J.Hilk
              Moderators
              wrote on last edited by
              #16

              @stefanwoe said in QMessageBox::warning replacement that wont process the event loop:

              How can that be done?

              it can't not without calls to processEvents() or additional QEventLoops


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply
              1
              • M Offline
                M Offline
                mchinand
                wrote on last edited by
                #17
                This post is deleted!
                1 Reply Last reply
                0
                • S stefanwoe

                  @J-Hilk That i understand - but this will continue code execution after the msgBox.show() statement - as it wont block control flow. So the code after msgBox.show() will be executed while the dialog is shown. But what i want, is a replacement for QMessageBox::warning which blocks further execution while the dialog is shown.
                  How can that be done?

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

                  @stefanwoe
                  As @J-Hilk says.
                  And since your earlier traceback showed

                  ...
                  Qt6Cored.dll!QEventDispatcherWin32::processEvents({...}) Line 474	C++
                  Qt6Guid.dll!QWindowsGuiEventDispatcher::processEvents({...}) Line 72	C++
                  Qt6Cored.dll!QEventLoop::processEvents({...}) Line 140	C++
                  Qt6Cored.dll!QEventLoop::exec({...}) Line 232	C++
                  

                  it seems to me likely/possible that you will be in the same state as you were originally.....

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    stefanwoe
                    wrote on last edited by
                    #19

                    I now tried:

                    QMessageBox msgBox(this);
                    msgBox.setText("My message");
                    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
                    msgBox.setDefaultButton(QMessageBox::Yes);
                    msgBox.setWindowModality(Qt::ApplicationModal);
                    msgBox.show();
                    QEventLoop eventLoop(&msgBox);
                    eventLoop.exec(QEventLoop::DialogExec);
                    

                    Still the same problem.

                    Inspecting the call stack in the debugger i think the root problem lies in

                    Qt6Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(0x000001577107c8c0) 
                    Qt6Guid.dll!QWindowSystemInterface::sendWindowSystemEvents({...}) Line 1172	C++
                    Qt6Guid.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 81	C++
                    Qt6Cored.dll!QEventDispatcherWin32::processEvents({...}) Line 474	C++
                    Qt6Guid.dll!QWindowsGuiEventDispatcher::processEvents({...}) Line 72	C++
                    Qt6Cored.dll!QEventLoop::processEvents({...}) Line 140	C++
                    Qt6Cored.dll!QEventLoop::exec({...}) Line 232	C++
                    

                    I can not find any configurable way to - temporarily - skip this call chain, when using QEventLoop.

                    JonBJ 1 Reply Last reply
                    0
                    • S stefanwoe

                      I now tried:

                      QMessageBox msgBox(this);
                      msgBox.setText("My message");
                      msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
                      msgBox.setDefaultButton(QMessageBox::Yes);
                      msgBox.setWindowModality(Qt::ApplicationModal);
                      msgBox.show();
                      QEventLoop eventLoop(&msgBox);
                      eventLoop.exec(QEventLoop::DialogExec);
                      

                      Still the same problem.

                      Inspecting the call stack in the debugger i think the root problem lies in

                      Qt6Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(0x000001577107c8c0) 
                      Qt6Guid.dll!QWindowSystemInterface::sendWindowSystemEvents({...}) Line 1172	C++
                      Qt6Guid.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 81	C++
                      Qt6Cored.dll!QEventDispatcherWin32::processEvents({...}) Line 474	C++
                      Qt6Guid.dll!QWindowsGuiEventDispatcher::processEvents({...}) Line 72	C++
                      Qt6Cored.dll!QEventLoop::processEvents({...}) Line 140	C++
                      Qt6Cored.dll!QEventLoop::exec({...}) Line 232	C++
                      

                      I can not find any configurable way to - temporarily - skip this call chain, when using QEventLoop.

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

                      @stefanwoe
                      I don't think you can, that is my point. You need an event loop to deal with any dialog, and some event being processed is upsetting something in the system....
                      Really ISTM the original issue, whatever it is/causes it, ought be sorted out. Like a (reproducible) bug report. But that may take time for a resolution.....

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        stefanwoe
                        wrote on last edited by
                        #21

                        I found this SO discussion which states the same problem:
                        https://stackoverflow.com/questions/26502673/will-qmessagebox-block-the-running-of-the-whole-main-thread-in-qt

                        The solution here is:

                        This is why we have a policy in our company that forbids to use QMessageBox::question() (and similar) and to call exec() on dialogs in our applications. We are creating modal dialogs on the heap and use their signals instead.

                        Well - can anybody tell what that means? Would this work without a event loop?

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

                          Hi,

                          It just means that they impose a single event loop throughout the whole application lifetime.

                          Basically, you should refactor your logic so that you do not depend on the fact that the event loop is processing events.

                          Can you explain how you implement your logic ?

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

                          S 1 Reply Last reply
                          1
                          • SGaistS SGaist

                            Hi,

                            It just means that they impose a single event loop throughout the whole application lifetime.

                            Basically, you should refactor your logic so that you do not depend on the fact that the event loop is processing events.

                            Can you explain how you implement your logic ?

                            S Offline
                            S Offline
                            stefanwoe
                            wrote on last edited by stefanwoe
                            #23

                            @SGaist As noted before - the problem only arises sporadically in not so common situations. I can not "refactor my logic" thanks for that hint. As the SO post shows i am not the only one who has that problem. And problems with event recursion are a common problem id say.

                            S 1 Reply Last reply
                            0
                            • S stefanwoe

                              @SGaist As noted before - the problem only arises sporadically in not so common situations. I can not "refactor my logic" thanks for that hint. As the SO post shows i am not the only one who has that problem. And problems with event recursion are a common problem id say.

                              S Offline
                              S Offline
                              stefanwoe
                              wrote on last edited by
                              #24

                              @stefanwoe Let me give you a better example: A 3rd party Library we use throws a unexpected exception. We catch this exception and we want to display it (many users just send screenshots instead of logfiles). In some cases the library can not recover from the problem and/or it gets difficult to handle this before it ever had happened. In such a situation the dialog just should "Pause"/Halt the application and display appropriate information - but the application shall not execute any more. We may then i.e. create a Windows Dump file etc. for post mortem analysis before our program possibly will die.

                              JonBJ 1 Reply Last reply
                              0
                              • S stefanwoe

                                @stefanwoe Let me give you a better example: A 3rd party Library we use throws a unexpected exception. We catch this exception and we want to display it (many users just send screenshots instead of logfiles). In some cases the library can not recover from the problem and/or it gets difficult to handle this before it ever had happened. In such a situation the dialog just should "Pause"/Halt the application and display appropriate information - but the application shall not execute any more. We may then i.e. create a Windows Dump file etc. for post mortem analysis before our program possibly will die.

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

                                @stefanwoe
                                As I understand it. Whether you use exec(), which will create its own event loop, or show(), which will will leave the main event loop running, either way Qt will process new events. And I believe you are saying you want to forbid this while the message box is showing(?).

                                Since I see you are Windows, have you considered maybe using a modal native Windows messagebox, which I am hoping would block the Qt event loop while displayed, would that satisfy you requirement?

                                S 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @stefanwoe
                                  As I understand it. Whether you use exec(), which will create its own event loop, or show(), which will will leave the main event loop running, either way Qt will process new events. And I believe you are saying you want to forbid this while the message box is showing(?).

                                  Since I see you are Windows, have you considered maybe using a modal native Windows messagebox, which I am hoping would block the Qt event loop while displayed, would that satisfy you requirement?

                                  S Offline
                                  S Offline
                                  stefanwoe
                                  wrote on last edited by
                                  #26

                                  @JonB Yes, i consider writing a Native Dialog for Windows, and one for the Mac. But actually it would be fairly easy to add such a flag to i.e. exec() that forbids the current behavior.
                                  And i still wonder how the approach in the linked Stackoverflow (above) answer would work. this seems to solve the problem.

                                  JonBJ J.HilkJ 2 Replies Last reply
                                  0
                                  • S stefanwoe

                                    @JonB Yes, i consider writing a Native Dialog for Windows, and one for the Mac. But actually it would be fairly easy to add such a flag to i.e. exec() that forbids the current behavior.
                                    And i still wonder how the approach in the linked Stackoverflow (above) answer would work. this seems to solve the problem.

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

                                    @stefanwoe said in QMessageBox::warning replacement that wont process the event loop:

                                    And i still wonder how the approach in the linked Stackoverflow (above) answer would work. this seems to solve the problem.

                                    It does not seem to solve your issue at all to me. You want a message box to run without Qt processing an event loop and therefore dispatching other events. I say Qt does/can not do that. As @SGaist observed earlier:

                                    It just means that they impose a single event loop throughout the whole application lifetime.

                                    So they are just using the single main event loop even when the dialog is showing, instead of the dialog having its own event loop when you call exec(). I do not see any difference wrt your situation. That is my understanding.

                                    1 Reply Last reply
                                    0
                                    • S stefanwoe

                                      @JonB Yes, i consider writing a Native Dialog for Windows, and one for the Mac. But actually it would be fairly easy to add such a flag to i.e. exec() that forbids the current behavior.
                                      And i still wonder how the approach in the linked Stackoverflow (above) answer would work. this seems to solve the problem.

                                      J.HilkJ Online
                                      J.HilkJ Online
                                      J.Hilk
                                      Moderators
                                      wrote on last edited by
                                      #28

                                      @stefanwoe said in QMessageBox::warning replacement that wont process the event loop:

                                      And i still wonder how the approach in the linked Stackoverflow (above) answer would work. this seems to solve the problem.

                                      Just like I suggested on the previous page!

                                      In order to be able to click on any button or even to draw/show the dialog, the event loop has to be processed.

                                      That is either done by the main event loop or by one QMessagebox is spawning or by one you yourself create. BUT event processing will be happening, if you wan't a responsive UI-window.

                                      In your case you want only the main event loop to be spinning.


                                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                      Q: What's that?
                                      A: It's blue light.
                                      Q: What does it do?
                                      A: It turns blue.

                                      S JonBJ 2 Replies Last reply
                                      0
                                      • J.HilkJ J.Hilk

                                        @stefanwoe said in QMessageBox::warning replacement that wont process the event loop:

                                        And i still wonder how the approach in the linked Stackoverflow (above) answer would work. this seems to solve the problem.

                                        Just like I suggested on the previous page!

                                        In order to be able to click on any button or even to draw/show the dialog, the event loop has to be processed.

                                        That is either done by the main event loop or by one QMessagebox is spawning or by one you yourself create. BUT event processing will be happening, if you wan't a responsive UI-window.

                                        In your case you want only the main event loop to be spinning.

                                        S Offline
                                        S Offline
                                        stefanwoe
                                        wrote on last edited by
                                        #29

                                        In your case you want only the main event loop to be spinning.

                                        How could that be done? Is there a example?

                                        J.HilkJ 1 Reply Last reply
                                        0
                                        • S stefanwoe

                                          In your case you want only the main event loop to be spinning.

                                          How could that be done? Is there a example?

                                          J.HilkJ Online
                                          J.HilkJ Online
                                          J.Hilk
                                          Moderators
                                          wrote on last edited by J.Hilk
                                          #30

                                          @stefanwoe

                                          #ifndef SOMECLASS_H
                                          #define SOMECLASS_H
                                          
                                          #include <QWidget>
                                          #include <QMessageBox>
                                          
                                          
                                          class SomeClass : public QWidget
                                          {
                                              Q_OBJECT
                                          public:
                                              explicit SomeClass(QWidget *parent = nullptr);
                                          
                                              void oldBlocking();
                                          
                                              void newNonBlocking();
                                          signals:
                                          
                                          private slots:
                                              void continuationOfnewNonBlocking();
                                          
                                          private:
                                              bool someCondition() {return  rand() % 2;}
                                          
                                          private:
                                              QMessageBox m_messageBox;
                                              QMetaObject::Connection m_lastConnect;
                                          };
                                          
                                          #endif // SOMECLASS_H
                                          
                                          

                                          #include "someclass.h"
                                          
                                          #include <QDebug>
                                          
                                          SomeClass::SomeClass(QWidget *parent) : QWidget(parent)
                                          {
                                              m_messageBox.setWindowModality(Qt::ApplicationModal);
                                          }
                                          
                                          void SomeClass::oldBlocking()
                                          {
                                              if(!someCondition()) {
                                                  QMessageBox::information(this, "Bla", "blubb");
                                              }
                                              
                                              qDebug() << "Do stuff as normal";
                                          }
                                          
                                          void SomeClass::newNonBlocking()
                                          {
                                              if(!someCondition()) {
                                                  m_messageBox.setText("blubb");
                                                  m_lastConnect = connect(&m_messageBox, &QMessageBox::accepted, this, &SomeClass::continuationOfnewNonBlocking);
                                                  m_messageBox.show();
                                              } else {
                                                  continuationOfnewNonBlocking();
                                              }
                                          }
                                          
                                          void SomeClass::continuationOfnewNonBlocking()
                                          {
                                              QObject::disconnect(m_lastConnect);
                                              qDebug() << "Do stuff as normal";
                                          }
                                          
                                          

                                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                          Q: What's that?
                                          A: It's blue light.
                                          Q: What does it do?
                                          A: It turns blue.

                                          S 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