简体   繁体   English

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

[英]Will UI block when waiting for QThread / How to use QThread properly

If I have a progressbar in the ui thread (window), which shall run endless until a method finishes it's work, will the ui thread block and so the progress bar if I'm waiting for a second QThread to finish? 如果我在ui线程(窗口)中有一个进度条,该进度条将无休止地运行,直到方法完成其工作为止,如果我在等待第二个QThread完成,ui线程是否会阻塞进度条? If the ui thread blocks waiting, then i would not to wait for the second thread. 如果ui线程阻塞了等待,那么我就不会等待第二个线程。 I thought to implement a callback method which will be called when the second thread finished, but then: How can i connect to the callback method? 我想实现一个回调方法,该方法将在第二个线程完成时调用,但是然后:我如何连接到该回调方法?

What do I want to do? 我要怎么办 I have a window, this window has a progressbar which is first not visible. 我有一个窗口,此窗口有一个进度条,它首先不可见。 When the user presses a certain button to request data, a method will be called which returns a RequestPointer which contains a method which returns the request status. 当用户按下某个按钮以请求数据时,将调用一个方法,该方法返回一个RequestPointer,其中包含一个返回请求状态的方法。 When the user presses the button, i want to make the progress bar visible, running infinitely till the request is finished and i can print the data to the window. 当用户按下按钮时,我希望使进度条可见,并无限运行直到请求完成为止,并且我可以将数据打印到窗口中。 To the Worker i want to pass this pointer and the worker checks in a while (flag) loop, if the status is still running and sleep if so. 我想传递给工作人员该指针,工作人员会在一段时间(标志)循环中检查状态是否仍在运行,如果处于睡眠状态则进入睡眠状态。 When the worker finishes, i want to stop the progressbar and make it unvisible again. 工作人员完成操作后,我要停止进度栏,并使它再次不可见。 Do i have to pass the progress bar to the thread, or can i wait for the thread without blocking the ui? 我必须将进度条传递给线程,还是可以在不阻塞ui的情况下等待线程?

I'm not quite a Qt pro. 我不是Qt专业人士。 Really new to it. 真的很新。 I tried to get some info from the https://doc.qt.io/Qt-5/qthread.html website, but it's a bit hard for me to understand the code example. 我试图从https://doc.qt.io/Qt-5/qthread.html网站获得一些信息,但是我很难理解该代码示例。

Method in my worker class: 我的工人班上的方法:

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;
        }

    }

QThread has a finished signal. QThread具有finished信号。 Connect this one to some appropriate slot, which will trigger any action necessary on thread completion. 将此连接到适当的插槽,这将触发线程完成时所需的任何操作。

I suppose best candidate to know how far the progress went is the worker thread itself. 我想最好的人选是知道工作线程本身所取得的进步。 You might create your own signal that sends the current progress to some slot that will do the update of the progress bar appropriately. 您可以创建自己的信号,将当前进度发送到某个插槽,该插槽将适当地更新进度栏。

Alternatively, you might use a QTimer to read the current progress from time to time (this resembles closer to what you have now, but does not block the UI). 或者,您可以使用QTimer来不时读取当前进度(这与您现在的进度很相似,但不会阻塞UI)。

If you don't want to block the user interface, all you have to do is to call QApplication::processEvents(); 如果您不想阻塞用户界面,则只需调用QApplication::processEvents(); in your while-loop. 在您的while循环中。

I have some code which uses std::future instead of QThread and my code looks like this: 我有一些使用std :: future而不是QThread的代码,我的代码如下所示:

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

This works well. 这很好。

To update the UI Thread's progress bar while the operation is running, use a QTimer object to increment the progress bar's value (Max value will be :One less than Progress bar's value when the operation completes). 要在操作运行时更新UI线程的进度条,请使用QTimer对象增加进度条的值(操作完成后,最大值将为:小于进度条的值一个)。 Also connect the QThread to a slot by Signal/Slot method to signal the UI thread when the operation has ended. 还可以通过Signal / Slot方法将QThread连接到插槽,以在操作结束时向UI线程发出信号。 When the QThread finishes the operation, send a signal to a Slot in the UI Thread, which will set the final value of the progress bar and also stop the QTimer. 当QThread完成操作时,向UI Thread中的Slot发送信号,这将设置进度条的最终值并停止QTimer。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM