Qtを使用しているときにコンソールに出力する方法


159

コンピューターグラフィックスでいくつかのプログラムを作成するためにQt4とC ++を使用しています。デバッグでcoutはなく実行時にいくつかの変数をコンソールに出力できるようにする必要がありますが、ライブラリを追加しても機能しないようです。これを行う方法はありますか?


3
それが確かに機能するはずなので、機能しないcoutについて詳しく説明できますか?コンパイルエラーが発生しますか?うまくいかないcoutのコード例を見せていただけますか?また、アプリケーションの実行方法も説明します。コンソールまたはIDE内から実行していて、出力ウィンドウへの出力が表示されていませんか?
アーノルドスペンス

完全を期すために:@ArnoldSpence-ライブラリなしでは、私はerror: ‘cout’ was not declared in this scope; iostreamを使用するとerror: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char>&)(& std::cout)), ...、代わりに回答のコマンドを使用すると正常に機能します。
sdaau

問題文が単に「動かない」というだけの場合、解決策を提供することは困難です。してください編集あなたはどのように異なるの実際の結果から起こるとすると予想何のより完全な説明を与えるためにあなたの質問を。何が良い説明をするかについてのヒントを求める方法を参照してください。
Toby Speight 2017

この場合、それらの「変数」がQt固有のオブジェクト(などQString)であることを明示的に指定する必要があります。
user202729

回答:


203

に出力するのに十分であれば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" );

コメントで指摘されていますが、qDebugメッセージがQT_NO_DEBUG_OUTPUT定義されている場合は削除されることに注意してください

stdoutが必要な場合は、次のようなものを試すことができます(カイルストランドが指摘したとおり)。

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

その後、次のように呼び出すことができます。

qStdOut() << "std out!";

1
デバッグはしていませんが、デバッグではなく実行時にコンソールにメッセージを書き込むことができる機能が必要です。
lesolorzanov

11
その名前にもかかわらず、その関数はデバッガーでのデバッグに関連していません。これはQtが出力をstderrに送信するために提供する便利な関数で、defineを使用してコンパイルから削除できます。したがって、実行時にコンソールへの出力を実現するための代替手段です。
アーノルドスペンス

どうもありがとう、私はこれを使っています:)。その時、私が使用したコードを書く必要はないと思います。ありがとう!これは非常に便利です。
lesolorzanov 2010年

51
#include <QDebug>
ducky

62
すべてのコンソール出力にqDebugを使用しないでください。真のデバッグ出力にのみ使用し、エラーと警告にはqWarning、qCritical、qFatalを使用します。これは、QT_NO_DEBUG_OUTPUTでコンパイルするときにqDebugステートメントを削除して、パフォーマンスを節約し、アプリケーションが出力を乱雑にしないようにするためです。
JustMaximumPower

150

私はこれが最も便利だと思いました:

#include <QTextStream>

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

14
なぜ答えが受け入れられないのかはわかりませんが、確かにそれが最も役に立ちます。
Semyon Danilov 2014

4
同意した。stderrは、エラー(およびデバッグ)のためのものです。stdoutとqtを使用するのはこれだけなので、これは受け入れられる答えになるはずです。
マーシャルユーバンクス2014

1
これは私にとってはうまくいきました-そしてcout経由で情報を出力する正しい方法のように見えました
Michael Vincent

2
エラー/警告を印刷する方法に関するGozの回答の情報と、qDebug()実際に何が行われるかについての少しの情報(Gozの回答には欠けているが、その下のコメントにある)を組み込むと、これははるかに優れた回答になります(IMOは、OPが何かを置き換えることを求めているためstd::cout、すでに優れていますが、40人の有権者が同意していないようです)。
カイルストランド

QTextStream qStdout() { return {stdout}; }これをラップするqWarning()など、一貫性のある便利な方法かもしれません。そしてstatic、一時的なストリーミングを回避するためのいくつかの状態ですか?
Yakk-Adam Nevraumont 2015年

36

への書き込み stdout

などstd::cout、アプリケーションの標準出力に書き込むものが必要な場合は、次の操作を行うだけです(CapelliCの功績です)。

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

一時QTextStreamオブジェクトの作成を避けたい場合は、以下のコメントのYakkの提案に従って、のstaticハンドルを返す関数を作成しますstdout

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

...

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

flushストリームを定期的に覚えて、出力が実際に印刷されることを確認してください

への書き込み stderr

上記の手法は他の出力にも使用できます。ただし、より読みやすい方法がありますstderrGozの功績と彼の回答の下のコメント)。

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()QT_NO_DEBUG_OUTPUTコンパイル時にオンになっている場合は閉じられます。

(Gozのコメントには、コンソール以外のアプリでは、とは異なるストリームに出力される可能性があると記載されていますstderr。)


注:すべてのQt印刷メソッドは、const char*引数が終了文字を含むISO-8859-1エンコードされた文字列であることを前提としています\0


1
QTextStream qStdout() { static QTextStream r{stdout}; return r; }
Yakk-Adam Nevraumont 2015年

1
@ヤク良い提案!私は私の答えに組み入れます。
カイルストランド2015年

qFatal()は、QT5でコンパイルするとエラーになります。投稿を読んで、とにかく(そこにいる/仕事する)のは気にならなかった...使用しないでください!:)
relascope

1
@KyleStrandそのための関数を使用できませんか?template <typename C> constexpr typename std::remove_const<typename std::remove_reference<C>::type>::type& no_const(C* c) { return const_cast<typename std::remove_const<typename std::remove_reference<C>::type>::type&>(*c); } 使用: no_const(this).method()。あなたはその関数をメソッドとしてクラスに注入することができ、それから渡す必要すらありませんthisFoo& no_const() const { return ::no_const(this); } タイプミスはありません、私は約束します。
モニカを

1
@Mitch Hm、それらのリンクとQtドキュメントを確認すると、あなたは正しいです。一時QTextStreamオブジェクトによって引き起こされる既知の問題があることを示すものは何もありません。編集。
カイルストランド2017

32

これをプロジェクトファイルに追加します。

CONFIG += console

5
使用されているビルドシステムに関する質問には、情報がありませんでした。これは、を使用する場合にのみ関係しqmakeます。
カイルストランド

19

印刷する変数は何ですか?QStringsを意味する場合は、cStringsに変換する必要があります。試してください:

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

8
@CoderaPurpa追加する必要があります#include <iostream>
Sebastian Negraszus 2012

myString.toUtf8().data()ASCII範囲外の文字を印刷するので、より良いです。漢字の例
peterchaula

8

また、prinftに似た構文もあります。例:

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

とても便利です


8

プロジェクトのProperties -> Linker-> System -> SubSystemに移動し、次にに設定しConsole(/S)ます。


1
これは(Kyle Lutzの答えのように)ビルドシステム固有です。
カイルストランド

3

iostreamライブラリを含めて、coutが次のようなstdのオブジェクトであることを正確に示します。

#include <iostream>

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

1

stdioライブラリを使用してstderrに出力している場合は、への呼び出しでfflush(stderr)バッファをフラッシュし、リアルタイムのロギングを取得する必要があります。



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

0

「ビルドして実行」>「ターミナルで実行」のデフォルト->有効

バッファをフラッシュするには、次のコマンドを使用します-> fflush(stdout); printfまたはで「\ n」を使用することもできますcout

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.