<QtLogging> - Qt Logging Types

<QtLogging> 头文件定义了 Qt 日志记录类型、函数和宏。更多内容...

Header: #include <QtLogging>

类型

QtMessageHandler
enum QtMsgType { QtDebugMsg, QtInfoMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg }

功能

QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
void qSetMessagePattern(const QString &pattern)

宏

qCritical(const char *format, ...)
qDebug(const char *format, ...)
qFatal(const char *format, ...)
qInfo(const char *format, ...)
qWarning(const char *format, ...)

详细说明

<QtLogging> 头文件包含若干用于日志记录的类型、函数和宏。

QtMsgType 枚举用于标识可生成并发送至Qt消息处理程序的各类消息;QtMessageHandler 是函数指针的类型定义,其签名如下:void myMessageHandler(QtMsgType, const QMessageLogContext &, const char *) 。qInstallMessageHandler()函数可用于安装指定的QtMessageHandler 。QMessageLogContext 类包含消息被记录时的行号、文件名和函数名。这些信息由QMessageLogger 类生成。

<QtLogging> 还包含一些根据给定的字符串参数生成消息的函数:qDebug()、qInfo()、qWarning()、qCritical() 以及qFatal()。这些函数会将给定的消息传递给消息处理程序。

示例:

if(!driver()->isOpen()||driver()->isOpenError()) {
    qWarning("QSqlQuery::exec: database not open");
   return false;
}

另请参阅 QLoggingCategory 。

类型文档

QtMessageHandler

这是一个对具有以下签名的函数指针的typedef:

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

另请参阅 QtMsgType 和qInstallMessageHandler()。

enum QtMsgType

此枚举描述了可发送到消息处理程序(QtMessageHandler )的消息。您可以使用该枚举来识别各种消息类型,并将它们与相应的操作关联起来。其取值按严重程度由低到高的顺序排列如下:

常量值描述
QtDebugMsg0由qDebug() 函数生成的消息。
QtInfoMsg4由qInfo() 函数生成的消息。
QtWarningMsg1由qWarning()函数生成的消息。
QtCriticalMsg2由qCritical() 函数生成的消息。
QtFatalMsg3由qFatal() 函数生成的消息。

另请参阅 QtMessageHandler 、qInstallMessageHandler() 和QLoggingCategory 。

函数文档

QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)

根据参数type 、context 、str 生成一个格式化字符串。

qFormatLogMessage 返回一个根据当前消息模式进行格式化的QString 。自定义消息处理程序可以使用它来格式化输出,其效果与 Qt 的默认消息处理程序类似。

该函数是线程安全的。

另请参阅 qInstallMessageHandler() 和qSetMessagePattern()。

QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)

安装一个 Qt 消息处理程序(handler )。返回指向先前安装的消息处理程序的指针。

消息处理函数是一个用于打印来自 Qt 日志基础设施的调试、信息、警告、严重和致命消息的函数。默认情况下,Qt 使用一个标准的消息处理函数,该函数会根据操作系统和 Qt 配置的特定情况,对消息进行格式化并将其打印到不同的接收端。 安装自定义消息处理程序可让您完全掌控日志记录,例如将消息记录到文件系统中。

请注意,Qt 支持logging categories 用于将相关消息按语义类别分组。您可以使用这些功能按类别启用或禁用日志记录,以及message type 。由于对日志类别的过滤是在消息创建之前就已完成,因此针对已禁用类型和类别的消息将无法到达消息处理程序。

消息处理程序必须reentrant 。也就是说,它可能会被不同线程并行调用。因此,对公共接收端(如数据库或文件)的写入操作通常需要进行同步。

Qt 允许通过调用 `qSetMessagePattern()` 或设置 `QT_MESSAGE_PATTERN ` 环境变量,为日志消息添加更多元数据。为保留此格式,自定义消息处理程序可使用 `qFormatLogMessage()`。

