我有以下问题:
我使用Qt 5.5.1并使用qDebug()函数通过内部消息(qInstallMessageHandler)处理程序生成日志文件。在此消息处理程序中,有一个特定的消息模式:
[%{time yyyy-MM-dd h:mm:ss.zzz} %{if-debug}DBG%{endif}%{if-info}INF"
"%{endif}%{if-warning}WRN%{endif}%{if-critical}CRT%{endif}%{if-fatal}FTL%{endif} %{category}]"
" %{file}:%{line} - %{message}
这会产生如下消息:
[2017-07-17 13:52:57.934 INF default] ..\..\..\file.cpp:146 - OutputTxt
通常,应该有一个带有相对路径的输出,但有些消息带有绝对路径。我发现当我在模板函数中使用qDebug()时会导致"问题"绝对路径。
有人知道,我如何在模板函数中使用qDebug(),以便在我的消息处理程序中有相对路径? 提前谢谢!
答案 0 :(得分:0)
QMessageLogger实际上生成了日志消息。来自Qt Documentation:
对于调试版本,
qDebug()
扩展为QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()
,对于版本版本,<QMessageLogger(0, 0, 0).debug()
扩展为__FILE__
。
这有两个后果:
文件,行号和功能名称仅在调试模式下可用by default.
消息处理程序打印的文件路径取决于预处理器对__FILE__
宏的扩展。该文件路径是相对路径还是绝对路径可能取决于编译器的预处理器。
GCC documentation可以说明#include <QtDebug>
#include <iostream>
template <typename T>
void warn(const T& message)
{
qWarning() << message;
std::cerr << "Macro __FILE__ expands to: " << __FILE__ << std::endl;
}
预处理器宏:
此宏以C字符串常量的形式扩展为当前输入文件的名称。这是预处理器打开文件的路径,而不是'#include'中指定的短名称或输入文件名参数。例如,&#34; /usr/local/include/myheader.h"是这个宏的可能扩展。
有了这些信息,这里有一个最小的例子,说明为什么从模板函数调用Qt的调试函数可能会打印绝对路径:
#include <QtDebug>
#include "warn.h"
int main(int argc, char *argv[])
{
qSetMessagePattern("File: %{file} Message: %{message}");
warn("OutputTxt");
}
File: ./warn.h Message: OutputTxt
Macro __FILE__ expands to: ./warn.h
这使用相对路径给出了预期的输出:
warn.h
但是如果我们将/var/tmp
移到另一个目录(INCLUDEPATH += /var/tmp/
)并将该文件的新位置添加到.pro文件中:
File: /var/tmp/warn.h Message: OutputTxt
Macro __FILE__ expands to: /var/tmp/warn.h
我们使用绝对路径获得此输出:
INCLUDEPATH
同样,如果我们使用main.cpp中的绝对路径包含带有模板函数的头文件,而不是附加到#include "/var/tmp/warn.h"
:
File: /var/tmp/warn.h Message: OutputTxt
Macro __FILE__ expands to: /var/tmp/warn.h
我们还获得绝对路径的输出:
INCPATH
虽然它可能只是编译器预处理器的一个怪癖,但也可能是你包含包含模板函数的头文件的方式。如果您没有使用绝对路径明确包含此头文件,则可以检查qmake生成的Makefile&#39; {{1}}变量,以查看是否存在任何绝对包含路径。