c++ - Qt 5.5.1:在模板中使用qDebug()

标签 c++ qt

我有以下问题:

我正在使用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(),以便在消息处理程序中具有相对路径吗?
提前致谢!

最佳答案

QMessageLogger实际上会生成日志消息。从Qt Documentation:

qDebug() expands to QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug() for debug builds, and QMessageLogger(0, 0, 0).debug() for release builds.



这有两个后果:
  • 文件,行号和函数名仅在 Debug模式下可用by default.
  • 消息处理程序打印的文件路径取决于预处理器对__FILE__宏的扩展。该文件路径是相对的还是绝对的,可能取决于编译器的预处理器。

  • GCC documentation关于__FILE__预处理程序宏的说法如下:

    This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ‘#include’ or as the input file name argument. For example, "/usr/local/include/myheader.h" is a possible expansion of this macro.



    有了这些信息,下面是一个最小的示例,显示了为什么从模板函数调用Qt的调试函数可能会打印绝对路径:

    警告
    #include <QtDebug>
    #include <iostream>
    
    template <typename T>
    void warn(const T& message)
    {
          qWarning() << message;
          std::cerr << "Macro __FILE__ expands to:  " << __FILE__ << std::endl;
    }
    

    main.cpp
    #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)并将文件的新位置添加到我们的.pro文件中:
    INCLUDEPATH += /var/tmp/
    

    我们得到带有绝对路径的输出:
    File: /var/tmp/warn.h Message: OutputTxt
    Macro __FILE__ expands to:  /var/tmp/warn.h
    

    类似地,如果我们在main.cpp中使用绝对路径而不是将附加头文件包含在模板函数中,而不是追加到INCLUDEPATH:
    #include "/var/tmp/warn.h"
    

    我们还获得带有绝对路径的输出:
    File: /var/tmp/warn.h Message: OutputTxt
    Macro __FILE__ expands to:  /var/tmp/warn.h
    

    因此,尽管这可能只是编译器预处理程序的一个怪癖,但也可能是您包括包含模板函数的头文件的方式。如果未使用绝对路径显式包括此头文件,则可以检查qmake生成的Makefile的INCPATH变量,以查看是否存在任何绝对包含路径。

    关于c++ - Qt 5.5.1:在模板中使用qDebug(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45144370/

    相关文章:

    c++ - 添加产品页面上的 QDate 空值

    C++ 创建文件时出错(名称基于其他文件名)

    c++ - 为什么 g++ 会生成两个具有不同名称修饰的构造函数?

    c++ - 在 C++ 中使用嵌套数组处理 MONGO 记录

    python - 在我的 Qt C++ 应用程序中使用 Anaconda 的 Python

    c++ - 我可以强制 Visual Studio 使用 mingw 编译器吗

    c++ - 了解 '&' 运算符

    c++ - 无法打开包含文件 "windows.h"没有这样的文件或目录

    c++ - 在 Qt Valgrind Function Profiler 中跳过代码

    c++ - QT ntp 并消除差异