请尽量减少消息处理程序本身的代码量,因为耗时较长的操作可能会阻塞应用程序。此外,为避免递归,消息处理程序本身生成的任何日志消息都将被忽略。

消息处理程序应始终返回。对于fatal messages ,应用程序在处理该消息后会立即终止。

整个应用程序中,同一时间只能安装一个消息处理程序。如果之前已安装过自定义消息处理程序,该函数将返回指向该处理程序的指针。随后可通过再次调用该方法重新安装该处理程序。此外,调用 `qInstallMessageHandler(nullptr) ` 将恢复默认消息处理程序。

以下是一个消息处理程序的示例,该程序在调用默认处理程序之前会将日志记录到本地文件中:

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

QtMessageHandler originalHandler = nullptr;

void logToFile(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QString message = qFormatLogMessage(type, context, msg);
    static FILE *f = fopen("log.txt", "a");
    fprintf(f, "%s\n", qPrintable(message));
    fflush(f);

    if (originalHandler)
        originalHandler(type, context, msg);
}

int main(int argc, char **argv)
{
    originalHandler = qInstallMessageHandler(logToFile);
    QApplication app(argc, argv);
    // ...
    return app.exec();
}

请注意,C++ 标准保证 `static FILE *f ` 以线程安全的方式进行初始化。我们还可以预期 `fprintf() ` 和 `fflush() ` 也是线程安全的,因此无需进行进一步的同步。

另请参阅 QtMessageHandler 、QtMsgType 、qDebug()、qInfo()、qWarning()、qCritical()、qFatal()、调试技术以及 qFormatLogMessage()。

void qSetMessagePattern(const QString &pattern)

更改默认消息处理程序的输出。

允许调整以下函数的输出:qDebug()、qInfo()、qWarning()、qCritical() 以及qFatal()。此外,qCDebug()、qCInfo()、qCWarning() 和qCCritical() 的日志输出也会进行格式化。

支持以下占位符:

占位符描述
%{appname}QCoreApplication::applicationName()
%{category}日志类别
%{file}源文件路径
%{function}函数
%{line}源文件中的行号
%{message}实际日志信息
%{pid}QCoreApplication::applicationPid()
%{threadid}当前线程的全局 ID(如果能够获取)
%{threadname}当前线程的名称(若能获取,或自 Qt 6.10 起为线程 ID)
%{qthreadptr}指向当前QThread 的指针(QThread::currentThread()的返回值)
%{type}“debug”、“warning”、“critical”或“fatal”
%{time process}消息的时间,以进程启动后的秒数计(标记“process”为字面量)
%{time boot}消息发生的时间,以系统启动以来的秒数计(若能确定;“boot”为字面量)。若无法获取自启动以来的时间,输出结果不确定(参见QElapsedTimer::msecsSinceReference())。
%{time [format]}消息发生时的系统时间,通过将format 传递给QDateTime::toString()进行格式化。若未指定格式,则采用Qt::ISODate 的格式。
%{backtrace [depth=N] [separator="..."]}包含由可选参数depth 指定的帧数(默认为 5)的回溯信息,各帧之间由可选参数separator 指定的分隔符分隔(默认为 "|")。从 Qt 6.12 开始,depth 的最大值限制为 16384 帧。

此扩展功能仅在某些平台上可用:

  • 使用 glibc 的平台;
  • 随附 C++23 的<stacktrace> 头文件的平台(需要以 C++23 模式编译 Qt)。

根据平台的不同,此扩展所输出的函数名称会受到一些限制。

在某些平台上,仅能获取导出函数的名称。若要查看应用程序中所有函数的名称,请确保您的应用程序是使用-rdynamic 或其等效头文件进行编译和链接的。

在读取回溯信息时,请注意可能因内联或尾调用优化而导致某些帧缺失。

您还可以通过%{if-debug} 、%{if-info} 、%{if-warning} 、%{if-critical} 或%{if-fatal} (后跟%{endif} )对消息类型进行条件判断。只有当类型匹配时,%{if-*} 和%{endif} 中的内容才会被打印出来。

