How to print to console when using Qt

327,837

Solution 1

If it is good enough to print to stderr, you can use the following streams originally intended for debugging:

#include<QDebug>
//qInfo is qt5.5+ only.
qInfo() << "C++ Style Info Message";
qInfo( "C Style Info Message" );
qDebug() << "C++ Style Debug Message";
qDebug( "C Style Debug Message" );
qWarning() << "C++ Style Warning Message";
qWarning( "C Style Warning Message" );
qCritical() << "C++ Style Critical Error Message";
qCritical( "C Style Critical Error Message" );
// qFatal does not have a C++ style method.
qFatal( "C Style Fatal Error Message" );

Though as pointed out in the comments, bear in mind qDebug messages are removed if QT_NO_DEBUG_OUTPUT is defined

If you need stdout you could try something like this (as Kyle Strand has pointed out):

QTextStream& qStdOut()
{
    static QTextStream ts( stdout );
    return ts;
}

You could then call as follows:

qStdOut() << "std out!";

Solution 2

I found this most useful:

#include <QTextStream>
QTextStream out(stdout);
foreach(QString x, strings)
    out << x << endl;

Solution 3

Writing to stdout

If you want something that, like std::cout, writes to your application's standard output, you can simply do the following (credit to CapelliC):

QTextStream(stdout) << "string to print" << endl;

If you want to avoid creating a temporary QTextStream object, follow Yakk's suggestion in the comments below of creating a function to return a static handle for stdout:

inline QTextStream& qStdout()
{
    static QTextStream r{stdout};
    return r;
}
...
foreach(QString x, strings)
    qStdout() << x << endl;

Remember to flush the stream periodically to ensure the output is actually printed.

Writing to stderr

Note that the above technique can also be used for other outputs. However, there are more readable ways to write to stderr (credit to Goz and the comments below his answer):

qDebug() << "Debug Message";    // CAN BE REMOVED AT COMPILE TIME!
qWarning() << "Warning Message";
qCritical() << "Critical Error Message";
qFatal("Fatal Error Message");  // WILL KILL THE PROGRAM!

qDebug() is closed if QT_NO_DEBUG_OUTPUT is turned on at compile-time.

(Goz notes in a comment that for non-console apps, these can print to a different stream than stderr.)


NOTE: All of the Qt print methods assume that const char* arguments are ISO-8859-1 encoded strings with terminating \0 characters.

Solution 4

Add this to your project file:

CONFIG += console

Solution 5

What variables do you want to print? If you mean QStrings, those need to be converted to c-Strings. Try:

std::cout << myString.toAscii().data();
Share:
327,837

Related videos on Youtube

lesolorzanov
Author by

lesolorzanov

Systems and computer engineer. MSc computer graphics. PhD and researcher. Working on biomedical imaging.

Updated on November 17, 2020

