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. Show a QMessage box from the context of a function defined outside mainwindow.cpp
Qt 6.11 is out! See what's new in the release blog

Show a QMessage box from the context of a function defined outside mainwindow.cpp

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 8 Posters 1.4k 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.
  • Christian EhrlicherC Offline
    Christian EhrlicherC Offline
    Christian Ehrlicher
    Lifetime Qt Champion
    wrote last edited by
    #6

    One problem with a simple callback will arise when you run the solver in a different thread. Then you have to add a context switch eg. with a QTimer single shot or a signal to switch to the main thread.

    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
    Visit the Qt Academy at https://academy.qt.io/catalog

    SGaistS 1 Reply Last reply
    0
    • Christian EhrlicherC Christian Ehrlicher

      One problem with a simple callback will arise when you run the solver in a different thread. Then you have to add a context switch eg. with a QTimer single shot or a signal to switch to the main thread.

      SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote last edited by
      #7

      @Christian-Ehrlicher said in Show a QMessage box from the context of a function defined outside mainwindow.cpp:

      One problem with a simple callback will arise when you run the solver in a different thread. Then you have to add a context switch eg. with a QTimer single shot or a signal to switch to the main thread.

      Beside the suggestion of @Christian-Ehrlicher, one can also make use of invokeMethod so everything GUI can properly stay in the place of concern rather than having unrelated code handling GUI related stuff.

      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

        @Christian-Ehrlicher said in Show a QMessage box from the context of a function defined outside mainwindow.cpp:

        One problem with a simple callback will arise when you run the solver in a different thread. Then you have to add a context switch eg. with a QTimer single shot or a signal to switch to the main thread.

        Beside the suggestion of @Christian-Ehrlicher, one can also make use of invokeMethod so everything GUI can properly stay in the place of concern rather than having unrelated code handling GUI related stuff.

        S Offline
        S Offline
        SimonSchroeder
        wrote last edited by
        #8

        @SGaist Yes, invokeMethod() is also my general solution if I'm multithreaded. As a second option, the callback could emit a signal and the connected slot can show the dialog in the GUI thread because signal/slot connections properly cross thread boundaries (it'll be automatically a queued connection). Sure, you could emit a signal directly from the solver (as has been suggested before). But a callback would allow you to not have anything Qt-related in your solver.

        SGaistS 1 Reply Last reply
        0
        • S SimonSchroeder

          @SGaist Yes, invokeMethod() is also my general solution if I'm multithreaded. As a second option, the callback could emit a signal and the connected slot can show the dialog in the GUI thread because signal/slot connections properly cross thread boundaries (it'll be automatically a queued connection). Sure, you could emit a signal directly from the solver (as has been suggested before). But a callback would allow you to not have anything Qt-related in your solver.

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote last edited by
          #9

          @SimonSchroeder I wasn't clear but I was thinking about using invokeMethod from the callback so indeed, the solver can be independent from Qt.

          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
          0
          • JonBJ Offline
            JonBJ Offline
            JonB
            wrote last edited by
            #10

            Never used invokeMethod(). Is it synchronous or asynchronous?

            jsulmJ S 2 Replies Last reply
            0
            • JonBJ JonB

              Never used invokeMethod(). Is it synchronous or asynchronous?

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote last edited by
              #11

              @JonB Depends how you call it, see https://doc.qt.io/archives/qt-5.15/qmetaobject.html#invokeMethod

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

              1 Reply Last reply
              0
              • JonBJ JonB

                Never used invokeMethod(). Is it synchronous or asynchronous?

                S Offline
                S Offline
                SimonSchroeder
                wrote last edited by
                #12

                @JonB said in Show a QMessage box from the context of a function defined outside mainwindow.cpp:

                Never used invokeMethod(). Is it synchronous or asynchronous?

                invokeMethod() basically lets you post calls to slots in the event queue. That's at least how I am using it. I makes it easier to not have a bunch of signals just so you connect them and call them once.

                JonBJ 1 Reply Last reply
                0
                • JKSHJ JKSH forked this topic
                • JonBJ JonB

                  @lukester88
                  You can use quite a number of ways. @JoeCFD's suggestion of a socket is fine, though I don't know why he has recommended that in particular. I would say the canonical Qt way is just to emit a signal. You place a slot on that somewhere in the UI to display a message box for that. Unlike a socket which I believe would require the UI to connect the other end of the socket, signal does not demand other end has a slot. And is possibly a bit less code.

                  Whether you use socket, signal or similar, your solver module may not need knowledge of UI code but will still need to include Qt headers to call it. If you want to avoid that, to keep your solver non-Qt-aware, you can use a function pointer or class with virtual method to do the socketing/signalling from the solver side. Since there are static methods of QMessageBox (https://doc.qt.io/qt-6/qmessagebox.html#static-public-members) which display a dialog and do not demand any knowledge of the UI if you go for application modal you can even use one of those in the function to display it directly without sockets/signals etc. if you want the simplest, dirty solution. Or even Qt's logging/qInstallMessageHandler(QtMessageHandler handler) where you could cause your qDebug() or similar calls to be shown to the user in a message box. So many ways! :)

                  JoeCFDJ Offline
                  JoeCFDJ Offline
                  JoeCFD
                  wrote last edited by
                  #13
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • L lukester88

                    Thank you for the reply! Do you happen to have a brief example of how this would be accomplished?

                    JoeCFDJ Offline
                    JoeCFDJ Offline
                    JoeCFD
                    wrote last edited by JoeCFD
                    #14

                    @lukester88 sorry I thought you are running two different processes.

                    1 Reply Last reply
                    0
                    • L lukester88

                      Hello,

                      I am working on a QT project that solves some equations iteratively, based on user input parameters in the GUI. I have 5 separate equations which require an iterative solution, and the equations are called using void equationName(); The way I have the ui set up right now is the user presses a button, and the 5 functions are run to iteratively solve the equations. The solution may not be reached within the specified number of iterations, so I want the program to show an error or warning message box to inform the user that the function was not able to converge on a solution. The challenge is, these functions are NOT defined in the mainwindow.cpp file, they are defined externally. A major theme I have in my code is keeping UI code and solver code completely separate, and I would like to continue that trend with this specific task.

                      My question is - how can I make these functions show a message box to the user when the function is executed? For example, when the user presses the button, and the function executes, if it exceeds the maximum number of iterations, the function should finish executing, and then a message box should show up warning the user that the function failed to converge. Furthermore, how can I implement such a thing without using UI code in the file with the solver source code?

                      Below I have included an example of one of the iterative solvers I am referring to. The thermo and kinetic things are structs that contain a list of associated variables, and the variables are updated through the iterative solver.

                      void iterativeSolver_T1_fromMachNumber() {

                      double maxIterations = 100;
                      double maxTolerance = 1e-4;
                      
                      double T01 = thermo.T01;
                      double Mc1_abs = kinetic.Mc1_abs;
                      
                      double T1_guess = thermo.T01;
                      double T1_new;
                      double gamma1;
                      
                      for (int i = 0; i < maxIterations; i++) {
                      
                          // Use the T1 guess to recalculate T1 and check for convergence
                          gamma1 = gammaData.linterp(T1_guess);
                      
                          double pow1 = std::pow(Mc1_abs, 2);
                          double powArg = 1 + (gamma1 - 1) / 2 * pow1;
                          double pow2 = std::pow(powArg, -1);
                      
                          T1_new = T01 * pow2;
                          thermo.T1 = T1_new;
                      
                          if (std::abs(T1_new - T1_guess) < maxTolerance) {
                              break;
                          }
                      
                          T1_guess = T1_new;
                      
                          if (i == maxIterations) {
                              qDebug() << "Solver did not converge within specified iterations.";
                              break;
                          }
                      }
                      

                      }

                      JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote last edited by JKSH
                      #15

                      @lukester88 said in Show a QMessage box from the context of a function defined outside mainwindow.cpp:

                      A major theme I have in my code is keeping UI code and solver code completely separate, and I would like to continue that trend with this specific task.

                      My question is - how can I make these functions show a message box to the user when the function is executed? For example, when the user presses the button, and the function executes, if it exceeds the maximum number of iterations, the function should finish executing, and then a message box should show up warning the user that the function failed to converge. Furthermore, how can I implement such a thing without using UI code in the file with the solver source code?

                      Make your solver return information about whether it converged on an answer or not:

                      struct SolverResult {
                          double finalValue;
                          bool converged;
                      };
                      

                      Then, do extra checks when processing the result.

                      If your result-processing code currently looks like this...

                      void MainWindow::onSolverFinished(double finalValue)
                      {
                          this->doSomethingWith(finalValue);
                      }
                      

                      ...now you can do extra checks:

                      void MainWindow::onSolverFinished(const SolverResult &result)
                      {
                          if (result.converged)
                          {
                              // Yay, we found a solution!
                              this->doSomethingWith(result.finalValue);
                          }
                          else
                          {
                              QMessageBox::warning(this,
                                  "No solution found", 
                                  QStringLiteral("Failed to converge on a solution within %1 iterations").arg(m_maxIterations)
                              );
                          }
                      }
                      

                      Alternatively, you could adopt a convention like "Return NaN if it fails to converge", and show the QMessageBox inside if (qIsNan(finalValue))

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      1 Reply Last reply
                      1
                      • L Offline
                        L Offline
                        lukester88
                        wrote last edited by
                        #16

                        Thank you everyone for your answers to this, I ended up going with the callback function logic as it made the most sense for my implementation. The solvers contain their own packet of information about convergence, and then deliver that packet of information to a separate function that parses it into an error message and passes it to the mainwindow for display

                        1 Reply Last reply
                        0
                        • L lukester88 has marked this topic as solved

                        • Login

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