Как печатать на консоль при использовании Qt
Я использую Qt4 и C++ для создания некоторых программ в компьютерной графике. Мне нужно иметь возможность печатать некоторые переменные в моей консоли во время выполнения, а не отладки, но cout не работает даже если я добавляю библиотеки. Есть ли способ сделать это?
11 ответов:
если это достаточно хорошо для печати
stderr, вы можете использовать следующие потоки, первоначально предназначенные для отладки://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" );хотя, как указано в комментариях, имейте в виду, что сообщения qDebug удаляются, если
QT_NO_DEBUG_OUTPUTопределенЕсли вам нужен stdout, вы можете попробовать что-то вроде этого (как указал Кайл Стрэнд):
QTextStream& qStdOut() { static QTextStream ts( stdout ); return ts; }затем вы можете позвонить следующим образом:
qStdOut() << "std out!";
нашел этой самые полезные:
#include <QTextStream> QTextStream out(stdout); foreach(QString x, strings) out << x << endl;
пишу
stdoutесли вы хотите что-то, что нравится
std::cout, пишет в стандартный вывод вашего приложения, вы можете просто сделать следующее (заслуга капеллы):QTextStream(stdout) << "string to print" << endl;если вы хотите избежать создания временного
QTextStreamобъект, следуйте предложению якка в комментариях ниже о создании функции для возвратаstaticдескрипторstdout:inline QTextStream& qStdout() { static QTextStream r{stdout}; return r; } ... foreach(QString x, strings) qStdout() << x << endl;
помните to
flushпоток периодически для того чтобы обеспечить выход фактически напечатан.пишу
stderrобратите внимание, что вышеописанный метод также может быть использован для других выходов. Однако есть более читаемые способы записи в
stderr(кредит в ГОЗ и комментарии под его ответом):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()закрыт, еслиQT_NO_DEBUG_OUTPUTвключается во время компиляции.(Goz отмечает в комментарии, что для неконсольных приложений эти может печатать в другой поток, чем
stderr.)
Примечание: все методы печати Qt предположим, что
const char*аргументы кодируются строки ISO-8859-1 с окончаниемсимволы.
какие переменные вы хотите печатать? Если вы имеете в виду QStrings, они должны быть преобразованы в C-строки. Попробуйте:
std::cout << myString.toAscii().data();
Он также имеет синтаксис, подобный prinft, например:
qDebug ("message %d, says: %s",num,str);очень удобно, а также
Как насчет включения библиотека iostream и точны, что cout объект std такой :
#include <iostream> std::cout << "Hello" << std::endl;
Если вы печатаете в stderr с помощью библиотеки stdio, вызовите
fflush(stderr)следует очистить буфер и получить вас в режиме реального времени регистрации.
Ну, после изучения нескольких примеров в Интернете, описывающих, как выводить сообщения из графического интерфейса в Qt в stdout, я уточнил рабочий автономный пример перенаправления сообщений на консоль через qDebug() и установку qInstallMessageHandler(). Консоль будет отображаться одновременно с графическим интерфейсом и может быть скрыта, если это необходимо. Код легко интегрировать с существующим кодом в вашем проекте. Вот полный образец и не стесняйтесь использовать его в любом случае, как вам нравится, как пока вы придерживаетесь лицензии GNU GPL v2. Вы должны использовать какую - то форму и главное окно, я думаю, - иначе образец будет работать, но, вероятно, сбой при принудительном выходе. Примечание: нет никакого способа выйти с помощью кнопки закрытия или меню закрыть, потому что я проверил эти альтернативы, и приложение будет аварийно завершать работу в конечном итоге время от времени. Без кнопки закрытия приложение будет стабильным, и вы можете закрыть его из главного окна. Наслаждайтесь!
#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(); }