最后,%{if-category}...%{endif} 中的文本仅在类别非默认类别时才会被打印。

示例:

    QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz ttt} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}"

默认的pattern 为%{if-category}%{category}: %{endif}%{message} 。

注意:在 Android平台上 ,默认的 `pattern ` 为 `%{message} `,因为该类别会被用作标签——Android Logcat 设有专门用于日志类别的字段,详见《Android 日志记录》。若使用包含类别的自定义 `pattern `,则 `QCoreApplication::applicationName()` 将被用作标签。

pattern 还可以在运行时通过设置 QT_MESSAGE_PATTERN 环境变量进行更改;如果同时调用了 qSetMessagePattern() 并设置了 QT_MESSAGE_PATTERN,则环境变量具有优先级。

注意: category 、file 、function 和line 占位符的相关信息 仅在调试版本中记录。此外,也可以显式定义QT_MESSAGELOGCONTEXT 。更多信息请参阅QMessageLogContext 文档。

注意:该 消息模式仅适用于非结构化日志记录,例如默认的stderr 输出。而系统d(systemd)等结构化日志记录会原样记录消息,并附带尽可能多的结构化信息。

自定义消息处理程序可使用 `qFormatLogMessage()` 来考虑 `pattern `。

安全注意事项

Qt 不会从 `pattern ` 中移除或转义控制字符——包括 `LF`、`CR`、`NUL ` 字节以及终端控制序列。因此,接受来自不可信来源的模式可能会导致日志伪造,或向日志流的消费者发送控制序列。此外,在某些日志后端中,如果存在 `NUL ` 字节,消息可能会在此处被截断。

另请参阅 qInstallMessageHandler(),调试技术,QLoggingCategory 以及QMessageLogContext 。

宏文档

qCritical(const char *format, ...)

将关键消息format 记录到中央消息处理程序中。format 中可以包含格式指定符,这些指定符将被附加参数中指定的值替换。

示例:

void load(const QString &fileName)
{
    QFile file(fileName);
    if (!file.exists())
        qCritical("File '%s' does not exist!", qUtf8Printable(fileName));
}

format 可以包含格式指定符,例如用于 UTF-8 字符串的%s ,或用于整数的%i 。这与 C 语言中 `printf() ` 函数的工作原理类似。有关格式的更多详细信息,请参阅QString::asprintf()。

为了更方便并支持更多类型,您还可以使用QDebug::qCritical(),它遵循流式处理范式(类似于std::cout 或std::cerr )。

若要在运行时抑制输出,您可以定义logging rules 或注册一个自定义的filter 。

出于调试目的,有时让程序在遇到关键消息时终止会比较方便。这样可以检查内核转储,或连接调试器——另请参阅qFatal()。要启用此功能,请将环境变量QT_FATAL_CRITICALS 设置为一个数字n 。此时,程序将在收到第 n 条关键消息时终止。 也就是说,如果环境变量设置为 1,程序将在首次调用时终止;如果其值为 10,则将在第 10 次调用时退出。环境变量中的任何非数值均等同于 1。

注意:此宏是线程安全的。

另请参阅 QDebug::qCritical 、qCCritical()、qDebug()、qInfo()、qWarning()、qFatal()、qInstallMessageHandler() 以及《调试技术》。

qDebug(const char *format, ...)

将调试消息format 记录到中央消息处理程序中。format 中可以包含格式指定符,这些指定符将被附加参数中指定的值替换。

示例:

qDebug("Items in list: %d", myList.size());

format 可以包含格式指定符,例如表示 UTF-8 字符串的%s ,或表示整数的%i 。这与 C 语言中 `printf() ` 函数的工作原理类似。有关格式化的更多详细信息,请参阅QString::asprintf()。

