Hybrid Qt GUI/Console cmake application on Windows
-
Hi there,
as in the title, I want to make one of my apps a hybrid CLI/GUI app.
While looking for a way to do it I found this code snippet in the official Qt documentation:
QCoreApplication* createApplication(int &argc, char *argv[]) { for (int i = 1; i < argc; ++i) { if (!qstrcmp(argv[i], "-no-gui")) return new QCoreApplication(argc, argv); } return new QApplication(argc, argv); } int main(int argc, char* argv[]) { QScopedPointer<QCoreApplication> app(createApplication(argc, argv)); if (qobject_cast<QApplication *>(app.data())) { // start GUI version... } else { // start non-GUI version... } return app->exec(); }
( https://doc.qt.io/qt-6/qapplication.html#details )
And this is the same code I'm currently using.
Further I added this to my CMakeLists:
set_target_properties(QtHybridApp PROPERTIES # False because of hybrid app, # if True -> WIN32 WINMAIN() entry point # = no Main() = no console app output possible WIN32_EXECUTABLE FALSE )
I can start the GUI and I can start the CLI mode with
-no-gui
, all is working good,
but, even when I start my app with GUI, a blank console window is opening in the background.
If I close it, the whole app exits.Is there a way to have either... or... ? I don't expect the console to show up when using the GUI mode.
Btw: I've see topics like this one, which did not help at all. I also don't want to have any launcher or "two-app-solution".
Thanks in advance :)
Edit:
The app is going to be Windows-only. No need to enforce platform-independency. -
You get the console because your CMake ends up passing /CONSOLE flag to visual studio's linker and that flag causes the runtime linker loader to create a console for you.
If you want to run the same executable in a mode without a console I'm not sure if you have any other way other than remove the /CONSOLE linker flag and then when you want the console based on your cmd line args create it yourself.
https://learn.microsoft.com/en-us/windows/console/creation-of-a-console
-
@SamiV123 said in Hybrid Qt GUI/Console cmake application on Windows:
You get the console because your CMake ends up passing /CONSOLE flag to visual studio's linker and that flag causes the runtime linker loader to create a console for you.
I use MinGW and QtCreator for this project.
After some more research and testing, I came up with this (solution was found here):
#include "windows.h" if (qobject_cast<QApplication *>(app.data())) { // start GUI version... ShowWindow(GetConsoleWindow(), SW_HIDE); // ... } else { // start non-GUI version... } // ...
This instantly hides the console when starting in GUI mode. Sometimes you'll see a little "blink" where the console opens and closes, but I think it's fine since there seems no way other than creating two independent apps for console and GUI and/or use a launcher.
Will leave it open for more suggestions
-
I use MinGW and QtCreator for this project.
Yeah ok, but still it essentially boils down to the same flag being set in the executable that then tells the runtime linker / process loader to set-up the console for your process on startup.
Will leave it open for more suggestions
Like I said, the alternative is to create the console yourself with the Win32 API(s).
Honestly though, your solution is probably adequate if your product people are able to accept the occasional blink of the console window on startup.
-
Instead of closing the console window you could compile without the /CONSOLE flag and then use AttachConsole in the case of the non-gui application.
We are actually using a two-application solution which is a little different than a launcher script. This solution is taken from Microsoft itself. Visual Studio comes as a
devenv.exe
and adevenv.com
. The .exe is the GUI application and the .com is the command line application. On the command line (when using the application name without the file ending) it will start the .com application. In our own application we added command line parameters to have each call the other one (using QProcess) to switch between GUI/non-GUI.