コンピューターグラフィックスでいくつかのプログラムを作成するためにQt4とC++を使用しています。デバッグではなく、実行時にコンソールにいくつかの変数を出力できる必要がありますが、ライブラリを追加してもcout
は機能しないようです。これを行う方法はありますか?
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!";
this が最も便利だとわかりました:
#include <QTextStream>
QTextStream out(stdout);
foreach(QString x, strings)
out << x << endl;
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;
Rememberを定期的にflush
に出力して、出力が実際に印刷されるようにします。
stderr
への書き込み上記の手法は、他の出力にも使用できることに注意してください。ただし、stderr
に書き込むより読みやすい方法があります( Gozにクレジット および彼の答えの下のコメント):
qDebug() << "Debug Message"; // CAN BE REMOVED AT COMPILE TIME!
qWarning() << "Warning Message";
qCritical() << "Critical Error Message";
qFatal("Fatal Error Message"); // WILL KILL THE PROGRAM!
コンパイル時にQT_NO_DEBUG_OUTPUT
がオンになっている場合、qDebug()
は閉じられます。
(Gozは、非コンソールアプリの場合、stderr
とは異なるストリームに印刷できるとコメントで述べています。)
注:すべてのQt印刷メソッド const char*
引数を想定 は、終端の\0
文字を含むISO-8859-1エンコード文字列です。
これをプロジェクトファイルに追加します。
CONFIG += console
どの変数を印刷しますか? QStringsを意味する場合、それらをc-Stringsに変換する必要があります。試してください:
std::cout << myString.toAscii().data();
プロジェクトのProperties -> Linker-> System -> SubSystem
に移動し、Console(/S)
に設定します。
また、prinftに似た構文もあります。
qDebug ("message %d, says: %s",num,str);
非常に便利です
iostream libraryとcoutがstdのオブジェクトであると正確に含めることはどうですか:
#include <iostream>
std::cout << "Hello" << std::endl;
#include <QTextStream>
...
qDebug()<<"Bla bla bla";
Stdioライブラリを使用してstderrに出力する場合、fflush(stderr)
を呼び出すと、バッファーがフラッシュされ、リアルタイムのログが取得されます。
さて、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();
}