Qt QML 杂记

Qt 拾遗 004 自定义日志

2020-04-07  本文已影响0人  赵者也

QtMessageHandler

QtMessageHandler 并不是一个类,其定义如下:
typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);

这是一个指向函数的指针,因此用户可以定义具有以下格式的自定义函数:

void myMessageHandler(QtMsgType,  const QMessageLogContext&, QString&);

第一个参数 QtMsgType 是日志的等级类型:

enum QtMsgType { 
QtDebugMsg, 
QtWarningMsg, 
QtCriticalMsg, 
QtFatalMsg, 
QtInfoMsg, 
QtSystemMsg = QtCriticalMsg 
};

我们可以将其与适当的操作关联起来:

QtMsgType 枚举值在文档中的描述

第二个参数 QMessageLogContext 是写日志的当前文件名,文件行数,和当前的函数信息类。和 __FILE__、__LINE__、__FUNCTION__ 功能类似,但是我们在自定义函数中需要借助 QMessageLogContext 对象来获取是谁在做这些事。这个类主要提供如下方法:

const char * category();
const char * file();
const char * function();
int line();
int version();

第三个参数 QString 就是日志信息。

QtMessageHandler 的使用示例:

  void myMessageOutput(QtMsgType type, const QMessageLogContext &context,
                        const QString &msg)
  {
      QByteArray localMsg = msg.toLocal8Bit();
      const char *file = context.file ? context.file : "";
      const char *function = context.function ? context.function : "";
      switch (type) {
      case QtDebugMsg:
          fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), 
                  file, context.line, function);
          break;
      case QtInfoMsg:
          fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(),
                  file, context.line, function);
          break;
      case QtWarningMsg:
          fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), 
                  file, context.line, function);
          break;
      case QtCriticalMsg:
          fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), 
                  file, context.line, function);
          break;
      case QtFatalMsg:
          fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), 
                  file, context.line, function);
          break;
      }
  }

qInstallMessageHandler

定义如下:
Q_CORE_EXPORT QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)

它的作用是安装之前定义的 QtMessageHandler 实例程序的函数指针。并返回指向这个消息处理程序的函数指针。

QtMessageHandler 是输出调试消息、警告、关键错误和致命错误消息的函数。Qt 库(调试模式)包含数百条警告消息,当内部错误(通常是无效的函数参数)发生时,将打印这些消息。除非 QT_NO_WARNING_OUTPUT 和/或 QT_NO_DEBUG_OUTPUT 在编译期间被设置,否则在发布模式中构建的 Qt 程序也会包含这样的警告。如果我们实现了自己的消息处理程序,则可以完全自主地控制这些消息。

默认消息处理程序将消息打印到 X11 下的标准输出或 Windows 下的调试器。如果是致命消息,应用程序将立即中止。

我们的应用每次只能定义一个消息处理程序,因为这这个设置通常是在应用程序全局左右域内进行的,目的是控制整个程序的调试信息的输出。

要恢复消息处理程序为默认,我们可以调用:

qInstallMessageHandler(0);

完整的使用实例:

#include <qapplication.h>
#include <stdio.h>
#include <stdlib.h>

void myMessageOutput(QtMsgType type, const QMessageLogContext &context, 
                      const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    const char *file = context.file ? context.file : "";
    const char *function = context.function ? context.function : "";
    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), 
                file, context.line, function);
        break;
    case QtInfoMsg:
        fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), 
                file, context.line, function);
        break;
    case QtWarningMsg:
        fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), 
                file, context.line, function);
        break;
    case QtCriticalMsg:
        fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), 
                file, context.line, function);
        break;
    case QtFatalMsg:
        fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), 
                file, context.line, function);
        break;
    }
}

int main(int argc, char **argv)
{
    qInstallMessageHandler(myMessageOutput);
    QApplication app(argc, argv);
    ...
    return app.exec();
}

以上

上一篇下一篇

猜你喜欢

热点阅读