在 Qt 开发过程中,调试是不可或缺的环节,而 QDebug 作为 Qt 框架自带的调试输出工具,凭借其简洁易用、功能强大的特点,成为了开发者排查问题的得力助手。无论是基础的变量输出,还是复杂的自定义数据类型打印,QDebug 都能轻松应对。本文将从基础用法到进阶技巧,全面介绍 QDebug 的使用方法。
01 QDebug 基础用法:快速上手输出信息
QDebug 的基础用法非常简单,只需包含相关头文件并调用相应的输出函数,就能快速输出调试信息。
首先,在代码中需要包含 <QDebug> 头文件,这是使用 QDebug 的前提。然后,最常用的就是 qDebug() 函数,它可以像 cout 一样直接输出各种基本数据类型,例如整数、浮点数、字符串等。
|
|
运行上述代码,在控制台中会清晰地输出相应的信息:
|
|
此外,qDebug() 还支持格式化输出,通过使用占位符来指定输出的格式。常用的占位符有 %d(整数)、%f(浮点数)、%s(字符串)等。
| qDebug("Number: %d, Score: %.2f", num, score); |
用法和printf相同,输出如下:
| Number: 10, Score: 95.50 |
02 qDebug 输出自定义结构体
在实际开发中,我们经常需要输出自定义结构体的数据,以便查看结构体内部成员的取值。QDebug 支持通过重载 operator<< 运算符来实现自定义结构体的输出。
假设我们有一个 Person 结构体:
|
|
要让 QDebug 能够输出 Person 结构体,只需在结构体外部重载 operator<< 运算符:
|
|
之后,就可以像输出基本数据类型一样输出 Person 结构体变量了:
|
|
输出结果如下:
| Person Info: Person(name: "Tom" , age: 25 , address: "Beijing" ) |
03 配置日志格式
默认情况下,QDebug 的输出格式比较简单。但在实际开发中,我们可能需要在日志中包含时间、日志级别等信息,以便更好地追踪和分析问题。Qt 提供了相关的方法来配置终端日志格式。
我们可以通过 qSetMessagePattern() 函数来设置日志的输出格式,该函数接受一个字符串作为参数,字符串中可以包含各种占位符来指定日志的组成部分。
常用的占位符有:
| %{appname} | |
| %{category} | 日志类别 |
%{file} | 源文件路径 |
| %{function} | 函数 |
%{line}
| 源文件中的行 |
%{message}
| 实际消息 |
%{pid}
| PID |
%{threadid}
| 当前线程的全局 ID(如果可以获取) |
%{type}
| "debug", "warning", "critical" or "fatal" |
%{time process}
| 消息发送时间,以进程启动以来的秒数为单位("process"是字面量) |
%{time boot}
| 消息发送时间,以系统启动以来的秒数为单位,如果可以确定("boot"是字面量)。如果无法获取自启动以来的时间,输出结果不确定(参见 QElapsedTimer::msecsSinceReference |
%{time [format]}
| 消息发生时的系统时间,通过将 format 传递给 QDateTime::toString ()进行格式化。如果未指定格式,则使用 Qt::ISODate 的格式。 |
消息发生时的系统时间,通过将 format 传递给 QDateTime::toString ()进行格式化。如果未指定格式,则使用 Qt::ISODate 的格式。
|
|
输出结果如下:
|
04 日志输出重定向
默认情况下,QDebug 的输出会显示在控制台中。但在某些场景下,我们可能需要将日志输出到文件、网络或其他地方,这就需要用到输出重定向功能。Qt 提供了 qInstallMessageHandler() 函数来实现自定义消息处理,从而实现输出重定向。
(一)重定向到文件
将日志输出到文件可以方便地保存日志信息,便于后续分析。以下是将日志重定向到文件的示例代码:
|
|
运行上述代码后,日志信息会被写入到当前目录下的 log.txt 文件中。
(二)重定向到其他设备
除了文件,我们还可以将日志重定向到其他设备,例如网络套接字。只需在自定义的消息处理函数中,将日志信息发送到网络即可。具体实现需要结合网络编程相关知识,这里不再详细展开。
(三)重定向到三方日志库
在大型项目中,我们可能需要更强大的日志管理能力,如日志轮转、多线程安全、远程日志收集等。此时,将 QDebug 输出重定向到三方日志库是一个不错的选择。以下是几个常用的三方日志库推荐:
-
spdlog
-
log4cpp
-
Poco logging
05 日志分类输出
自从Qt5.2开始就加入了日志分类功能,陆陆续续再后续版本也添加了其他特性。要为输出的日志进行分类,需要提供类型参数,所以引入了新的日志宏:qCDebug()、qCInfo()、qCWarning() 和 qCCritical()。这些宏在头文件 QLoggingCategory 中声明。
入门的用法:
|
|
注意类型名称"dirver.usb"的定义存在限制,仅字母数字和点。
看下构造函数:
QLoggingCategory(constchar *category, QtMsgType enableForLevel = QtDebugMsg)
需要提供一个分类的字符串名称和输出限制级别。默认值所有级别的日志都会输出。如果指定了 Warning,那么比这个级别低的日志将不会输出。比如 Debug类型的就不会输出。
另外提供了两个宏方便声明 QLoggingCategory 静态变量。
|
|
宏定义如下,相当于头文件里声明了一个全局函数,源文件实现这个函数,返回一个静态的 QLoggingCategory 类型变量。
|
同时日志分类之后,可以全局配置,限制指定模块日志是否输出。比如:
QLoggingCategory::setFilterRules("*.debug=false\n""driver.usb.debug=true"); |
日志的输出规则提供多种方式配置,优先级如下:
-
[QLibraryInfo::DataPath]/qtlogging.ini
-
QtProject/qtlogging.ini
-
setFilterRules()
-
QT_LOGGING_CONF(环境变量,指定配置文件的位置)
-
QT_LOGGING_RULES(环境变量,多条规则分号隔开)
日志格式化的时候也可以配置日志分类:
qSetMessagePattern("%{category} %{message}");
3080

被折叠的 条评论
为什么被折叠?



