Qt GUI数学应用程序在计算时挂起了GUI

yak*_*yak 5 c++ user-interface qt

我的应用程序有一个简单的GUI =我必须为我的数学函数设置一些输入参数,然后单击"计算"按钮,然后启动函数.数学函数是用纯C编写的,所以没有对象,只有函数.

它看起来像这样:

#include "mymath.h"

class myMath : public QMainWindow
{
    Q_OBJECT

    // ...
    void compute();
};

void myMath::compute()
{
   //get parameters from gui
   call_C_fun();
   // save results to GUI
}
Run Code Online (Sandbox Code Playgroud)

这个代码的主要问题是,当我点击'compute'(它做了太多的计算,它需要大约5分钟左右)时它会挂掉我的GUI,所以我什么也做不了(我甚至看不到我的GUI,窗口在计算运行的时候被"冻结".在函数完成后,它在QLabel上打印出结果,GUI又一次"活着".我怎么能解决这个问题?我不想要我的当计算需要时间时,GUI会被"冻结".任何想法?我想过QThread- 但我在线程中有点新东西,所以请为新手提供简单易懂的答案:)

The*_*ght 6

将计算分解为另一个线程,如下所示: -

// This is the object that will run the computation on a different thread
class Computation : public QObject
{
signals:
    void Finished();
public slots:
    void Compute();
};
Run Code Online (Sandbox Code Playgroud)

然后在主窗口类中创建另一个线程并开始运行: -

class MyMath : public QMainWindow
{
    public:
        void StartComputation();
};


MyMath::StartComputation()
{
    QThread* pThread = new QThread;
    Computation* pComputation = new Computation;

    // move computation to the new thread
    pCompuation->moveToThread(pThread);

    // Note Qt5 connection style    

    // ensure the computation starts when the thread starts
    connect(pThread, &QThread::started, pComputation, &Computation::Compute); 
    // when computation is finished, quit the thread
    connect(pComputation, &Compute::Finished, pThread, &QThread::quit);
    // have the thread tidy up when finished
    connect(pThread, &QThread::finished, pThread, &QThread::deleteLater);
    // start it!
    pThread->start();
}
Run Code Online (Sandbox Code Playgroud)


JBL*_*JBL 2

在你的情况下,线程将是一个解决方案。您的计算将在一个单独的线程中运行,然后您的 GUI 在计算您需要的任何内容时能够做出响应。

根据我的经验,这是 GUI 中很常见的事情。GUI 有它自己的线程,并且您的逻辑使用它自己的线程。

然后,您可以使用非常简单的模式来处理此问题,使用来自启动工作程序的 GUI 的信号,以及来自触发 GUI 中更新的工作程序的信号。

您需要小心常见的线程安全问题。我强烈建议您学习一些有关线程的一般知识,以便更好地掌握您正在做的事情。它还可以帮助您理解在使用线程代码时可能会观察到的奇怪行为(这对于不习惯它的人来说并不总是微不足道的)。

我还建议您阅读QThread 文档,它很好地解释了如何在 Qt 中实现线程代码(不过,更喜欢单独的工作线程而不是 Qthread 的子类化)。另请查看QMutexQMutexLocker,您可能需要它们。