Printing to console... in a non-console application.
-
Hi!
I'm developing an application that should work in two different modes, that is, having a GUI or as a regular console application.
I use the number of arguments in the command line to tell apart the way it should work. If the app is invoked just by typing its name (that is, "myapp"), then I create a widget where I can type all the required data for the app to work. On the contrary, if I call the app passing the name of a file containing the same options that I would type in the GUI (that is, "myapp the_options_file.txt") then it should work as a pure console applicaiton.
Everything works fine... but the fact that I can't print messages to the console... since this is not a console application. If I add CONFIG += "console" in my .pro file then I always get a console, no matter whether I start the app with or without GUI, which is pretty awful.
I know that, maybe, I'm asking something that is not possible, but if there is a way to solve this problem, It'd be great.
By the way: the idea is to use the app either by humans (GUI behaviour) or integrated in a production chain (in batch files). That's why I'm trying to do such weird thing; I'd prefer not having to develop to different (but at the same time, so similar) applications.
By the way, I'm using QT 5.9.2.
Thank you very much!
-
Which platform you are using and which platforms you are targeting?
-
@bleriot13 some more clarifications please:
- what approach are you using for "printing" your "messages"?
1.a qDebug()/qInfo() and so on?
1.b printf("message") / cout << "message" - "Everything works fine..." what is that exactly? What are you seeing in GUI mode that you cannot see in console mode?
- what approach are you using for "printing" your "messages"?
-
This is not an answer to your problem but a suggestion for a method to deal with something like this. What I would do is write the application as pure console. If you want a GUI front end write a separate program that calls the console version with all the necessary arguments (don't try and duplicate what the console program does in the GUI version of your program). I have seen lots of examples of this approach but I haven't seen any using the way you describe. You will have problems when working from a console if a GUI environment is not available.
-
@bleriot13 If you start your GUI application from a console then you should see what it prints.
If you need to have both: console only and GUI support, then you either create two executables which share libs with actual program logic or you create one executable where you can tell the application whether you want an UI or not using a parameter.
Example:# Start as console application ./myApp # Start as GUI application ./myApp -ui
-
@casdevel
Good morning! The target is Windows only. Thanks for your interest!
-
Hi!
I have tried everything, starting from cout, going through qInfo() and using QTextStreams. None of these approaches worked because of a very simple reason: I don't have a console to write to...
Thanks!
@Rondog Hi. 'm afraid that what you say is the only way to go. However, I've thought of another approach; instead of writing to the console, I may write to a log file, which is always possible. Thanks!
@jsulm Hi! What you propose is what I do. The parameter you talk about to tell the application how to work is the name of an options file. It it is present in the command line, then the app doesn't instantiate the interface widget and calls the object (non graphical) that does the actual job. If no paremeter is present, then the app creates the widget to let the user type the data that would have been present in the (absent) options file and then run the (non-graphical) object.
In the second case I show a message box stating the result of the process. In the first one, I try to write such status message to the "console". And this is the problem; this approach does not work. That's exactly why I asked for help in this forum.
And I would prefer not to split the app into two...
Thanks for your interest!
-
@bleriot13
You need to create the console dynamically, not at compile/link time. https://stackoverflow.com/questions/3360548/console-output-in-a-qt-gui-app gives some suggestions. Since it appears that Qt does not offer this functionality through its own code, you need to call a native WIN32 function likeAttachConsole
orAllocConsole
. https://stackoverflow.com/a/41701133/489865 looks good. -
@JonB Hi! Yes! This is more or less what I was looking for.
It works, but in a little weird way. It prints the messages to the console... but only after the process has finished and after the command prompt in the command line window has been printed too.
For instance, this is what I get:
myprompt > myprogram my_options_file.op
myprompt> Successful completioninstead of:
myprompt > myprogram my_options_file.op
Successful completion
myprompt>I've tried everything: flushing after writing (as, for instance, cout << "Successful completion" << endl << flush;) closing stdout and stderr (fclose(stdout); fclose(stderr);) and dettaching the console (Freeconsole();). No matter what I do, the messages appear after the command prompt.
One more question, and just in the case that soon or later someone asks me to migrate to Linux. Is there any equivalent of Attachconsole (and, eventually, Freeconsole) in the gcc world?
Thanks!!!!
-
@bleriot13
I'm not really a C++ or Windows person.Your question now is not really about Qt, it's about redirection from a Windows GUI app.
In that thread I pointed you to, several people seemed to say it didn't really work for C++
cout
stuff, doubtless hence your problem. You'd probably have to delve into the mysteries of C++ stdio.As per https://stackoverflow.com/a/3370017/489865:
Windows does not really support dual mode applications.
I don't recall seeing any Windows application which tries to do what you want, half GUI and half console. I think that's problematic. The more usual way would be to factor your "back-end" code so that it is callable from either one of a GUI or console front-end separate programs. I think that is what @Rondog was saying.
GUI programs don't play well with things like stdin/stdout or batch files. For example, how do you think your app is going to work right in a "chain"? If I'm not mistaken, because it will ultimately be linked as a Windows/GUI app, not a console one, I don't think you'll be able (easily) to wait for it to finish from a batch file, which may render your whole approach useless? I'd rethink how you intend to do this.
As for Linux. I don't think there's an exact equivalent of the Windows-only console code. Again, for portability, I'd rethink how you're doing this.
-