Domanda

Utilizzo Qt4 e C++ per realizzare alcuni programmi di computer grafica.Devo essere in grado di stampare alcune variabili nella mia console in fase di esecuzione, non di debug, ma cout non sembra funzionare anche se aggiungo le librerie.C'è un modo per fare questo?

È stato utile?

Soluzione

Se è abbastanza buono per la stampa a stderr, è possibile utilizzare i seguenti flussi originariamente previsto per il debug:

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

Anche se, come sottolineato nei commenti, tenere a mente i messaggi qDebug vengono rimossi se QT_NO_DEBUG_OUTPUT è definito

Se avete bisogno di stdout si potrebbe provare qualcosa di simile (come Kyle Strand ha sottolineato):

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

È quindi possibile chiamare i seguenti:

qStdOut() << "std out!";

Altri suggerimenti

questo più utili:

#include <QTextStream>

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

La scrittura a stdout

Se si desidera qualcosa che, come std::cout, scrive sullo standard output dell'applicazione, si può semplicemente fare la seguente ( credito per CapelliC ):

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

Se si vuole evitare di creare un oggetto QTextStream temporanea, seguire il suggerimento di Yakk nei commenti qui sotto per la creazione di una funzione per restituire un handle static per stdout:

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

...

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

Ricordare per flush flusso periodicamente per garantire la potenza viene stampata.

La scrittura a stderr

Si noti che la tecnica di cui sopra può essere utilizzato anche per altre uscite. Tuttavia, ci sono modi più leggibili a scrivere a stderr ( credito per Goz e commenti qui sotto la sua risposta):

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() è chiuso se QT_NO_DEBUG_OUTPUT è acceso al momento della compilazione.

(note Goz in un commento che per le applicazioni non-console, questi possano stampare su un flusso diverso rispetto stderr.)


Nota: rel Tutti i metodi di stampa Qt Si supponga che gli argomenti "noreferrer" const char* sono ISO-8859-1 stringhe codificate con terminazione caratteri \0.

Aggiungi questo al vostro file di progetto:

CONFIG += console

Quali variabili vuoi stampare? Se vuoi dire QStrings, quelli bisogno di essere convertito in c-Strings. Prova:

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

Properties -> Linker-> System -> SubSystem Vai del progetto, quindi impostarlo Console(/S).

Essa ha anche una sintassi simile a prinft, per esempio:.

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

Molto comodo e

Che dire tra cui libreria iostream e precisa che cout è un oggetto di std in questo modo:

#include <iostream>

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

Se si stampa su stderr utilizzando la libreria stdio, una chiamata a fflush(stderr) dovrebbe svuotare il buffer e si ottiene la registrazione in tempo reale.

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

Bene, dopo aver studiato diversi esempi su Internet che descrivono come inviare messaggi da una GUI in Qt a stdout, ho perfezionato un esempio autonomo funzionante sul reindirizzamento dei messaggi a una console, tramite qDebug() e l'installazione di qInstallMessageHandler().La console verrà mostrata contemporaneamente alla GUI e potrà essere nascosta se ritenuto necessario.Il codice è facile da integrare con il codice esistente nel tuo progetto.Ecco l'esempio completo e sentiti libero di usarlo come preferisci, purché rispetti la licenza GNU GPL v2.Penso che devi usare un modulo di qualche tipo e una finestra principale, altrimenti l'esempio verrà eseguito, ma probabilmente si bloccherà quando costretto a uscire.Nota:non c'è modo di uscire tramite un pulsante di chiusura o una chiusura del menu perché ho testato queste alternative e l'applicazione prima o poi si blocca di tanto in tanto.Senza il pulsante di chiusura l'applicazione sarà stabile e potrai chiuderla dalla finestra principale.Godere!

#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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top