Musisz zainstalować program obsługi komunikatów za pomocą qInstallMsgHandler
funkcji, a następnie możesz użyć go QTextStream
do zapisania komunikatu debugowania do pliku. Oto przykładowy przykład:
#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();
}
Zaczerpnięte z dokumentu qInstallMsgHandler
(dodałem tylko komentarze):
W powyższym przykładzie funkcja myMessageOutput
używa, stderr
którą możesz chcieć zastąpić innym strumieniem plików lub całkowicie ponownie napisać funkcję!
Raz piszesz i zainstalować tę funkcję, wszystkie qDebug
(jak również qWarning
, qCritical
etc) wiadomości zostaną przekierowane do pliku piszesz w module obsługi.
qDebug
,qWarning
,qCritical
i tak dalej!qInstallMsgHandler
został przestarzały i zastąpiony przezqInstallMessageHandler
(ten sam pomysł) w Qt5. Wersja 5.0qInstallMsgHandler
jest dostępna pod adresem qt-project.org/doc/qt-5.0/qtcore/ ... i teżqInstallMessageHandler
tam jest. W wersji 5.1qInstallMsgHandler
został całkowicie usunięty.void myMessageOutput(QtMsgType type, const char *msg) { ... }
Od tutaj wszystko zasługa ducha .
#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(); }
źródło
qInstallMessageHandler
zamiastqInstallMsgHandler
zmieniać obsługę komunikatów.Oto działający przykład przechwytywania domyślnego programu obsługi komunikatów.
Dziękuję @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; }
źródło
Oto wieloplatformowe rozwiązanie do logowania się do konsoli, jeśli aplikacja została uruchomiona z Qt Creator, oraz do
debug.log
pliku, gdy jest kompilowana i uruchamiana jako samodzielna aplikacja.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
Formatowanie dziennika jest obsługiwane przez
QString("%1 %2: %3 (%4)").arg...
(dla pliku) ifprintf(stderr, "%s %s: %s (%s:%u, %s)\n"...
(dla konsoli).Inspiracja: https://gist.github.com/polovik/10714049 .
źródło
Cóż, powiedziałbym, że moment, w którym musisz przekierować wyjście debugowania na coś innego niż stderr, jest momentem, w którym możesz pomyśleć o jakimś narzędziu do logowania. Jeśli czujesz, że go potrzebujesz, polecam użycie
QxtLogger
( "Klasa QxtLogger jest łatwym w użyciu, łatwym do rozszerzenia narzędziem do logowania." ) ZQxt
biblioteki.źródło
Oto prosty, bezpieczny wątkowo idiomatyczny przykład Qt, w którym można logować
stderr
i zapisywać :Zainstaluj go,
qInstallMessageHandler(messageHandler)
jak opisano w innych odpowiedziach.źródło