Вам нужно установить обработчик сообщений с помощью qInstallMsgHandler
функции, а затем вы можете использовать его QTextStream
для записи отладочного сообщения в файл. Вот примерный пример:
#include <QtGlobal>
#include <stdio.h>
#include <stdlib.h>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
}
int main(int argc, char **argv)
{
qInstallMessageHandler(myMessageOutput);
QApplication app(argc, argv);
...
return app.exec();
}
Взято из документа qInstallMsgHandler
(я только добавил комментарии):
В приведенном выше примере myMessageOutput
используется функция, stderr
которую вы, возможно, захотите заменить каким-либо другим файловым потоком или полностью переписать функцию!
После того, как вы пишете , и установить эту функцию, все ваши qDebug
(а также qWarning
, и qCritical
т.д.) сообщения будут перенаправлены в файл вы пишете в обработчике.
qDebug
,qWarning
,qCritical
и так далее!qInstallMsgHandler
устарел и замененqInstallMessageHandler
(той же идеей) в Qt5. Версия 5.0qInstallMsgHandler
находится на qt-project.org/doc/qt-5.0/qtcore/… иqInstallMessageHandler
тоже там есть. Для 5.1qInstallMsgHandler
был удален полностью.void myMessageOutput(QtMsgType type, const char *msg) { ... }
От сюда все заслуга духа .
#include <QApplication> #include <QtDebug> #include <QFile> #include <QTextStream> void myMessageHandler(QtMsgType type, const QMessageLogContext &, const QString & msg) { QString txt; switch (type) { case QtDebugMsg: txt = QString("Debug: %1").arg(msg); break; case QtWarningMsg: txt = QString("Warning: %1").arg(msg); break; case QtCriticalMsg: txt = QString("Critical: %1").arg(msg); break; case QtFatalMsg: txt = QString("Fatal: %1").arg(msg); break; } QFile outFile("log"); outFile.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream ts(&outFile); ts << txt << endl; } int main( int argc, char * argv[] ) { QApplication app( argc, argv ); qInstallMessageHandler(myMessageHandler); ... return app.exec(); }
источник
qInstallMessageHandler
следует использовать вместоqInstallMsgHandler
изменения обработчика сообщений.Вот рабочий пример подключения обработчика сообщений по умолчанию.
Спасибо, @Ross Rogers!
// -- main.cpp // Get the default Qt message handler. static const QtMessageHandler QT_DEFAULT_MESSAGE_HANDLER = qInstallMessageHandler(0); void myCustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { // Handle the messages! // Call the default handler. (*QT_DEFAULT_MESSAGE_HANDLER)(type, context, msg); } int main(int argc, char *argv[]) { qInstallMessageHandler(myCustomMessageHandler); QApplication a(argc, argv); qDebug() << "Wello Horld!"; return 0; }
источник
Вот кроссплатформенное решение для входа в консоль, если приложение было запущено из Qt Creator, и в
debug.log
файл, когда он компилируется и запускается как отдельное приложение.main.cpp :
#include <QApplication> #include <QtGlobal> #include <QtDebug> #include <QTextStream> #include <QTextCodec> #include <QLocale> #include <QTime> #include <QFile> const QString logFilePath = "debug.log"; bool logToFile = false; void customMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QHash<QtMsgType, QString> msgLevelHash({{QtDebugMsg, "Debug"}, {QtInfoMsg, "Info"}, {QtWarningMsg, "Warning"}, {QtCriticalMsg, "Critical"}, {QtFatalMsg, "Fatal"}}); QByteArray localMsg = msg.toLocal8Bit(); QTime time = QTime::currentTime(); QString formattedTime = time.toString("hh:mm:ss.zzz"); QByteArray formattedTimeMsg = formattedTime.toLocal8Bit(); QString logLevelName = msgLevelHash[type]; QByteArray logLevelMsg = logLevelName.toLocal8Bit(); if (logToFile) { QString txt = QString("%1 %2: %3 (%4)").arg(formattedTime, logLevelName, msg, context.file); QFile outFile(logFilePath); outFile.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream ts(&outFile); ts << txt << endl; outFile.close(); } else { fprintf(stderr, "%s %s: %s (%s:%u, %s)\n", formattedTimeMsg.constData(), logLevelMsg.constData(), localMsg.constData(), context.file, context.line, context.function); fflush(stderr); } if (type == QtFatalMsg) abort(); } int main(int argc, char *argv[]) { QByteArray envVar = qgetenv("QTDIR"); // check if the app is ran in Qt Creator if (envVar.isEmpty()) logToFile = true; qInstallMessageHandler(customMessageOutput); // custom message handler for debugging QApplication a(argc, argv); // ...and the rest of 'main' follows
Форматирование журнала обрабатывается
QString("%1 %2: %3 (%4)").arg...
(для файла) иfprintf(stderr, "%s %s: %s (%s:%u, %s)\n"...
(для консоли).Вдохновение: https://gist.github.com/polovik/10714049 .
источник
Что ж, я бы сказал, что момент, когда вам нужно перенаправить вывод отладки на что-то другое, кроме stderr, - это когда вы можете подумать о каком-нибудь инструменте ведения журнала. Если вы чувствуете, что он вам нужен, я бы рекомендовал использовать
QxtLogger
( «Класс QxtLogger - простой в использовании, легко расширяемый инструмент ведения журнала.» ) ИзQxt
библиотеки.источник
Вот простой, потокобезопасный идиоматический пример Qt для входа
stderr
и файла:Установите его,
qInstallMessageHandler(messageHandler)
как описано в других ответах.источник