Как печатать на консоли при использовании Qt - программирование

Как печатать на консоли при использовании Qt

Я использую Qt4 и С++ для создания некоторых программ в компьютерной графике. Мне нужно иметь возможность печатать некоторые переменные в моей консоли во время выполнения, а не отладки, но cout не работает, даже если я добавляю библиотеки. Есть ли способ сделать это?

4b9b3361

Ответ 1

Если для печати достаточно 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!";

Ответ 2

Я нашел this наиболее полезным:

#include <QTextStream>

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

Ответ 3

Добавьте это в свой файл проекта:

CONFIG += console

Ответ 4

Запись в stdout

Если вы хотите что-то, что, например, std::cout, записывает на стандартный вывод вашего приложения, вы можете просто следующее (для CapelliC):

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

Вместо создания временного объекта QTextStream (который может вызвать плохое поведение, если другой поток уже открыт для того же дескриптора, в соответствии с Ben Voigt), вы должен действительно следовать предложению Якка в комментариях ниже о создании функции для возврата дескриптора static для stdout:

inline QTextStream& qStdout()
{
    static QTextStream r{stdout};
    return r;
}

...

foreach(QString x, strings)
    qStdout() << x << endl;

Помните - flush поток периодически, чтобы гарантировать, что вывод действительно напечатан.

Запись в 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!

qDebug() закрывается, если QT_NO_DEBUG_OUTPUT включается во время компиляции.

(Заметки Goz в комментарии, что для неконфигурных приложений они могут печатать в другом потоке, чем stderr.)


ПРИМЕЧАНИЕ.. Все методы печати Qt считают, что аргументы const char* являются ISO-8859-1 закодированные строки с завершающими символами \0.

Ответ 5

Какие переменные вы хотите распечатать? Если вы имеете в виду QStrings, они должны быть преобразованы в c-Strings. Попробуйте:

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

Ответ 6

Он также имеет синтаксис, похожий на prinft, например:

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

Очень удобно также

Ответ 7

Перейдите в проект Properties -> Linker-> System -> SubSystem, затем установите его на Console(/S).

Ответ 8

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

Ответ 9

Что касается включения библиотеки iostream и точного определения того, что cout является объектом std следующим образом:

#include <iostream>

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

Ответ 10

Если вы печатаете на stderr, используя библиотеку stdio, вызов fflush(stderr) должен очистить буфер и получить ведение журнала в реальном времени.

Ответ 11

Я попробовал все образцы выше:

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

Спасибо

Ответ 12

Хорошо, после изучения нескольких примеров в Интернете, описывающих, как выводить сообщения из графического интерфейса в Qt в stdout, я уточнил рабочий автономный пример перенаправления сообщений на консоль с помощью qDebug() и установки qInstallMessageHandler(), Консоль будет отображаться одновременно с графическим интерфейсом и может быть скрыта, если сочтет это необходимым. Код легко интегрируется с существующим кодом в вашем проекте. Вот полный образец и не стесняйтесь использовать его каким-либо образом, как вам нравится, если вы придерживаетесь лицензии GNU GPL v2. Вы должны использовать какую-то форму и MainWindow, я думаю - иначе образец будет запущен, но, вероятно, сбой, когда он будет вынужден покинуть. Примечание. Невозможно завершить работу с помощью кнопки закрытия или закрытия меню, потому что я тестировал эти альтернативы, и приложение время от времени ломается. Без кнопки закрытия приложение будет стабильным, и вы можете закрыть его из главного окна. Наслаждайтесь!

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