使用Qt时如何打印到控制台

时间:2010-10-07 21:43:04

标签: c++ qt cout

我正在使用Qt4和C ++在计算机图形学中制作一些程序。我需要能够在运行时在我的控制台中打印一些变量,而不是调试,但即使添加库,cout似乎也不起作用。有没有办法做到这一点?

12 个答案:

答案 0 :(得分:176)

如果打印到stderr足够好,您可以使用以下用于调试的流:

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

虽然在评论中指出,但请记住,如果QT_NO_DEBUG_OUTPUT已定义,则删除qDebug消息

如果你需要stdout,你可以尝试这样的事情(正如Kyle Strand指出的那样):

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

然后你可以按如下方式打电话:

qStdOut() << "std out!";

答案 1 :(得分:141)

我发现this最有用:

#include <QTextStream>

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

答案 2 :(得分:29)

写入stdout

如果您想要某些内容(例如std::cout)写入应用程序的标准输出,则只需执行the followingcredit to CapelliC):

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

如果您想避免创建临时QTextStream对象,请在下面的评论中按照Yakk的建议创建一个函数来返回static的{​​{1}}句柄:

stdout

定期

记住inline QTextStream& qStdout() { static QTextStream r{stdout}; return r; } ... foreach(QString x, strings) qStdout() << x << endl; 流,以确保实际打印输出。

写入flush

请注意,上述技术也可用于其他输出。但是,有更多可读方式可以写入stderrcredit to Goz以及其答案下面的评论):

stderr
如果在编译时打开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()将会关闭。

(Goz在评论中指出,对于非控制台应用,这些应用可以打印到与QT_NO_DEBUG_OUTPUT不同的流。)


注意:所有Qt打印方法assume that const char* arguments都是ISO-8859-1编码的字符串,其中包含终止stderr个字符。

答案 3 :(得分:28)

将其添加到项目文件中:

CONFIG += console

答案 4 :(得分:16)

您想要打印哪些变量?如果你的意思是QStrings,那些需要转换为c-Strings。尝试:

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

答案 5 :(得分:8)

转到项目的Properties -> Linker-> System -> SubSystem,然后将其设置为Console(/S)

答案 6 :(得分:7)

它的语法类似于prinft,例如:

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

非常方便

答案 7 :(得分:2)

包括 iostream库以及 cout std 的对象,如下所示:

        MySqlConnection gSQLConnection;
        MySqlCommand sqlCommand;
        MySqlDataReader sqlReader;

        summaryPortfolioStats stats = new summaryPortfolioStats();

        gSQLConnection = new MySqlConnection(sdbConn);
        sqlCommand = new MySqlCommand("LH_GetPortfolioStatsFromIndexAssets", gSQLConnection);
        sqlCommand.CommandType = CommandType.StoredProcedure;
        sqlCommand.Parameters.Clear();
        MySqlParameter sqlParameter = sqlCommand.Parameters.Add(new MySqlParameter("InIdx_i", MySqlDbType.Int32));
        sqlParameter.Value = iIndex;
        sqlParameter = sqlCommand.Parameters.Add(new MySqlParameter("InStart_i", MySqlDbType.Int32));
        sqlParameter.Value = iStartAsset;
        sqlParameter = sqlCommand.Parameters.Add(new MySqlParameter("InEnd_i", MySqlDbType.Int32));
        sqlParameter.Value = iEndAsset;

        gSQLConnection.Open();
        sqlReader = sqlCommand.ExecuteReader();

答案 8 :(得分:1)

如果使用stdio库打印到stderr,则调用fflush(stderr)应该刷新缓冲区并让您实时记录。

答案 9 :(得分:1)

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

答案 10 :(得分:0)

好吧,在互联网上研究了几个描述如何从Qt中的GUI输出消息到stdout的例子后,我已经改进了一个独立的工作例子,通过qDebug()和安装qInstallMessageHandler()将消息重定向到控制台。 。控制台将与GUI同时显示,并在必要时隐藏。代码很容易与项目中的现有代码集成。以下是完整的示例,只要您遵守许可证GNU GPL v2,就可以随意使用它。您必须使用某种形式和我认为的MainWindow - 否则样本将运行,但可能在被迫退出时崩溃。注意:没有办法通过关闭按钮或关闭菜单退出,因为我已经测试了这些替代方案,应用程序最终会不时崩溃。如果没有关闭按钮,应用程序将保持稳定,您可以从主窗口关闭它。享受!

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

答案 11 :(得分:0)

“构建并运行”>“在终端中运行”的默认设置->启用

使用以下命令刷新缓冲区-> fflush(stdout); 您还可以在printfcout中使用“ \ n”。