Run Qt Gui in separate thread
-
Re: Running QApplication::exec() from another thread (QCoreApplication)
Sorry to bring this up again. I need clarification on run or launch a Qt Gui from an existing application that is non qt based. I have read a lot of posts over the last few days trying to make sense of the different dates with different approaches. I never knew that I could not use QThread!
Background: My project is an existing non-gui simulation application that calls an "update" method at a scheduled rate (for example every 20-30 ms). At the initialization phase I want to show a gui with some data produced by the update.
The referenced post might be the approach I should use but I wanted to make sure that I understood that I should create a new thread (for example using std::thread) i.e.not using QThread.
In this new thread I should call QApplication etc. and show the gui window. I know I have to figure out how to get data to this gui and perhaps back to the update method.
Is there any change to this approach since the original post?
I am currently forced to use Qt 5.15 and VC2010 but might be able to use Qt 6 an VC2019 if required. -
Hum... sounds like you're doing it wrong.
I understand that what you have is
- a non GUI based application that computes something (simulation) and produces some result that gets updated at some interval?
- you want to show the result graphically?
Correct?
if so then what I would recommend is
- keep your simulation application separate.
- create a gui application that is separate
- have the gui application launch the simulation app process
- use IPC to share the result data from the simulation app to the GUI app.
- depending on the volume of data and frequency etc. you can use sockets, pipes, files or named memory maps to share.
Pros
- you just create another app for the graphical display, no need to try to retrofit a GUI onto the previous application. Just add the IPC as needed.
- depending on the IPC method you choose but with some more elaborate protocols you can even pipe the output to a web server, websocket and create your GUI in HTML5/JS
-
Hi, and welcome!
@tparry_venture-0 said in Run Qt Gui in separate thread:
The referenced post might be the approach I should use but I wanted to make sure that I understood that I should create a new thread (for example using std::thread) i.e.not using QThread.
In this new thread I should call QApplication etc. and show the gui window. I know I have to figure out how to get data to this gui and perhaps back to the update method.
Yes, you have understood correctly.
Is there any change to this approach since the original post?
No, nothing has changed since the original post at https://forum.qt.io/topic/124878/running-qapplication-exec-from-another-thread-qcoreapplication-qguiapplication
-
You are on Windows. This has many restrictions that have nothing to do with Qt specifically when talking about GUI applications. First of all, when compiling you need to specify if your application is a console or a GUI application. A GUI application does not have a console (there are workarounds to attach a console window to stdout). If you want to use any GUI features (Qt or not) you need to switch this setting. Second, if you specify a GUI application on Windows, WinMain() is called instead of main(). Qt just hides this so you can write your regular main() function. This means that on startup of your app Windows decides which thread gets all the notifications/signals (mouse, keyboard, redraw, ...). This makes it impossible to move all this into a separate thread. Maybe there are some crazy tricks to register GUI functionality after the fact with Windows in a console application. If these exist, Qt is not built to work with this approach. (And there would be very few experts to help you with this, let alone one who knows Qt at the same time).
-
@SimonSchroeder said in Run Qt Gui in separate thread:
You are on Windows. This has many restrictions that have nothing to do with Qt specifically when talking about GUI applications. First of all, when compiling you need to specify if your application is a console or a GUI application. A GUI application does not have a console (there are workarounds to attach a console window to stdout). If you want to use any GUI features (Qt or not) you need to switch this setting. Second, if you specify a GUI application on Windows, WinMain() is called instead of main(). Qt just hides this so you can write your regular main() function. This means that on startup of your app Windows decides which thread gets all the notifications/signals (mouse, keyboard, redraw, ...). This makes it impossible to move all this into a separate thread. Maybe there are some crazy tricks to register GUI functionality after the fact with Windows in a console application. If these exist, Qt is not built to work with this approach. (And there would be very few experts to help you with this, let alone one who knows Qt at the same time).
Sorry to say but this is wrong in so many ways:
- A console application can open windows just fine, it's not a problem.
- Your "non-console" app doesn't have to have WinMain, again it can have just int main(int argc, char* argv), it all boils down to a single linker setting when you build. /CONSOLE (or not)
- There's no "windows decides which thread gets ...".
On Win32 each thread begins without a message queue and when the thread makes a Win32 API call that requires a message queue one gets created it if doesn'tt already exist. - Any thread can create a message queue and create windows. Just that the GUI components such as windows have a strong thread affinity, i.e. a window can only be accessed from the thread that created it. All the window events that belong to that window (such as key presses and mouse events) are then posted to the message queue associated with that window. So the thread that called CreateWindow(Ex) is then the thread that will receive the message through GetMessage/PeekMessage.
- There's no "crazy tricks to register GUI functionality", the GUI functionality is always there.. As a developer all you need to do is to link against the correct libraries such as user32.lib/dll and it makes no difference whether this is a "console" or "win32" app. The only time this makes a difference is when you run your "Project Wizard" in MSVS and it sets up the project template for you and chooses the default compiler and linker settings for you.
-
@SamiV123 said in Run Qt Gui in separate thread:
Sorry to say but this is wrong in so many ways:
Thanks for the clarification. Do you think that Qt would somehow work with such a model? Could we run Qt event loops for native events in separate threads? Could we open widgets inside other threads? What parts of Qt would we have to work around? (QApplication maybe?)
-
This post is deleted!
-
@jsulm
I think/suspect @SimonSchroeder's post is intended as "rhetorical". I believe he is aware of this, and is replying to @SamiV123 to suggest that whatever Windows might or might not allow natively there are restrictions in Qt (such as UI only on main thread) which would still have to be obeyed regardless. -
@SimonSchroeder said in Run Qt Gui in separate thread:
@SamiV123 said in Run Qt Gui in separate thread:
Sorry to say but this is wrong in so many ways:
Thanks for the clarification. Do you think that Qt would somehow work with such a model? Could we run Qt event loops for native events in separate threads? Could we open widgets inside other threads? What parts of Qt would we have to work around? (QApplication maybe?)
Conceptually a thread is a thread, there's no difference between the thread that the system creates for you vs. the one that you could create yourself with CreateThread.
About Qt I don't know. I can see failure modes if some bad engineering is done.
-
@SamiV123 said in Run Qt Gui in separate thread:
About Qt I don't know. I can see failure modes if some bad engineering is done.
there's one major problem with creating a Thread via QThread that then contains the QCoreApplication instance.
QThread is a QObject. And QCoreApplication or one of its derivatives NEEDS to be the first QObject to be instantiated. One of the reasons static QObjects are prohibited
-
@J-Hilk said in Run Qt Gui in separate thread:
@SamiV123 said in Run Qt Gui in separate thread:
About Qt I don't know. I can see failure modes if some bad engineering is done.
there's one major problem with creating a Thread via QThread that then contains the QCoreApplication instance.
QThread is a QObject. And QCoreApplication or one of its derivatives NEEDS to be the first QObject to be instantiated. One of the reasons static QObjects are prohibited
Yep, but you can always use CreateThread, std::thread for example.