在Qt Creator中,我可以直接在IDE中查看qDebug()
, qWarning()
等输出。在Visual Studio中该如何实现呢?
在Qt Creator中,我可以直接在IDE中查看qDebug()
, qWarning()
等输出。在Visual Studio中该如何实现呢?
有一个更简单的方法:
进入项目属性 > 链接器 > 系统: 将子系统设置为"SUBSYSTEM:CONSOLE"
运行程序后,您现在将获得控制台,并且qDebug()将被重定向到其中。(您也可以使用std::cout)
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
:
https://doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandler - Dmytro它会重定向到Visual Studio的输出窗口。
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