web-dev-qa-db-fra.com

Comment imprimer sur la console avec Qt

J'utilise Qt4 et C++ pour créer des programmes en infographie. Je dois pouvoir imprimer certaines variables dans ma console au moment de l'exécution, sans déboguer, mais cout ne semble pas fonctionner même si j'ajoute les bibliothèques. Y a-t-il un moyen de faire cela?

145
Zloy Smiertniy

S'il est suffisant d'imprimer sur stderr, vous pouvez utiliser les flux suivants initialement destinés au débogage:

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

Cependant, comme indiqué dans les commentaires, gardez à l'esprit que les messages qDebug sont supprimés si QT_NO_DEBUG_OUTPUT est défini

Si vous avez besoin de stdout, vous pouvez essayer quelque chose comme ceci (comme l'a souligné Kyle Strand):

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

Vous pouvez alors appeler comme suit:

qStdOut() << "std out!";
182
Goz

J'ai trouvé this plus utile:

#include <QTextStream>

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

Ecrire à stdout

Si vous voulez quelque chose qui, comme std::cout, soit écrit sur la sortie standard de votre application, vous pouvez simplement faire ce qui suit ( crédit à CapelliC ):

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

Si vous voulez éviter de créer un objet temporaire QTextStream, suivez la suggestion de Yakk dans les commentaires ci-dessous de créer une fonction pour renvoyer un handle static pour stdout:

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

...

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

N'oubliez pas à flush le flux périodiquement pour vous assurer que le résultat est réellement imprimé.

Ecrire à stderr

Notez que la technique ci-dessus peut également être utilisée pour d'autres sorties. Cependant, il existe des moyens plus lisibles d'écrire dans stderr ( crédit à Goz et les commentaires sous sa réponse):

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() est fermé si QT_NO_DEBUG_OUTPUT est activé à la compilation.

(Dans un commentaire, Goz note que, pour les applications non-console, celles-ci peuvent être imprimées dans un flux différent de stderr.)


REMARQUE: Toutes les méthodes d'impression Qt supposons que const char* arguments sont des chaînes codées ISO-8859-1 avec mettre fin à \0 caractères.

32
Kyle Strand

Ajoutez ceci à votre fichier de projet:

CONFIG += console
30
Kyle Lutz

Quelles variables voulez-vous imprimer? Si vous voulez parler de QStrings, ceux-ci doivent être convertis en c-Strings. Essayer:

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

Allez dans le Properties -> Linker-> System -> SubSystem du projet, puis réglez-le sur Console(/S).

8
Son Vu

Il a également une syntaxe similaire à prinft, par exemple:

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

Très pratique aussi

7
ulitosCoder

Pourquoi ne pas inclure la bibliothèque iostream et préciser que cout est un objet de std comme ceci:

#include <iostream>

std::cout << "Hello" << std::endl;
3
Emerald Cottet
#include <QTextStream>
...
qDebug()<<"Bla bla bla";
1
Amir Twito

Si vous imprimez sur stderr à l'aide de la bibliothèque stdio, un appel à fflush(stderr) devrait vider la mémoire tampon et obtenir une journalisation en temps réel.

1
Andrew Prock

Eh bien, après avoir étudié plusieurs exemples sur Internet décrivant comment sortir des messages d'une interface utilisateur graphique dans Qt sur stdout, j'ai affiné un exemple autonome sur la redirection de messages vers une console, via qDebug () et l'installation de qInstallMessageHandler (). La console sera affichée en même temps que l'interface graphique et peut être masquée si nécessaire. Le code est facile à intégrer au code existant dans votre projet. Voici l'échantillon complet et n'hésitez pas à l'utiliser à votre guise, tant que vous respectez la Licence GNU GPL v2. Vous devez utiliser une forme quelconque et une fenêtre principale, je pense, sinon l'échantillon s'exécutera, mais se plantera probablement lorsqu'il sera forcé de quitter. Remarque: il n'y a aucun moyen de quitter via un bouton de fermeture ou une fermeture de menu car j'ai testé ces alternatives et l'application se plantera éventuellement de temps en temps. Sans le bouton de fermeture, l'application sera stable et vous pourrez la fermer à partir de la fenêtre principale. Prendre plaisir!

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