【发布时间】:2012-06-26 10:16:57
【问题描述】:
在 Qt Creator 中,我可以直接在 IDE 中查看qDebug()、qWarning() 等输出。我如何在 Visual Studio 中做到这一点?
【问题讨论】:
标签: visual-studio-2010 visual-studio qt
在 Qt Creator 中,我可以直接在 IDE 中查看qDebug()、qWarning() 等输出。我如何在 Visual Studio 中做到这一点?
【问题讨论】:
标签: visual-studio-2010 visual-studio qt
有一个更简单的方法:
转到项目属性>链接器>系统:将子系统设置为“SUBSYSTEM:CONSOLE”
现在,当您运行程序时,您将获得一个控制台,并且 qDebug() 将被重定向到它。 (也可以使用 std::cout)
【讨论】:
当您使用附加的调试器运行程序时,它将显示在 Visual Studio 的输出窗口中,但出于调试目的,我经常将调试输出重定向到某种漂亮的日志窗口,您可以使用函数来完成qInstallMsgHandler:
我使用的代码:
#include <qapplication.h>
#include <qwidget.h>
#include <qplaintextedit.h>
#include <qmetaobject.h>
#include <qthread.h>
#include <qboxlayout.h>
#include <qdatetime.h>
#include <qdebug.h>
#include <cstdio>
#include <cassert>
QWidget *DEBUG_MESSAGE_DISPLAY_WIDGET = NULL;
QPlainTextEdit *DEBUG_MESSAGE_DISPLAY_TEXTEDIT = NULL;
void setupDebugDisplay();
void debugMessageDisplayFunc(QtMsgType type, const char *msg);
int main( int argc, char* argv[] )
{
QApplication a( argc, argv );
a.setQuitOnLastWindowClosed( true );
setupDebugDisplay();
// your code here.... e.g:
// YourMainWindow mainWindow;
int ret = a.exec();
delete DEBUG_MESSAGE_DISPLAY_WIDGET;
return ret;
}
void setupDebugDisplay()
{
QWidget *widget = new QWidget();
widget->setWindowTitle( "Debug Log" );
widget->setAttribute( Qt::WA_QuitOnClose, false ); //quit only when mainwindow is closed
QBoxLayout* layout = new QVBoxLayout();
widget->setLayout( layout );
QPlainTextEdit *textEdit = new QPlainTextEdit( widget );
QFont font = QFont( "Monospace" );
font.setStyleHint(QFont::TypeWriter);
textEdit->setFont( font );
textEdit->setReadOnly(true);
layout->addWidget( textEdit );
widget->show();
DEBUG_MESSAGE_DISPLAY_WIDGET = widget;
DEBUG_MESSAGE_DISPLAY_TEXTEDIT = textEdit;
qInstallMsgHandler(debugMessageDisplayFunc);
}
void debugMessageDisplayFunc(QtMsgType type, const char *msg)
{
bool do_abort = false;
const char* msgTypeStr = NULL;
switch (type) {
case QtDebugMsg:
msgTypeStr = "Debug";
break;
case QtWarningMsg:
msgTypeStr = "Warning";
break;
case QtCriticalMsg:
msgTypeStr = "Critical";
break;
case QtFatalMsg:
msgTypeStr = "Fatal";
do_abort = true;
default:
assert(0);
return;
}
QTime now = QTime::currentTime();
QString formattedMessage =
QString::fromLatin1("%1 %2 %3")
.arg(now.toString("hh:mm:ss:zzz"))
.arg(msgTypeStr).arg(msg);
// print on console:
fprintf( stderr, "%s\n", formattedMessage.toLocal8Bit().constData() );
// print in debug log window
{
bool isMainThread = QThread::currentThread() == QApplication::instance()->thread();
if(DEBUG_MESSAGE_DISPLAY_TEXTEDIT)
{
if( isMainThread )
DEBUG_MESSAGE_DISPLAY_TEXTEDIT->appendPlainText( formattedMessage );
else // additional code, so that qDebug calls in threads will work aswell
QMetaObject::invokeMethod( DEBUG_MESSAGE_DISPLAY_TEXTEDIT, "appendPlainText", Qt::QueuedConnection, Q_ARG( QString, formattedMessage ) );
}
}
}
【讨论】:
qInstallMsgHandler 已从 Qt 5.0 中弃用,请改用 qInstallMessageHandler:doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandler
重定向到 Visual Studio 的输出窗口。
【讨论】:
您也可以将 DebugView++ 用于 QDebug,它仍然可以使用它
【讨论】:
OutputDebugString 是做到这一点的关键。
我如何使用 Qt 5.15:
#if defined(Q_OS_WIN) && defined(QT_DEBUG)
qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &ctx, const QString &message) {
const QString msg = qFormatLogMessage(type, ctx, message);
// write logs to Output window of Visual Studio
{
QString prefix;
switch (type) {
case QtWarningMsg:
prefix = "[WARNING] ";
break;
case QtCriticalMsg:
prefix = "[CRITICAL ERROR] ";
break;
case QtFatalMsg:
prefix = "[FATAL ERROR] ";
break;
}
auto msgW = QString(prefix + message).toStdWString();
msgW.append(L"\n");
OutputDebugString(msgW.c_str());
}
});
#endif
【讨论】: