Cómo imprimir en la consola cuando se usa Qt


Estoy usando Qt4 y C++ para hacer algunos programas en gráficos por computadora. Necesito poder imprimir algunas variables en mi consola en tiempo de ejecución, no depurar, pero cout no parece funcionar incluso si agrego las bibliotecas. ¿Hay alguna manera de hacer esto?

 132
Author: Jonathan Leffler, 2010-10-08

11 answers

Si es lo suficientemente bueno para imprimir en stderr, puede usar las siguientes secuencias originalmente destinadas a la depuración:

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

Aunque como se señala en los comentarios, tenga en cuenta que los mensajes qDebug se eliminan si QT_NO_DEBUG_OUTPUT se define

Si necesitas stdout puedes probar algo como esto (como Kyle Strand ha señalado):

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

Entonces podrías llamar de la siguiente manera:

qStdOut() << "std out!";
 161
Author: Goz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-05 07:03:37

Encontré esto más útil:

#include <QTextStream>

QTextStream out(stdout);
foreach(QString x, strings)
    out << x << endl;
 134
Author: CapelliC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-07 20:28:26

Agregue esto a su archivo de proyecto:

CONFIG += console
 27
Author: Kyle Lutz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-08 00:58:19

Escribiendo a stdout

Si desea algo que, como std::cout, escriba en la salida estándar de su aplicación, simplemente puede hacer lo siguiente (crédito a CapelliC):

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

Si desea evitar crear un objeto temporal QTextStream, siga la sugerencia de Yakk en los comentarios a continuación de crear una función para devolver un identificador static para stdout:

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

...

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

Recuerde a flush el flujo periódicamente para asegurarse de que la salida sea realmente impreso.

Escribiendo a stderr

Tenga en cuenta que la técnica anterior también se puede utilizar para otras salidas. Sin embargo, hay formas más legibles de escribir stderr (crédito a Goz y los comentarios debajo de su respuesta):

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() se cierra si QT_NO_DEBUG_OUTPUT está activado en tiempo de compilación.

(Goz señala en un comentario que para aplicaciones que no son de consola, estas pueden imprimirse en una secuencia diferente a stderr.)


NOTA: Todos los métodos de impresión Qt supongamos que const char* argumentos son cadenas codificadas ISO-8859-1 con caracteres terminantes \0.

 24
Author: Kyle Strand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-18 16:28:25

¿Qué variables desea imprimir? Si te refieres a QStrings, estos deben ser convertidos a c-Strings. Try:

std::cout << myString.toAscii().data();
 15
Author: Sebastian Negraszus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-08 00:32:31

También tiene una sintaxis similar a prinft, por ejemplo:

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

Muy útil también

 7
Author: ulitosCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-25 15:30:06

Vaya a Properties -> Linker-> System -> SubSystem del proyecto, luego configúrelo a Console(/S).

 7
Author: Son Vu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-01 14:58:59
#include <QTextStream>
...
qDebug()<<"Bla bla bla";
 1
Author: Amir Twito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-15 13:50:28

¿Qué tal incluir iostream library y precisar que cout es un objeto de std así:

#include <iostream>

std::cout << "Hello" << std::endl;
 1
Author: Emerald Cottet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-14 12:48:29

Si está imprimiendo en stderr utilizando la biblioteca stdio, una llamada a fflush(stderr) debería vaciar el búfer y obtener un registro en tiempo real.

 0
Author: Andrew Prock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-28 18:51:42

Bueno, después de estudiar varios ejemplos en Internet que describen cómo enviar mensajes desde una interfaz gráfica de usuario en Qt a stdout, he refinado un ejemplo independiente de trabajo sobre redirigir mensajes a una consola, a través de qDebug() e instalar qInstallMessageHandler(). La consola se mostrará al mismo tiempo que la GUI y se puede ocultar si se considera necesario. El código es fácil de integrar con el código existente en su proyecto. Aquí está la muestra completa y siéntase libre de usarla de cualquier manera que desee, como siempre y cuando se adhiera a la Licencia GNU GPL v2. Tienes que usar una forma de algún tipo y una ventana principal creo-de lo contrario la muestra se ejecutará, pero probablemente se bloqueará cuando se vea obligado a salir. Nota: no hay forma de salir a través de un botón de cierre o un menú de cierre porque he probado esas alternativas y la aplicación se bloqueará eventualmente de vez en cuando. Sin el botón cerrar la aplicación será estable y puede cerrarla desde la ventana principal. ¡Que lo disfrutes!

#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();
}
 -1
Author: user2178077,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-07 20:20:31