如何重定向 qDebug、qWarning、qCritical 等输出?

新手上路,请多包涵

我正在使用大量 qDebug() << 语句进行调试输出。是否有任何跨平台的方式可以将调试输出重定向到文件,而无需使用 shell 脚本?我猜 open()dup2() 会在 Linux 中完成这项工作,但它会在 Windows 中使用 MinGW 编译吗?

也许有一种 Qt 方法可以做到这一点?

原文由 Septagram 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 626
2 个回答

您必须使用 qInstallMessageHandler 函数安装消息处理程序,然后,您可以使用 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); // Install the handler
    QApplication app(argc, argv);
    ...
    return app.exec();
}

取自 qInstallMessageHandler 的文档(我只添加了评论):

在上面的例子中,函数 myMessageOutput 使用 stderr 你可能想用其他文件流替换它,或者完全重写函数!

一旦你编写并安装了这个函数,你所有的 qDebug (以及 qWarningqCritical 等)消息将被重定向到你正在写入的文件在处理程序中。

原文由 Nawaz 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果应用程序是从 Qt Creator 运行的,那么这是一个跨平台登录到控制台的解决方案,当它被编译并作为独立应用程序运行时,它会登录到 debug.log 文件。

主.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。

原文由 Neurotransmitter 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题