Pregunta

Estoy usando Qt4 y C ++ para la fabricación de algunos programas de gráficos por ordenador. Tengo que ser capaz de imprimir algunas variables en mi consola en tiempo de ejecución, no la depuración, pero cout no parece trabajo, incluso si añado las bibliotecas. ¿Hay una manera de hacer esto?

¿Fue útil?

Solución

Si es lo suficientemente bueno para imprimir en stderr, puede utilizar los siguientes flujos originalmente destinados a la depuración:

#include<QDebug>

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

A pesar de lo señalado en los comentarios, tenga en mente los mensajes qDebug se eliminan si se define QT_NO_DEBUG_OUTPUT

Si necesita stdout usted podría intentar algo como esto (como Kyle Strand ha señalado):

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

A continuación, puede llamar a los siguientes:

qStdOut() << "std out!";

Otros consejos

este más útil:

#include <QTextStream>

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

Escritura a stdout

Si usted quiere algo que, al igual que std::cout, escribe en la salida estándar de su aplicación, se puede hacer simplemente la siguiente ( crédito para CapelliC ):

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

Si se quiere evitar la creación de un objeto QTextStream temporal, seguir la sugerencia de Yakk en los comentarios de abajo de la creación de una función para devolver un mango static para stdout:

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

...

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

Recuerde para flush la corriente periódicamente para asegurar la salida se imprime realmente.

Escritura a stderr

Tenga en cuenta que la técnica anterior también se puede utilizar para otras salidas. Sin embargo, hay maneras más fáciles de leer escribir en stderr ( de crédito a Goz y los comentarios a continuación 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 se enciende en tiempo de compilación.

(Goz notas en un comentario que para las aplicaciones no-consola, estos pueden imprimir en una corriente diferente a stderr.)


Nota: rel Todos los métodos de impresión Qt asumir que los argumentos const char* son ISO-8859-1 cadenas codificadas con la terminación de caracteres \0.

Añadir esto a su archivo de proyecto:

CONFIG += console

¿Qué variables es lo que desea imprimir? Si se refiere a QStrings, aquellos deben ser convertidos a c-Cuerdas. Proveedores:

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

Ir Properties -> Linker-> System -> SubSystem del Proyecto, luego otra vez en Console(/S).

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

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

Muy práctico, así

¿Qué hay de incluir biblioteca iostream y precisa que cout es un objeto de std como esto:

#include <iostream>

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

Si está imprimiendo a stderr usando la biblioteca stdio, una llamada a fflush(stderr) debe vaciar el búfer y se obtiene el registro en tiempo real.

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

Bueno, después de estudiar varios ejemplos en Internet que describe cómo los mensajes de salida de una interfaz gráfica de usuario en Qt a la salida estándar, he refinado un ejemplo autónomo de trabajo sobre redirigir mensajes a una consola, a través de qDebug () y la instalación de qInstallMessageHandler () . La consola se mostró al mismo tiempo que la interfaz gráfica de usuario 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 no dude en utilizarlo en cualquier forma que se desee, siempre y cuando se adhieran a la GNU GPL v2. Usted tiene que utilizar una forma de algún tipo y un MainWindow creo - de lo contrario la muestra se ejecutará, pero probablemente bloquearse cuando se ven obligados a dejar de fumar. Nota: no hay manera de dejar de fumar a través de un botón de cierre o un menú de cerca porque he probado esas alternativas y la aplicación se bloqueará el tiempo de vez en cuando. Sin el botón de cerrar la aplicación será estable y se puede cerrar hacia abajo desde la ventana principal. Disfrutar!

#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();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top