web-dev-qa-db-de.com

So drucken Sie in der Konsole, wenn Sie Qt verwenden

Ich verwende Qt4 und C++, um einige Programme in Computergrafiken zu erstellen. Ich muss in der Lage sein, einige Variablen zur Laufzeit in meiner Konsole zu drucken, nicht zu debuggen, aber cout scheint nicht zu funktionieren, selbst wenn ich die Bibliotheken hinzufüge. Gibt es eine Möglichkeit, dies zu tun?

145
Zloy Smiertniy

Wenn es gut genug ist, um auf stderr zu drucken, können Sie die folgenden Streams verwenden, die ursprünglich zum Debuggen vorgesehen waren:

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

Beachten Sie jedoch, dass qDebug-Meldungen entfernt werden, wenn QT_NO_DEBUG_OUTPUT ist definiert

Wenn Sie stdout brauchen, können Sie so etwas ausprobieren (wie Kyle Strand herausgestellt hat):

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

Sie könnten dann wie folgt anrufen:

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

Ich fand this am nützlichsten:

#include <QTextStream>

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

Schreiben an stdout

Wenn Sie etwas möchten, das wie std::cout In die Standardausgabe Ihrer Anwendung schreibt, können Sie einfach das Folgende ( Dank an CapelliC ) :

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

Wenn Sie vermeiden möchten, ein temporäres QTextStream -Objekt zu erstellen, befolgen Sie den Vorschlag von Yakk in den Kommentaren unten, eine Funktion zum Zurückgeben eines static -Handles für stdout zu erstellen:

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

...

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

Denken Sie daran, den Stream regelmäßig zu flush, um sicherzustellen, dass die Ausgabe tatsächlich gedruckt wird.

Schreiben an stderr

Beachten Sie, dass die obige Technik auch für andere Ausgaben verwendet werden kann. Es gibt jedoch besser lesbare Möglichkeiten, an stderr zu schreiben ( Dank an Goz und die Kommentare unter seiner Antwort):

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() wird geschlossen, wenn QT_NO_DEBUG_OUTPUT zur Kompilierungszeit aktiviert ist.

(Goz merkt in einem Kommentar an, dass diese für Nicht-Konsolen-Apps in einem anderen Stream als stderr gedruckt werden können.)


HINWEIS: Alle Qt-Druckmethoden nehmen an, dass const char* - Argumente ISO-8859-1 sind codierte Zeichenfolgen mit abschließenden \0 - Zeichen.

32
Kyle Strand

Fügen Sie dies zu Ihrer Projektdatei hinzu:

CONFIG += console
30
Kyle Lutz

Welche Variablen möchten Sie drucken? Wenn Sie QStrings meinen, müssen diese in c-Strings konvertiert werden. Versuchen:

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

Gehen Sie zum Properties -> Linker-> System -> SubSystem Des Projekts und setzen Sie es auf Console(/S).

8
Son Vu

Es hat auch eine ähnliche Syntax wie prinft, z.

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

Sehr praktisch

7
ulitosCoder

Was ist mit der Einbindung der iostream-Bibliothek und genau das cout ist ein Objekt von std wie folgt:

#include <iostream>

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

Wenn Sie mit der stdio-Bibliothek auf stderr drucken, sollte ein Aufruf von fflush(stderr) den Puffer leeren und Sie in Echtzeit protokollieren.

1
Andrew Prock

Nachdem ich einige Beispiele im Internet studiert habe, in denen beschrieben wird, wie Nachrichten von einer GUI in Qt an stdout ausgegeben werden, habe ich ein eigenständiges Beispiel für die Umleitung von Nachrichten an eine Konsole über qDebug () und die Installation von qInstallMessageHandler () verfeinert. Die Konsole wird gleichzeitig mit der Benutzeroberfläche angezeigt und kann bei Bedarf ausgeblendet werden. Der Code lässt sich leicht in vorhandenen Code in Ihrem Projekt integrieren. Hier finden Sie das vollständige Beispiel. Sie können es nach Belieben verwenden, solange Sie die Lizenz GNU GPL v2) einhalten. Sie müssen eine Art und ein verwenden Ich denke, MainWindow - andernfalls wird das Beispiel ausgeführt, stürzt aber wahrscheinlich ab, wenn es zum Beenden gezwungen wird. Hinweis: Es gibt keine Möglichkeit, über eine Schaltfläche zum Schließen oder ein Menü zum Schließen zu beenden, da ich diese Alternativen getestet habe und die Anwendung gelegentlich abstürzt Ohne die Schaltfläche zum Schließen wird die Anwendung stabil und Sie können sie vom Hauptfenster aus schließen.

#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