Optimal way to update GUI from another thread?
-
I have a sensor which delivers 30 fps and I would like to pre process the images received and then visualize it on a
QLabel
.Since receiving frames from a sensor is a never ending
while
loop, this is how it looks like:void Class::startSensor() { // start a loop to receive frames on a different thread QtConcurrent::run(this, &Class::asyncFunction); // do other stuff }
Async function runs in a loop receiving frames and doing pre processing on the images and emits signals to update UIs.
void Class::asyncFunction() { // start a loop to receive frames on a different thread while(connection()) { // receive images and do pre-processing // medium weight computations doPreprocessing(); // signal main thread to update GUI // calls slot to render images on QLabels emit updateUI(); } // do other stuff }
Why? - To keep my GUI thread free and keep the whole application responsive. But i would like to know, is emitting signals in a loop to update GUI a good idea?
I feel emitting signals from another thread also keeps the GUI thread busy in updating the UI forever. Although, this method works but I noticed my GUI sometimes gets choppy, like: laggy when i move
QSplitter
or responsiveness ofQPushButtons
etc.What would be the optimal way to achieve better performing and reliable solution?
-
@MarKS said in Optimal way to update GUI from another thread?:
To keep my GUI thread free and keep the whole application responsive. But i would like to know, is emitting signals in a loop to update GUI a good idea?
Yes, it is a good idea to emit signals like this!
Although, this method works but I noticed my GUI sometimes gets choppy
What would be the optimal way to achieve better performing and reliable solution?Then buffer (e.g. a
QQueue
) the received signals at the slot side, and only actually update the visible UI at a rate you/the user is comfortable with. For example, you might only update the UI every 10 received signals, or you might have aQTimer
ticking which only updates from stored received signals so many times per second, or buffer them away if the user has started a splitter-drag, or many other similar approaches. Don't think that because the thread emits a signal the UI receiver has to act on that immediately. Regard the thread's signal as just a notification that something has happened, how/when the UI chooses to act on that is separate.