创作灵感
刚刚在看qt帮助手册时,无意间在<QtGlobal>中看见了这个函数void qSetMessagePattern(const QString &pattern),该函数的精华在于,你可以直接重定义qDebug()的输出结果格式。以往打印调试内容,调试内容所在的行,所在的文件等都采用定义宏的方式,如下所示
#include <QDebug>#define UN_MY_DEBUG
//#undef UN_MY_DEBUG
#if defined(UN_MY_DEBUG)
#define MY_DEBUG(x)
#else
#define MY_DEBUG(x) qDebug()<<"["<<__FILE__<<"}"<<__LINE__<<x;
#endif
然而现在你有另外一中全新的方式定义,Qt官方给出的原文如下图所示
void qSetMessagePattern(const QString &pattern)
Changes the output of the default message handler.
更改默认消息处理程序的输出。
Allows to tweak the output of qDebug(), qInfo(), qWarning(), qCritical(), and qFatal(). The category logging output of qCDebug(), qCInfo(), qCWarning(), and qCCritical() is formatted, too.
允许调整qDebug()、qInfo()、qWarning()、qCritical() 和 qFatal()的类别日志输出。qCDebug()、qCInfo()、qCWarning()和qCCritical()的类别日志输出也被格式化。
Following placeholders are supported:
支持以下占位符:
Placeholder 占位符 | Description 描述 |
---|---|
%{appname} | QCoreApplication::applicationName() 应用程序名称 |
%{category} | Logging category 日志记录类别 |
%{file} | Path to source file 源文件路径 |
%{function} | Function 函数名称 |
%{line} | Line in source file 源文件中的行 |
%{message} | The actual message 打印的日志信息 |
%{pid} | QCoreApplication::applicationPid() 应用程序Pid |
%{threadid} | The system-wide ID of current thread (if it can be obtained) 当前线程的系统范围ID(如果可以获得) |
%{qthreadptr} | A pointer to the current QThread (result of QThread::currentThread()) 指向当前QThread(QThread的结果::当前线程QThread::currentThreadQThread的结果::当前线程()结果) |
%{type} | "debug", "warning", "critical" or "fatal" “调试”、“警告”、“严重”或“致命” |
%{time process} | time of the message, in seconds since the process started (the token "process" is literal) 消息的时间,自进程启动以来的秒数(“process”是字面意思) |
%{time boot} | the time of the message, in seconds since the system boot if that can be determined (the token "boot" is literal). If the time since boot could not be obtained, the output is indeterminate (see QElapsedTimer::msecsSinceReference()). 消息的时间,如果可以确定,自系统启动以来的秒数(“boot”是字面意思)。如果无法获得启动后的时间,则输出不确定(参见QElapsedTimer::msecsSinceReference())。 |
%{time [format]} | system time when the message occurred, formatted by passing the 消息发生时的系统时间,通过将 |
%{backtrace [depth=N] [separator="..."]} | A backtrace with the number of frames specified by the optional 由可选的 |
You can also use conditionals on the type of the message using
%{if-debug}
,%{if-info}
%{if-warning}
,%{if-critical}
or%{if-fatal}
followed by an%{endif}
. What is inside the%{if-*}
and%{endif}
will only be printed if the type matches.您也可以对消息的类型使用条件
%{if-debug}
、%{if-info}
%{if-warning}
、%{if-critical}
或%{if-fatal}
后跟%{endif}
。只有当类型匹配时,才会打印%{if-*}
和%{endif}
中的内容。Finally, text inside
%{if-category}
...%{endif}
is only printed if the category is not the default one.最后,只有当
%{if-category}
…%{endif}
不是默认类别时,才会打印文本。
Example:
示例:
QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}"
The default pattern is "%{if-category}%{category}: %{endif}%{message}".
默认模式是"%{if-category}%{category}:%{endif}%{message}"。
The pattern can also be changed at runtime by setting the QT_MESSAGE_PATTERN environment variable; if both qSetMessagePattern() is called and QT_MESSAGE_PATTERN is set, the environment variable takes precedence.
也可以在运行时通过设置QT_MESSAGE_PATTERN环境变量来更改模式;如果同时调用了qSetMessagePattern()并设置了QT_MESSAGE_PATTERN,则环境变量优先。
Custom message handlers can use qFormatLogMessage() to take pattern into account.
自定义消息处理程序可以使用qFormatLogMessage()来考虑模式。
案例1
#include "mainwindow.h"
#include <QApplication>
#include <QtGlobal>
#include <QDebug>int main(int argc, char *argv[])
{qSetMessagePattern("begin*************************************************\n""appname:%{appname}\n""category:%{category}\n""file:%{file}\n""function:%{function}\n""line:%{line}\n""pid:%{pid} ""threadid:%{threadid}\n""qthreadptr:%{qthreadptr}\n""type:%{type}\n""time process:%{time process}s\n""time boot:%{time boot}s\n""time [format]:%{time [yyyy-MM-dd hh:mm:ss.zzz]}\n""message:%{message}\n""end*************************************************\n");QApplication a(argc, argv);MainWindow w;w.show();qDebug()<<"hello world";qInfo()<<"hello world";qWarning()<<"hello world";return a.exec();
}
案例1输出
begin*************************************************
appname:untitled2
category:default
file:main.cpp
function:main
line:26
pid:13712 threadid:20500
qthreadptr:0x8d3758
type:debug
time process: 0.118s
time boot:280024.458s
time [format]:[2024-06-06 16:32:04.481]
message:hello world
end*************************************************begin*************************************************
appname:untitled2
category:default
file:main.cpp
function:main
line:27
pid:13712 threadid:20500
qthreadptr:0x8d3758
type:info
time process: 0.118s
time boot:280024.458s
time [format]:[2024-06-06 16:32:04.481]
message:hello world
end*************************************************begin*************************************************
appname:untitled2
category:default
file:main.cpp
function:main
line:28
pid:13712 threadid:20500
qthreadptr:0x8d3758
type:warning
time process: 0.119s
time boot:280024.459s
time [format]:[2024-06-06 16:32:04.483]
message:hello world
end*************************************************
案例2
当然有时候我们还会去限定某些条件同某些功能,例如
#include "mainwindow.h"
#include <QApplication>
#include <QtGlobal>
#include <QDebug>int main(int argc, char *argv[])
{qSetMessagePattern("begin*************************************************\n""appname:%{appname}\n""category:%{category}\n""file:%{file}\n""function:%{function}\n""line:%{line}\n""pid:%{pid} ""threadid:%{threadid}\n""qthreadptr:%{qthreadptr}\n""type:%{type}\n""time process:%{time process}s\n""time boot:%{time boot}s\n""time [format]:%{time [yyyy-MM-dd hh:mm:ss.zzz]}\n""%{if-debug}debug:%{endif}""%{if-info}info:%{endif}""%{if-warning}warning:%{endif}""%{if-critical}critical:%{endif}""%{if-fatal}fatal:%{endif}""message:%{message}\n""end*************************************************\n");QApplication a(argc, argv);MainWindow w;w.show();qDebug()<<"hello world";qInfo()<<"hello world";qWarning()<<"hello world";return a.exec();
}
案例2输出
begin*************************************************
appname:untitled2
category:default
file:main.cpp
function:main
line:31
pid:14164 threadid:17496
qthreadptr:0x13c36c0
type:debug
time process: 0.120s
time boot:280626.977s
time [format]:[2024-06-06 16:42:07.000]
debug:message:hello world
end*************************************************begin*************************************************
appname:untitled2
category:default
file:main.cpp
function:main
line:32
pid:14164 threadid:17496
qthreadptr:0x13c36c0
type:info
time process: 0.120s
time boot:280626.977s
time [format]:[2024-06-06 16:42:07.000]
info:message:hello world
end*************************************************begin*************************************************
appname:untitled2
category:default
file:main.cpp
function:main
line:33
pid:14164 threadid:17496
qthreadptr:0x13c36c0
type:warning
time process: 0.122s
time boot:280626.979s
time [format]:[2024-06-06 16:42:07.003]
warning:message:hello world
end*************************************************
案例3
再如,我需要
debug模式下打印file,line
info模式下打印file,line,qthreadptr,time
waring模式下打印file,line
critical模式下打印file,line
fatal模式下打印file,line
#include "mainwindow.h"
#include <QApplication>
#include <QtGlobal>
#include <QDebug>int main(int argc, char *argv[])
{qSetMessagePattern("begin*************************************************\n""%{if-debug}%{file}(%{line}) %{endif}""%{if-info}%{file}(%{line}) qthreadptr:%{qthreadptr} time [format]:%{time [yyyy-MM-dd hh:mm:ss.zzz]} %{endif}""%{if-warning}%{file}(%{line}) %{endif}""%{if-critical}%{file}(%{line}) %{endif}""%{if-fatal}%{file}(%{line}) %{endif}""%{type}:%{message}\n""end*************************************************\n");QApplication a(argc, argv);MainWindow w;w.show();qDebug()<<"hello world";qInfo()<<"hello world";qWarning()<<"hello world";return a.exec();
}
案例3输出
begin*************************************************
main.cpp(41) main debug:hello world
end*************************************************begin*************************************************
main.cpp(42) qthreadptr:0x13c3828 time [format]:[2024-06-06 16:56:18.884] info:hello world
end*************************************************begin*************************************************
main.cpp(43) warning:hello world
end*************************************************
案例4
设置环境变量
QT_MESSAGE_PATTERN=%{if-critical}%{file}(%{line}) %{endif}%{if-debug}%{file}(%{line}) %{endif}%{if-fatal}%{file}(%{line}) %{endif}%{if-info}%{file}(%{line}) qthreadptr:%{qthreadptr} time [format]:%{time [yyyy-MM-dd hh:mm:ss.zzz]} %{endif}%{if-warning}%{file}(%{line}) %{endif}%{type}:%{message}
方法1 QtCreator系统的环境变量设置,下次新建项目时依旧可用,一劳永逸
注意:变量不需要加双引号
弊端:没法加换行,亲测加换行就不行(我更倾向在代码里添加)
实例代码
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;qDebug()<<"hello world";qInfo()<<"hello world";qWarning()<<"hello world";w.show();return a.exec();
}
方法1 输出
main.cpp(8) debug:hello world
main.cpp(9) qthreadptr:0xbd1770 time [format]:[2024-06-06 17:39:29.131] info:hello world
main.cpp(10) warning:hello world
实例代码
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;qDebug()<<"hello world";qInfo()<<"hello world";qWarning()<<"hello world";w.show();return a.exec();
}
方法2 针对项目设置,下次新建项目时需重新设置
方法2输出
main.cpp(8) debug:hello world
main.cpp(9) qthreadptr:0xbd1770 time [format]:[2024-06-06 17:39:29.131] info:hello world
main.cpp(10) warning:hello world