为了更方便且支持更多数据类型,您还可以使用QDebug::qDebug(),该函数遵循流式处理范式(类似于std::cout 或std::cerr )。

如果编译时定义了QT_NO_DEBUG_OUTPUT ,则该函数不会执行任何操作。

若要在运行时抑制输出,请使用qInstallMessageHandler() 设置您自己的消息处理程序。

注意:此宏是线程安全的。

另请参阅 QDebug::qDebug()、qCDebug()、qInfo()、qWarning()、qCritical()、qFatal()、qInstallMessageHandler()以及《调试技术》。

qFatal(const char *format, ...)

将致命错误消息format 记录到中央消息处理程序中。format 中可以包含格式指定符,这些指定符将被附加参数中指定的值替换。

示例:

int divide_by_zero(int a, int b)
{
    if (b == 0)                                // program error
        qFatal("divide: cannot divide by zero");
    return a / b;
}

如果您使用的是默认消息处理程序,此函数将终止运行以生成核心转储。在 Windows 系统上,对于调试版本,此函数将报告一个 _CRT_ERROR,从而允许您将调试器连接到应用程序。

若要在运行时抑制该输出,请使用qInstallMessageHandler() 设置您自己的消息处理程序。

另请参阅 qCFatal()、qDebug()、qInfo()、qWarning()、qCritical()、qInstallMessageHandler() 以及《调试技术》。

qInfo(const char *format, ...)

将信息消息format 记录到中央消息处理程序中。format 中可以包含格式指定符,这些指定符将被附加参数中指定的值替换。

示例:

qInfo("Items in list: %d", myList.size());

format 可以包含格式指定符,例如表示 UTF-8 字符串的 `%s `,或表示整数的 `%i `。这与 C 语言中 `printf() ` 函数的工作原理类似。有关格式的更多详细信息,请参阅 `QString::asprintf()`。

为了更方便且支持更多类型,您还可以使用QDebug::qInfo(),该函数遵循流式处理范式(类似于std::cout 或std::cerr )。

如果编译时定义了 `QT_NO_INFO_OUTPUT `,则该函数不执行任何操作。

若要在运行时抑制输出,请使用qInstallMessageHandler() 安装您自己的消息处理程序。

注意:此宏是线程安全的。

另请参阅 QDebug::qInfo()、qCInfo()、qDebug()、qWarning()、qCritical()、qFatal()、qInstallMessageHandler() 以及“调试技巧”。

qWarning(const char *format, ...)

将警告消息format 记录到中央消息处理程序中。format 中可以包含格式说明符,这些说明符将被附加参数中指定的值替换。

示例:

void f(int c)
{
    if (c > 200)
        qWarning("f: bad argument, c == %d", c);
}

format 可以包含格式指定符,例如用于 UTF-8 字符串的%s ,或用于整数的%i 。这与 C 语言中printf() 函数的工作原理类似。有关格式化的更多详细信息,请参阅QString::asprintf()。

为了更方便并支持更多类型,您还可以使用QDebug::qWarning(),该函数遵循流式处理范式(类似于std::cout 或std::cerr )。

如果编译时定义了QT_NO_WARNING_OUTPUT ,则该函数不会执行任何操作。若要在运行时抑制输出,您可以设置logging rules 或注册自定义的filter 。

出于调试目的,有时让程序因警告消息而中止会比较方便。这允许您检查核心转储,或附加调试器——另请参阅qFatal()。要启用此功能,请将环境变量QT_FATAL_WARNINGS 设置为一个数字n 。此时,程序将在第 n 个警告时终止。 也就是说,如果该环境变量被设置为 1,程序将在第一次调用时终止;如果其值为 10,则将在第 10 次调用时退出。环境变量中的任何非数值都等同于 1。

注意:此宏是线程安全的。

另请参阅 QDebug::qWarning(),qCWarning(),qDebug(),qInfo(),qCritical(),qFatal(),qInstallMessageHandler(),以及《调试技术》。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.