Reputation: 366
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? If the ui thread blocks waiting, then i would not to wait for the second thread. 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. 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?
I'm not quite a Qt pro. 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.
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;
}
}
Upvotes: 0
Views: 1199
Reputation: 88
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). Also connect the QThread to a slot by Signal/Slot method to signal the UI thread when the operation has ended. 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.
Upvotes: 0
Reputation: 25536
QThread
has a finished
signal. 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).
Upvotes: 2
Reputation: 2073
If you don't want to block the user interface, all you have to do is to call QApplication::processEvents();
in your while-loop.
I have some code which uses std::future instead of QThread and my code looks like this:
while (!progressIndicator->UserBreak()
&& (future.wait_for(std::chrono::seconds(0)) != std::future_status::ready))
{
QApplication::processEvents();
}
This works well.
Upvotes: 1