<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Show a QMessage box from the context of a function defined outside mainwindow.cpp]]></title><description><![CDATA[<p dir="auto">Hello,</p>
<p dir="auto">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.</p>
<p dir="auto">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?</p>
<p dir="auto">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.</p>
<p dir="auto">void iterativeSolver_T1_fromMachNumber() {</p>
<pre><code>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 &lt; 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) &lt; maxTolerance) {
        break;
    }

    T1_guess = T1_new;

    if (i == maxIterations) {
        qDebug() &lt;&lt; "Solver did not converge within specified iterations.";
        break;
    }
}
</code></pre>
<p dir="auto">}</p>
]]></description><link>https://forum.qt.io/topic/164879/show-a-qmessage-box-from-the-context-of-a-function-defined-outside-mainwindow.cpp</link><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 17:11:52 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/164879.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 12 Jul 2026 19:16:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Sat, 25 Jul 2026 01:09:11 GMT]]></title><description><![CDATA[<p dir="auto">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</p>
]]></description><link>https://forum.qt.io/post/839368</link><guid isPermaLink="true">https://forum.qt.io/post/839368</guid><dc:creator><![CDATA[lukester88]]></dc:creator><pubDate>Sat, 25 Jul 2026 01:09:11 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Sun, 19 Jul 2026 00:09:12 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/lukester88">@<bdi>lukester88</bdi></a> said in <a href="/post/839121">Show a QMessage box from the context of a function defined outside mainwindow.cpp</a>:</p>
<blockquote>
<p dir="auto">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.</p>
<p dir="auto">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?</p>
</blockquote>
<p dir="auto">Make your solver return information about whether it converged on an answer or not:</p>
<pre><code>struct SolverResult {
    double finalValue;
    bool converged;
};
</code></pre>
<p dir="auto">Then, do extra checks when processing the result.</p>
<p dir="auto">If your result-processing code currently looks like this...</p>
<pre><code>void MainWindow::onSolverFinished(double finalValue)
{
    this-&gt;doSomethingWith(finalValue);
}
</code></pre>
<p dir="auto">...now you can do extra checks:</p>
<pre><code>void MainWindow::onSolverFinished(const SolverResult &amp;result)
{
    if (result.converged)
    {
        // Yay, we found a solution!
        this-&gt;doSomethingWith(result.finalValue);
    }
    else
    {
        QMessageBox::warning(this,
            "No solution found", 
            QStringLiteral("Failed to converge on a solution within %1 iterations").arg(m_maxIterations)
        );
    }
}
</code></pre>
<p dir="auto">Alternatively, you could adopt a convention like "Return NaN if it fails to converge", and show the QMessageBox inside <code>if (qIsNan(finalValue))</code></p>
]]></description><link>https://forum.qt.io/post/839218</link><guid isPermaLink="true">https://forum.qt.io/post/839218</guid><dc:creator><![CDATA[JKSH]]></dc:creator><pubDate>Sun, 19 Jul 2026 00:09:12 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Sat, 18 Jul 2026 17:40:46 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/lukester88">@<bdi>lukester88</bdi></a> sorry I thought you are running two different processes.</p>
]]></description><link>https://forum.qt.io/post/839213</link><guid isPermaLink="true">https://forum.qt.io/post/839213</guid><dc:creator><![CDATA[JoeCFD]]></dc:creator><pubDate>Sat, 18 Jul 2026 17:40:46 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Fri, 17 Jul 2026 06:40:46 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a> said in <a href="/post/839187">Show a QMessage box from the context of a function defined outside mainwindow.cpp</a>:</p>
<blockquote>
<p dir="auto">Never used invokeMethod(). Is it synchronous or asynchronous?</p>
</blockquote>
<p dir="auto"><code>invokeMethod()</code> 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.</p>
]]></description><link>https://forum.qt.io/post/839194</link><guid isPermaLink="true">https://forum.qt.io/post/839194</guid><dc:creator><![CDATA[SimonSchroeder]]></dc:creator><pubDate>Fri, 17 Jul 2026 06:40:46 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Fri, 17 Jul 2026 05:22:17 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a> Depends how you call it, see <a href="https://doc.qt.io/archives/qt-5.15/qmetaobject.html#invokeMethod" target="_blank" rel="noopener noreferrer nofollow ugc">https://doc.qt.io/archives/qt-5.15/qmetaobject.html#invokeMethod</a></p>
]]></description><link>https://forum.qt.io/post/839191</link><guid isPermaLink="true">https://forum.qt.io/post/839191</guid><dc:creator><![CDATA[jsulm]]></dc:creator><pubDate>Fri, 17 Jul 2026 05:22:17 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Thu, 16 Jul 2026 19:41:24 GMT]]></title><description><![CDATA[<p dir="auto">Never used <code>invokeMethod()</code>.  Is it synchronous or asynchronous?</p>
]]></description><link>https://forum.qt.io/post/839187</link><guid isPermaLink="true">https://forum.qt.io/post/839187</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Thu, 16 Jul 2026 19:41:24 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Thu, 16 Jul 2026 18:29:27 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/simonschroeder">@<bdi>SimonSchroeder</bdi></a> I wasn't clear but I was thinking about using <code>invokeMethod</code> from the callback so indeed, the solver can be independent from Qt.</p>
]]></description><link>https://forum.qt.io/post/839186</link><guid isPermaLink="true">https://forum.qt.io/post/839186</guid><dc:creator><![CDATA[SGaist]]></dc:creator><pubDate>Thu, 16 Jul 2026 18:29:27 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Thu, 16 Jul 2026 07:17:22 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/sgaist">@<bdi>SGaist</bdi></a> Yes, <code>invokeMethod()</code> 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.</p>
]]></description><link>https://forum.qt.io/post/839177</link><guid isPermaLink="true">https://forum.qt.io/post/839177</guid><dc:creator><![CDATA[SimonSchroeder]]></dc:creator><pubDate>Thu, 16 Jul 2026 07:17:22 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Wed, 15 Jul 2026 18:45:40 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/christian-ehrlicher">@<bdi>Christian-Ehrlicher</bdi></a> said in <a href="/post/839167">Show a QMessage box from the context of a function defined outside mainwindow.cpp</a>:</p>
<blockquote>
<p dir="auto">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.</p>
</blockquote>
<p dir="auto">Beside the suggestion of <a class="plugin-mentions-user plugin-mentions-a" href="/user/christian-ehrlicher">@<bdi>Christian-Ehrlicher</bdi></a>, one can also make use of <a href="https://doc.qt.io/qt-6/qmetaobject.html#invokeMethod" target="_blank" rel="noopener noreferrer nofollow ugc">invokeMethod</a> so everything GUI can properly stay in the place of concern rather than having unrelated code handling GUI related stuff.</p>
]]></description><link>https://forum.qt.io/post/839171</link><guid isPermaLink="true">https://forum.qt.io/post/839171</guid><dc:creator><![CDATA[SGaist]]></dc:creator><pubDate>Wed, 15 Jul 2026 18:45:40 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Wed, 15 Jul 2026 13:25:01 GMT]]></title><description><![CDATA[<p dir="auto">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.</p>
]]></description><link>https://forum.qt.io/post/839167</link><guid isPermaLink="true">https://forum.qt.io/post/839167</guid><dc:creator><![CDATA[Christian Ehrlicher]]></dc:creator><pubDate>Wed, 15 Jul 2026 13:25:01 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Wed, 15 Jul 2026 06:55:44 GMT]]></title><description><![CDATA[<p dir="auto">In my projects, if I want to separate these kind of things I tend to use callback functions (basically <a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a>'s function pointer suggestion). Callback functions might have specific callback data associated with it. This would help with your specific version including a main window.</p>
<p dir="auto">This might look like the following:</p>
<pre><code>typedef void (*solver_warning_callback_t)(const std::string &amp;message, int current_iteration, int max_iterations, void *callback_data);
...
solver_warning_callback_t solver_warning_callback = nullptr;
void *solver_warning_callback_data = nullptr;
</code></pre>
<p dir="auto">From your main window you would have to register the callback and set the callback data:</p>
<pre><code>solver_warning_callback = [](const std::string &amp;message, int current_iteration, int max_iterations, void *callback_data)
{
    MainWindow *mw = reinterpret_cast&lt;MainWindow*&gt;(callback_data);
    QMessageBox::warning(mw, tr("Solver warning"), QString::fromStdString(message));
};
solver_warning_callback_data = this; // setting callback data from a member function within MainWindow
</code></pre>
<p dir="auto">Then you can call it from your solver function:</p>
<pre><code>solver_warning_callback("Solver did not converge withing specified iterations", i, maxIterations, callback_data);
</code></pre>
<p dir="auto">Notice that I included the iterations and max iterations in this example to show you would handle additional parameters (but they don't have to be used by the callback itself). Assuming you might want to have no Qt inside your solver I also used <code>std::string</code> instead of <code>QString</code>. Usually, the callback data is the last parameter to a callback function. It is always a <code>void*</code> pointer to allow for any data. This can safely be cast back and forth. If you want to use more than just a single parameter as the callback data you just put it into a <code>struct</code>. However, you have to make sure that the struct variable lives long enough! If you don't have any callback data, just leave it as <code>nullptr</code>. The callback data does not have to be used by the callback function, but usually sooner or later you'll need it. So, any callback function should have that callback data as a parameter. Using a lambda function that captures the data instead would not work. The capture list needs to be empty (if you are using a lambda; regular functions also work!).</p>
]]></description><link>https://forum.qt.io/post/839160</link><guid isPermaLink="true">https://forum.qt.io/post/839160</guid><dc:creator><![CDATA[SimonSchroeder]]></dc:creator><pubDate>Wed, 15 Jul 2026 06:55:44 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Mon, 13 Jul 2026 07:13:54 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/lukester88">@<bdi>lukester88</bdi></a><br />
You can use quite a number of ways.  <a class="plugin-mentions-user plugin-mentions-a" href="/user/joecfd">@<bdi>JoeCFD</bdi></a>'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 <em>require</em> 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.</p>
<p dir="auto">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 <code>QMessageBox</code> (<a href="https://doc.qt.io/qt-6/qmessagebox.html#static-public-members" target="_blank" rel="noopener noreferrer nofollow ugc">https://doc.qt.io/qt-6/qmessagebox.html#static-public-members</a>) 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/<a href="https://doc.qt.io/qt-6/qtlogging.html#qInstallMessageHandler" target="_blank" rel="noopener noreferrer nofollow ugc">qInstallMessageHandler(QtMessageHandler handler)</a> where you could cause your <code>qDebug()</code> or similar calls to be shown to the user in a message box.  So many ways! :)</p>
]]></description><link>https://forum.qt.io/post/839129</link><guid isPermaLink="true">https://forum.qt.io/post/839129</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Mon, 13 Jul 2026 07:13:54 GMT</pubDate></item><item><title><![CDATA[Reply to Show a QMessage box from the context of a function defined outside mainwindow.cpp on Sun, 12 Jul 2026 22:12:04 GMT]]></title><description><![CDATA[<p dir="auto">Thank you for the reply! Do you happen to have a brief example of how this would be accomplished?</p>
]]></description><link>https://forum.qt.io/post/839124</link><guid isPermaLink="true">https://forum.qt.io/post/839124</guid><dc:creator><![CDATA[lukester88]]></dc:creator><pubDate>Sun, 12 Jul 2026 22:12:04 GMT</pubDate></item></channel></rss>