Comments

  • lesolorzanov
    lesolorzanov about 2 years

    I'm using Qt4 and C++ for making some programs in computer graphics. I need to be able to print some variables in my console at run-time, not debugging, but cout doesn't seem to work even if I add the libraries. Is there a way to do this?

    • Arnold Spence
      Arnold Spence about 12 years
      Can you elaborate on cout not working because that should certainly work. Do you get a compile error. Can you show a code example of cout that isn't working for you? Also explain how you are running the application. Are you running it from a console or from within an IDE and not seeing output to its output window?
    • sdaau
      sdaau over 7 years
      Just for completeness: @ArnoldSpence - without libraries, I get error: ‘cout’ was not declared in this scope; with iostream, I get error: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char>&)(& std::cout)), ...; using the commands in the answer instead works fine.
    • Toby Speight
      Toby Speight almost 6 years
      It is difficult to offer solutions when the problem statement is simply, "it doesn't work". Please edit your question to give a more complete description of what you expected to happen and how that differs from the actual results. See How to Ask for hints on what makes a good explanation.
    • user202729
      user202729 over 4 years
      In this case, you should explicitly specify that those "variables" are Qt-specific objects (such as QString).
  • lesolorzanov
    lesolorzanov about 12 years
    I asked ,while not debugging, there must be a function that allows me to write messages in console during runtime, not during debugging.
  • Arnold Spence
    Arnold Spence about 12 years
    Despite its name, that function is not related to debugging with a debugger. It is a convenience function that Qt provides for sending output to stderr that can be removed from compilation with a define. So it is an alternative for achieving output to the console at runtime.
  • lesolorzanov
    lesolorzanov about 12 years
    Thank you all a lot, I'm using this :). I guess there is no need then for me to write any of the code I used. Thanks! This has been super usefull.
  • Sebastian Negraszus
    Sebastian Negraszus over 10 years
    @CoderaPurpa You need to add #include <iostream>
  • JustMaximumPower
    JustMaximumPower about 10 years
    Please don't use qDebug for all console output. Only use it for true debug prints use qWarning, qCritical and qFatal for errors and warnings. Because qDebug statements can be removed when compiling with QT_NO_DEBUG_OUTPUT to save performance and stop the application from cluttering up the output.
  • Semyon Danilov
    Semyon Danilov almost 9 years
    I don't know why answer isn't accepted, but it's the most useful for sure.
  • Marshall Eubanks
    Marshall Eubanks over 8 years
    Agreed. stderr is for, well, errors (and debugging). This should be the accepted answer because it's the only one which uses stdout AND qt.
  • Michael Vincent
    Michael Vincent almost 8 years
    This one worked for me - and seemed like the correct way to output info via cout
  • Kyle Strand
    Kyle Strand almost 8 years
    There was no information given in the question regarding which build system is being used. This is only relevant when using qmake.
  • Kyle Strand
    Kyle Strand almost 8 years
    This (like Kyle Lutz's answer) is build-system specific.
  • Kyle Strand
    Kyle Strand almost 8 years
    If you incorporate the information from Goz's answer about how to print errors/warnings, along with a bit of information (sadly lacking from Goz's answer but present in the comments below it) about what qDebug() etc actually do, this will be by far the superior answer (IMO it's already superior since OP is asking for something to replace std::cout, but 40ish voters appear not to agree).
  • Yakk - Adam Nevraumont
    Yakk - Adam Nevraumont almost 8 years
    QTextStream qStdout() { return {stdout}; } might be a useful way to wrap this, consistent with qWarning() etc. And maybe some static state to avoid temporary streamage?
  • Yakk - Adam Nevraumont
    Yakk - Adam Nevraumont almost 8 years
    QTextStream qStdout() { static QTextStream r{stdout}; return r; }?
  • Kyle Strand
    Kyle Strand almost 8 years
    @Yakk Good suggestion! I'll incorporate into my answer.
  • relascope
    relascope over 7 years
    qFatal() gets an error when compiling with QT5. a read a post, that it wasn't ment to (be there/work) anyway... don't use it! :)
  • Kyle Strand
    Kyle Strand over 7 years
    @relascope I'm not sure what you mean by "gets an error," but the documentation does indicate that it will cause a core dump on Unix, so I've indicated that in the answer.
  • relascope
    relascope over 7 years
    /* sorry, didn't find the article anymore but / qFatal("Hello Fatal"); / is the way to use it (on QT5), it send SIGABRT !!! when compiling */ qFatal() << "Hello Fatal"; / ./qfatal/main.cpp: In function 'int main(int, char*)': ../qfatal/main.cpp:13:12: error: no matching function for call to 'QMessageLogger::fatal()' qFatal() << "Hello Fatal"; [...] qlogging.h:107:10: note: candidate expects 1 argument, 0 provided */
  • Kyle Strand
    Kyle Strand over 7 years
    @relascope Ah, I see, the function itself is supposed to take the error message string. I've edited my example; all four lines now compile correctly and behave as expected.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 6 years
    You don't want to be suggesting that people create a new text stream on every iteration of the loop. Even if the text stream had an optimization to make this cheap (it doesn't), it still would have very bad code smell to it. Obviously I just realized that you also comment that it's wrong. Here's what I suggest: I rolled back the edit. Sorry for the noise.
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber No problem. I actually did hope (if not assume) that since it's using an already-existing text stream in the constructor, it would have an optimization to make this cheap. But either way the "right" way to do this is indeed the function-returning-reference-to-static approach. Thanks for reminding me of this; I'll edit to simplify a bit.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 6 years
    stdout is not a text stream, it's a pointer a C file object. Apart from the buffers in QTextStream, you're also at the very least constructing and destructing a temporary QIODevice every time, too. That's how a QTextStream accesses the file: by wrapping it in a QIODevice subclass (I forget which one, probably QFile).
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber Ah, that also clarifies why stdout isn't from a namespace, which I'd been wondering but hadn't looked into.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 6 years
    @KyleStrand The C++98 standard, in [lib.c.files] says that stderr, stdin and stdout are macros and obviously macros can't be in any namespace. From Jakub Jelinek. That also tells you why macros are so bad, and unless you absolutely need them, they have no place in modern C++
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 6 years
    @KyleStrand E.g. in C++ if you include <cstdio>, you can't use any symbols named stdin, stdout, stderr, in any namespace :( They behave like keywords, except that the compiler will give you weird diagnostics and/or silently miscompile your code. E.g. on OS X/clang, a public foo::stdin symbol becomes foo::__stdinp, and any code that might use it will not link iff it happens not to include <cstdio>. Global namespace pollution by macros is frightening, frankly said.
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber I actually use them quite a bit, mostly to work around what I perceive as shortcomings in the language. For instance, I have a macro that simply takes the name of a member function and creates a lambda that copy-captures this and otherwise duplicates the member function's signature. I find this easier than remembering the oddities of generic capturing in C++14 for various compilers and more readable and typesafe than using std::bind(&ClassName::functionName, this, std::placeholders::_1, .... ).
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 6 years
    @KyleStrand This can be done with a function, no need for a macro :)
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber If nothing else, the function would require the 'this' pointer explicitly as one of its arguments, and I believe you'd need the fully scoped name of the function with ampersand function-pointer syntax as well. That's simply not as nice as a simple macro.
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber In other words, I find BIND_MEMBER_TO_THIS(myMemberFunc) much more readable than BindMemberToPtr(this, &MyClass::myMemberFunc).
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber Another example that's just come up: I realize that casting away const is dangerous and should therefore be explicit, but in the case where a const member function calls a non-const member function, I find it inelegant and redundant to have to re-specify what class I'm in just to cast away const. But the syntax for inferring the type and stripping const looks like this: const_cast<std::remove_const<std::remove_reference<decltype(‌​*this)>::type>::type‌​&>(*this). Seriously, there is no reason to type that multiple times.
  • Kuba hasn't forgotten Monica
    Kuba hasn't forgotten Monica over 6 years
    @KyleStrand Can't you use a function for that? template <typename C> constexpr typename std::remove_const<typename std::remove_reference<C>::type>::type& no_const(C* c) { return const_cast<typename std::remove_const<typename std::remove_reference<C>::type>::type&>(*c); } Use: no_const(this).method(). You could inject that function as a method into the class, and then you wouldn't even need to pass this: Foo& no_const() const { return ::no_const(this); } No typos, I promise.
  • Kyle Strand
    Kyle Strand over 6 years
    @KubaOber After I wrote that, I realized that indeed the std::remove_.... functions I'm using are indeed functions, so it should be possible to write a template function that could do the rest for me. I'll admit I still think that's way more complicated than it ought to be, but it's certainly not the argument for macros that I thought it was! Thank you.
  • phyatt
    phyatt almost 6 years
    One downside of QTextStream, is it doesn't print out all the Q-Types as easily as QDebug or QInfo, etc. For example: qDebug() << widget->geometry(); v. out << widget->geometry().x() << ", " << widget->geometry().y() //....
  • Tomáš Zato
    Tomáš Zato over 5 years
    And should I instantiate this only once? Or can I do this per pethod?
  • Tomáš Zato
    Tomáš Zato over 5 years
    I naively upvoted this answer before trying and I cannot take that back. But it does not work. When I replace qStdout with QTextStream(stdout) it works, so static initialization is probably a bad idea.
  • CapelliC
    CapelliC over 5 years
    @TomášZato: as you like... I would probably declare an inline in a .h (maybe toStdout.h), so would be easy to call
  • Kyle Strand
    Kyle Strand over 5 years
    @TomášZato I've tested this, so I know it works. When you say it "does not work", do you mean you get a compile error, or you don't get any output? Are you ensuring that the stream is flushed?
  • Tomáš Zato
    Tomáš Zato over 5 years
    It does not generate any output at all. Once I replaced it with QTextStream constructor it started working. I do not understand what do you mean by flushing the stream.
  • Kyle Strand
    Kyle Strand over 5 years
    @TomášZato Output is buffered and may not actually print until the stream is flushed (which simply means that the application forces all buffered output to be written, and stops execution until that has happened). This is done automatically by the QTextStream destructor, which may be why you're seeing output when you use the constructor directly to create temporary objects. To flush manually, just call qStdout().flush().
  • Kyle Strand
    Kyle Strand over 5 years
    @TomášZato (Buffering/flushing I/O is very standard; you should research it on your own if you still have questions about it.)
  • Kyle Strand
    Kyle Strand over 5 years
    @TomášZato I have made an edit that includes a note to flush the streams. If you are still having difficulties, feel free to remove your upvote (votes are unlocked when a post is edited).
  • Mitch
    Mitch about 5 years
    Is the part about making a function necessary? It seems the source you reference said it was a hypothetical: meta.stackoverflow.com/questions/287692/… I'd like to upvote this answer but I'm hesitant to believe that it's necessary to make a function that returns a static instance.
  • Kyle Strand
    Kyle Strand about 5 years
    @Mitch Hm, reviewing those links and the Qt documentation, you're right; I don't see anything to indicate that there's any real known issue caused by temporary QTextStream objects. Edited.
  • Peter Chaula
    Peter Chaula over 2 years
    myString.toUtf8().data() is better because it prints Characters outside the ascii range. Chinese characters for example
  • Swift - Friday Pie
    Swift - Friday Pie over 2 years
    QTextStream dooesn't flush the output, so if it used to show dynamic process, it will stall until program closes
  • Matthias Urlichs
    Matthias Urlichs over 2 years
    So add an appropriate flush statement to the answer?
  • MiB_Coder
    MiB_Coder over 2 years
    If you add << endl, the stream will also be flushed. This is not the case if you use "\n"
  • MiB_Coder
    MiB_Coder over 2 years
    Note that using << endl will also flush the stream, while "\n" does not.
  • CapelliC
    CapelliC over 2 years
    @MiB_Coder: that's by design in stdlib::streams, no ? Also, right now I don't remember if "\n" does the platform specific translation (at least on Windows, endl should be "\r\n").
  • MiB_Coder
    MiB_Coder over 2 years
    @CapelliC: As discussed in the other answers, if you write out() << "Hello\n", it will print when out is destroyed (e.g. at the end of the program), while out() << "Hello" << endl will print immediately. The c++ standard on the other hand says: endl is equivalent with "\n".
  • muman
    muman about 1 year
    IMHO this is the best answer. If you want to send output to Standard output just use the standard C++ iostream std::cout...