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?
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!";
I found this most useful:
#include <QTextStream>
QTextStream out(stdout);
foreach(QString x, strings)
out << x << endl;
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). –
Metathesize 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? –
Dispose qDebug() << widget->geometry();
v. out << widget->geometry().x() << ", " << widget->geometry().y() //....
–
Lethargy Add this to your project file:
CONFIG += console
qmake
. –
Metathesize 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.
QTextStream qStdout() { static QTextStream r{stdout}; return r; }
? –
Dispose 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
). –
Inessential stdout
isn't from a namespace, which I'd been wondering but hadn't looked into. –
Metathesize <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. –
Inessential 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, .... )
. –
Metathesize BIND_MEMBER_TO_THIS(myMemberFunc)
much more readable than BindMemberToPtr(this, &MyClass::myMemberFunc)
. –
Metathesize 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. –
Metathesize 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. –
Inessential 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. –
Metathesize qStdout
with QTextStream(stdout)
it works, so static initialization is probably a bad idea. –
Terresaterrestrial QTextStream
constructor it started working. I do not understand what do you mean by flushing the stream. –
Terresaterrestrial 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()
. –
Metathesize flush
the streams. If you are still having difficulties, feel free to remove your upvote (votes are unlocked when a post is edited). –
Metathesize QTextStream
objects. Edited. –
Metathesize 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();
#include <iostream>
–
Anemia myString.toUtf8().data()
is better because it prints Characters outside the ascii range. Chinese characters for example –
Feola It also has a syntax similar to prinft, e.g.:
qDebug ("message %d, says: %s",num,str);
Very handy as well
Go the Project's Properties -> Linker-> System -> SubSystem
, then set it to Console(/S)
.
What about including iostream library and precise that cout is an object of std like this :
#include <iostream>
std::cout << "Hello" << std::endl;
If you are printing to stderr using the stdio library, a call to fflush(stderr)
should flush the buffer and get you real-time logging.
For Qt5 QString must be converted, for example:
QString sResultText = lblLineEdit->text(); //<--text from QLineEdit
qInfo(sResultText.toUtf8().data()); //<--show converted result
Well, after studying several examples on the Internet describing how to output messages from a GUI in Qt to stdout, I have refined a working stand-alone example on redirecting messages to a console, via qDebug() and installing qInstallMessageHandler(). The console will be showed at the same time as the GUI and can be hidden if deemed necessary. The code is easy to integrate with existing code in your project. Here is the full sample and feel free to use it in any way as you like, as long as you adhere to the License GNU GPL v2. You have to use a form of some sort and a MainWindow I think - otherwise the sample will run, but probably crash when forced to quit. Note: there is no way to quit via a close button or a menu close because I have tested those alternatives and the application will crash eventually every now and then. Without the close button the application will be stable and you can close it down from the main window. Enjoy!
#include "mainwindow.h"
#include <QApplication>
//GNU GPL V2, 2015-02-07
#include <QMessageBox>
#include <windows.h>
#define CONSOLE_COLUMNS 80
#define CONSOLE_ROWS 5000
#define YOURCONSOLETITLE "Your_Console_Title"
typedef struct{
CONSOLE_SCREEN_BUFFER_INFOEX conScreenBuffInfoEX;
HANDLE con_screenbuf;
HWND hwndConsole;
HMENU consoleMenu ;
QString consoleTitle;
QMessageBox mBox;
QString localMsg;
QString errorMessage;
WINBOOL errorCode;
} consoleT;
static consoleT *console;
BOOL WINAPI catchCTRL( DWORD ctrlMsg ){
if( ctrlMsg == CTRL_C_EVENT ){
HWND hwndWin = GetConsoleWindow();
ShowWindow(hwndWin,SW_FORCEMINIMIZE);
}
return TRUE;
}
void removeCloseMenu(){
int i;
for( i = 0; i < 10; i++){
console->hwndConsole = FindWindowW( NULL, console->consoleTitle.toStdWString().data());
if(console->hwndConsole != NULL)
break;
}
if( !(console->errorCode = 0) && (console->hwndConsole == NULL))
console->errorMessage += QString("\nFindWindowW error: %1 \n").arg(console->errorCode);
if( !(console->errorCode = 0) && !(console->consoleMenu = GetSystemMenu( console->hwndConsole, FALSE )) )
console->errorMessage += QString("GetSystemMenu error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = DeleteMenu( console->consoleMenu, SC_CLOSE, MF_BYCOMMAND )))
console->errorMessage += QString("DeleteMenu error: %1 \n").arg(console->errorCode);
}
void initialiseConsole(){
console->conScreenBuffInfoEX.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
console->consoleMenu = NULL;
console->consoleTitle = YOURCONSOLETITLE;
console->con_screenbuf = INVALID_HANDLE_VALUE;
console->errorCode = 0;
console->errorMessage = "";
console->hwndConsole = NULL;
console->localMsg = "";
if(!(console->errorCode = FreeConsole()))
console->errorMessage += QString("\nFreeConsole error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = AllocConsole()))
console->errorMessage += QString("\nAllocConsole error: %1 \n").arg(console->errorCode);
if( (console->errorCode = -1) && (INVALID_HANDLE_VALUE ==(console->con_screenbuf = CreateConsoleScreenBuffer( GENERIC_WRITE | GENERIC_READ,0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL))))
console->errorMessage += QString("\nCreateConsoleScreenBuffer error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = SetConsoleActiveScreenBuffer(console->con_screenbuf)))
console->errorMessage += QString("\nSetConsoleActiveScreenBuffer error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = GetConsoleScreenBufferInfoEx(console->con_screenbuf, &console->conScreenBuffInfoEX)))
console->errorMessage += QString("\nGetConsoleScreenBufferInfoEx error: %1 \n").arg(console->errorCode);
console->conScreenBuffInfoEX.dwSize.X = CONSOLE_COLUMNS;
console->conScreenBuffInfoEX.dwSize.Y = CONSOLE_ROWS;
if(!(console->errorCode = SetConsoleScreenBufferInfoEx(console->con_screenbuf, &console->conScreenBuffInfoEX)))
console->errorMessage += QString("\nSetConsoleScreenBufferInfoEx error: %1 \n").arg(console->errorCode);
if(!(console->errorCode = SetConsoleTitleW(console->consoleTitle.toStdWString().data())))
console->errorMessage += QString("SetConsoleTitle error: %1 \n").arg(console->errorCode);
SetConsoleCtrlHandler(NULL, FALSE);
SetConsoleCtrlHandler(catchCTRL, TRUE);
removeCloseMenu();
if(console->errorMessage.length() > 0){
console->mBox.setText(console->errorMessage);
console->mBox.show();
}
}
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg){
if((console->con_screenbuf != INVALID_HANDLE_VALUE)){
switch (type) {
case QtDebugMsg:
console->localMsg = console->errorMessage + "Debug: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
break;
case QtWarningMsg:
console->localMsg = console->errorMessage + "Warning: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length() , NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
break;
case QtCriticalMsg:
console->localMsg = console->errorMessage + "Critical: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
break;
case QtFatalMsg:
console->localMsg = console->errorMessage + "Fatal: " + msg;
WriteConsoleW(console->con_screenbuf, console->localMsg.toStdWString().data(), console->localMsg.toStdWString().length(), NULL, NULL );
WriteConsoleA(console->con_screenbuf, "\n--\n", 4, NULL, NULL );
abort();
}
}
}
int main(int argc, char *argv[])
{
qInstallMessageHandler(messageHandler);
QApplication a(argc, argv);
console = new consoleT();
initialiseConsole();
qDebug() << "Hello World!";
MainWindow w;
w.show();
return a.exec();
}
"build & run" > Default for "Run in terminal" --> Enable
to flush the buffer use this command --> fflush(stdout);
you can also use "\n" in printf
or cout
.
© 2022 - 2024 — McMap. All rights reserved.
error: ‘cout’ was not declared in this scope
; with iostream, I geterror: 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. – HarmonistQString
). – Nineteenth