如何使用Qt打印到控制台

我正在使用Qt4和C ++在计算机graphics学中制作一些程序。 我需要能够在运行时在控制台中打印一些variables,而不是debugging,但即使添加库, cout也不起作用。 有没有办法做到这一点?

如果可以打印到stderr ,则可以使用最初用于debugging的以下stream:

 //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" ); 

虽然正如在注释中指出的那样,请记住,如果定义了QT_NO_DEBUG_OUTPUT,则会删除qDebug消息

如果你需要stdout你可以尝试这样的事情(正如Kyle Strand指出的那样):

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

你可以打电话如下:

 qStdOut() << "std out!"; 

我发现这个最有用:

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

将其添加到您的项目文件中:

 CONFIG += console 

写入stdout

如果你想要的东西,如std::cout ,写入你的应用程序的标准输出,你可以简单地做到以下几点 ( 信贷给CapelliC ):

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

而不是创build一个临时的QTextStream对象( 根据Ben Voigt的说法,如果另一个stream已经对同一个描述符打开,会导致不良的行为),你应该真的按照Yakk的build议创build一个函数来返回一个static句柄stdout

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

请记得定期flushstream,以确保输出实际上是打印的。

写给stderr

请注意,上述技术也可用于其他输出。 然而,有更多可读的方式写给stderr ( 信用Goz和他的答案下面的评论):

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

如果在编译时打开QT_NO_DEBUG_OUTPUT则closuresqDebug()

(Goz在评论中指出,对于非控制台应用程序,这些应用程序可以打印到不同于stderrstream。)


注意:所有的Qt打印方法都假定const char*参数是ISO-8859-1编码的string,终止\0字符。

你想打印哪些variables? 如果你的意思是QStrings,那些需要转换为c-Strings。 尝试:

 std::cout << myString.toAscii().data(); 

它也有一个类似于prinft的语法,例如:

 qDebug ("message %d, says: %s",num,str); 

非常方便

转到项目的Properties -> Linker-> System -> SubSystem ,然后将其设置为Console(/S)

 #include <QTextStream> ... qDebug()<<"Bla bla bla"; 

包括iostream库和精确的coutstd的一个对象是这样的:

 #include <iostream> std::cout << "Hello" << std::endl; 

如果使用stdio库打印到stderr,则调用fflush(stderr)应该刷新缓冲区并获得实时日志logging。

我尝试了上面的所有示例:

 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" ); 

除了qDebug()之外的所有显示; 找不到QT_NO_DEBUG可能被调用的地方。 qDebug()为我工作得很好,但与Ubuntu 17.10消失

谢谢

那么,在研究了一些在Internet上描述如何从Qt中的GUI输出消息到stdout的示例之后,我已经通过qDebug()和安装qInstallMessageHandler()将一个独立工作的例子重新定向到控制台。 控制台将与GUI同时显示,如果认为有必要,可以隐藏。 该代码很容易与您的项目中的现有代码集成。 这里是完整的示例,只要您遵守GNU GPL v2许可证,就可以随意使用它。 你必须使用某种forms的窗体和我想的MainWindow,否则该示例将运行,但在被迫退出时可能会崩溃。 注意:没有办法通过closuresbutton或菜单closures退出,因为我已经testing了这些替代品,并且应用程序最终会随时崩溃。 没有closuresbutton的应用程序将是稳定的,你可以从主窗口closures它。 请享用!

 #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(); }