Come stampare su console quando si usa Qt

Sto usando Qt4 e C ++ per fare alcuni programmi in computer grafica. Devo essere in grado di stampare alcune variabili nella mia console in fase di esecuzione, non di debug, ma il cout sembra non funzionare anche se aggiungo le librerie. C’è un modo per fare questo?

Se è sufficiente stampare su stderr , è ansible utilizzare i seguenti flussi originariamente destinati al debug:

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

Sebbene come sottolineato nei commenti, tenere presente che i messaggi qDebug vengono rimossi se viene definito QT_NO_DEBUG_OUTPUT

Se hai bisogno di stdout puoi provare qualcosa di simile (come ha sottolineato Kyle Strand):

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

Potresti quindi chiamare come segue:

 qStdOut() << "std out!"; 

Ho trovato questo più utile:

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

Aggiungi questo al tuo file di progetto:

 CONFIG += console 

Scrivere su stdout

Se vuoi qualcosa che, come std::cout , scriva sullo standard output della tua applicazione, puoi semplicemente fare quanto segue ( credito a CapelliC ):

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

Se si desidera evitare di creare un object QTextStream temporaneo, seguire il suggerimento di Yakk nei commenti sotto di creare una funzione per restituire un handle static per stdout :

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

Ricordarsi di flush periodicamente lo stream per assicurarsi che l'output sia effettivamente stampato.

Scrivendo a stderr

Si noti che la tecnica sopra può essere utilizzata anche per altre uscite. Tuttavia, ci sono modi più leggibili per scrivere su stderr ( credito a Goz e commenti sotto la sua risposta):

 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() è chiuso se QT_NO_DEBUG_OUTPUT è triggersto in fase di compilazione.

(Goz osserva in un commento che per le app non console, queste possono stampare su un stream diverso rispetto a stderr ).


NOTA: Tutti i metodi di stampa Qt presuppongono che gli argomenti const char* siano stringhe codificate ISO-8859-1 con caratteri di terminazione \0 .

Quali variabili vuoi stampare? Se intendi QStrings, quelli devono essere convertiti in c-String. Provare:

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

Ha anche una syntax simile a prinft, ad esempio:

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

Molto utile pure

Vai a Properties -> Linker-> System -> SubSystem del progetto Properties -> Linker-> System -> SubSystem , quindi Properties -> Linker-> System -> SubSystem su Console(/S) .

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

Che dire della libreria iostream inclusa e precisa che cout è un object di std come questo:

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

Se si sta stampando su stderr usando la libreria stdio, una chiamata a fflush(stderr) dovrebbe svuotare il buffer e ottenere la registrazione in tempo reale.

Bene, dopo aver studiato diversi esempi su Internet che descrivono come inviare messaggi da una GUI in Qt a stdout, ho perfezionato un esempio standalone funzionante sul reindirizzamento dei messaggi a una console, tramite qDebug () e installando qInstallMessageHandler (). La console verrà mostrata allo stesso tempo della GUI e può essere nascosta se ritenuto necessario. Il codice è facile da integrare con il codice esistente nel tuo progetto. Ecco il campione completo e sentitevi liberi di utilizzarlo in qualsiasi modo a vostro piacimento, a patto che aderiate alla licenza GNU GPL v2. Devi usare una forma di qualche tipo e una MainWindow credo – altrimenti il ​​campione verrà eseguito, ma probabilmente crash quando forzato ad uscire. Nota: non c’è modo di uscire da un pulsante di chiusura o da un menu chiuso perché ho provato quelle alternative e l’applicazione andrà in crash alla fine di tanto in tanto. Senza il pulsante di chiusura l’applicazione sarà stabile e potrai chiuderla dalla finestra principale. Godere!

 #include "mainwindow.h" #include  //GNU GPL V2, 2015-02-07 #include  #include  #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(); }