在等待QThread /如何正确使用QThread时,UI是否会阻塞

时间:2019-03-25 10:06:34

标签: c++ qt qthread

如果我的ui线程(窗口)中有一个进度条,该进度条将无休止地运行,直到方法完成其工作为止,如果我在等待第二个QThread完成,ui线程是否会阻塞进度条?如果ui线程阻塞了等待,那么我就不会等待第二个线程。我想实现一个回调方法,该方法将在第二个线程完成时调用,但是然后:我如何连接到该回调方法?

我想做什么? 我有一个窗口,此窗口有一个进度条,它首先不可见。当用户按下某个按钮以请求数据时,将调用一个方法,该方法返回一个RequestPointer,其中包含一个返回请求状态的方法。 当用户按下按钮时,我希望使进度条可见,并无限运行直到请求完成为止,并且我可以将数据打印到窗口中。 我想传递给工作人员该指针,工作人员会在一段时间(标志)循环中检查状态是否仍在运行,如果处于睡眠状态则进入睡眠状态。工作人员完成操作后,我要停止进度栏,并使它再次不可见。我必须将进度条传递给线程,还是可以在不阻塞ui的情况下等待线程?

我不是Qt专业人士。真的很新。我试图从https://doc.qt.io/Qt-5/qthread.html网站上获取一些信息,但是我很难理解该代码示例。

工作者类中的方法:

void Worker::watchRequest(RequestPtr r_ptr)
{
    bool exit = true;

    while (!exit)
    {
        ErrorCode errorCode = r_ptr->Test();

        switch (errorCode)
        {
        case Request_RUNNING:   
            QThread::msleep(10);
            break;
        case Request_ABORTED:
            exit = true;
            break;
        case Request_SUCCESS:
            exit = true;
            break;
        }

    }

3 个答案:

答案 0 :(得分:2)

QThread有一个finished信号。将此连接到适当的插槽,这将触发线程完成时所需的任何操作。

我想最好的人选是知道工作进程本身是什么进展。您可以创建自己的信号,将当前进度发送到某个插槽,该插槽将适当地更新进度栏。

或者,您可以不时使用QTimer来读取当前进度(类似于您现在的进度,但不会阻止UI)。

答案 1 :(得分:1)

如果您不想阻塞用户界面,只需在while循环中调用QApplication::processEvents();

我有一些使用std :: future而不是QThread的代码,我的代码如下:

while (!progressIndicator->UserBreak()
    && (future.wait_for(std::chrono::seconds(0)) != std::future_status::ready))
{
    QApplication::processEvents();
}

这很好。

答案 2 :(得分:0)

要在操作运行时更新UI线程的进度条,请使用QTimer对象增加进度条的值(操作完成时最大值将为:比进度条的值小1)。还可以通过Signal / Slot方法将QThread连接到插槽,以在操作结束时向UI线程发出信号。当QThread完成操作后,向UI Thread中的Slot发送信号,这将设置进度条的最终值并停止QTimer。