How to update the GUI from another thread?
-
Hi,
I have a long-running task (for loop) which I want to run in a seperate QThread (to not block the gui).
In each iteration of the loop I want to send an update to my GUI which will draw a line. How would I do this?
Do I have to use signals to communicate between the MainThread (GUI) and the QThread where I run my computation?Bonus questions: Is it possible to pause the for loop which is inside the seperate QThread via some pause button and then continue again from where it stopped? Is there documentation for this?
-
Hi and welcome to devnet,
See the Mandelbrot example for a possible implementation.
As for stopping and restarting the loop, sure you can, a way to do it also shown in that example. There might be others depending on your needs though.
-
Hi,
I have a long-running task (for loop) which I want to run in a seperate QThread (to not block the gui).
In each iteration of the loop I want to send an update to my GUI which will draw a line. How would I do this?
Do I have to use signals to communicate between the MainThread (GUI) and the QThread where I run my computation?Bonus questions: Is it possible to pause the for loop which is inside the seperate QThread via some pause button and then continue again from where it stopped? Is there documentation for this?
@HoliGui said in How to update the GUI from another thread?:
Do I have to use signals to communicate between the MainThread (GUI) and the QThread where I run my computation?
Yep :)
Bonus questions: Is it possible to pause the for loop which is inside the seperate QThread via some pause button and then continue again from where it stopped?
QThreads do not natively support "pausing". You might achieve this with signals & slots too. You will have to write the link to a UI "Pause" button yourself. -
Hi and welcome to devnet,
See the Mandelbrot example for a possible implementation.
As for stopping and restarting the loop, sure you can, a way to do it also shown in that example. There might be others depending on your needs though.
-
In the case of the example the decoupling is already done.
Your business logic should go in a class (or several depending on it) and then you can simply use signals and slots to transmit your data between both. Or use the model view approach.
It really depends on what your business logic does and what kind of data it generates that shall be shown on the UI.
-
@SGaist Thank you this looks really promising. Do you have a suggestion how to decouple GUI logic from business logic?
I tought about implementing an observer/Eventlistener pattern to communicate with the GUI.@HoliGui said in How to update the GUI from another thread?:
Thank you this looks really promising. Do you have a suggestion how to decouple GUI logic from business logic?
I tought about implementing an observer/Eventlistener pattern to communicate with the GUI.Qt's signals and slots already is some sort of observer pattern: The observer will register its slot with the appropriate signals. No need to reinvent the wheel here. Your business logic would just have a signals saying "this has changed" and the GUI logic would take that information (in a slot) and decide how to display it.
The problem of executing GUI code in a different thread occurred for me over and over again. You can queue function calls using
QMetaObject::invokeMethod(qGuiApp, ...). Most easily just put in a lambda for'...'. I wrote a little helper library for this: https://github.com/SimonSchroeder/QtThreadHelper . You can just useguiThread(...)to execute any function inside the GUI thread. It is a single header library (requires C++17).