关于qt:qDebug不显示__FILE __,__ LINE__


qDebug not showing __FILE__,__LINE__

根据qlogging.h

1
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug

但是当我这样使用时,文件,行,函数名称不显示。

1
2
qDebug()<<"abc"; // only show abc;
qDebug()<<"";    // show nothing;

我搜索了一会儿,似乎没有人遇到上述问题。

我使用ubuntu14.04,g ++版本4.8.2,从git编译qt5.3。


您可以从默认输出格式重新格式化。
此功能在Qt 5.0中引入。

由于默认的消息模式为"%{if-category}%{category}:%{endif}%{message}",因此不会输出行号。此格式表示默认的输出格式不包括行号或文件名之类的元数据。

%cat logtest.pro

1
2
3
4
TEMPLATE = app
TARGET = logtest
mac:CONFIG-=app_bundle
SOURCES += main.cpp

%cat main.cpp

1
2
3
4
5
6
7
8
9
10
#include <QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    qSetMessagePattern("%{file}(%{line}): %{message}");
    QCoreApplication a(argc, argv);
    qDebug() <<"my output";
    return 0;
}

%qmake && make

%./logtest

1
main.cpp(8): my output

您也可以使用QT_MESSAGE_PATTERN环境变量来设置消息模式,而无需调用qSetMessagePattern()。

有关其他占位符,请参见参考。 http://qt-project.org/doc/qt-5/qtglobal.html#qSetMessagePattern


如果您查看Qt历史记录,您会发现__FILE____FUNCTION__仅在2014年10月1日以后才在调试版本中记录。git commit哈希为d78fb442d750b33afe2e41f31588ec94cf4023ad。提交消息指出:

Logging: Disable tracking of debug source info for release builds

Tracking the file, line, function means the information has to be
stored in the binaries, enlarging the size. It also might be a
surprise to some commercial customers that their internal file &
function names are 'leaked'. Therefore we enable it for debug builds
only.


这是一个简单示例,说明如何在使用qInstallMessageHandler安装的自定义消息处理程序中使用捕获的QMessageLogContext数据。我没有输出categoryversion成员,因为它们似乎没有用。如果需要,您也可以通过这种方式登录到文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <QDebug>
#include <QString>
#include <QDateTime>
#include <iostream>

void verboseMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static const char* typeStr[] = {"[   Debug]","[ Warning]","[Critical]","[   Fatal]" };

    if(type <= QtFatalMsg)
    {
        QByteArray localMsg = msg.toLocal8Bit();
        QString contextString(QStringLiteral("(%1, %2, %3)")
                              .arg(context.file)
                              .arg(context.function)
                              .arg(context.line));

        QString timeStr(QDateTime::currentDateTime().toString("dd-MM-yy HH:mm:ss:zzz"));

        std::cerr << timeStr.toLocal8Bit().constData() <<" -"
                  << typeStr[type] <<""
                  << contextString.toLocal8Bit().constData() <<""
                  << localMsg.constData() << std::endl;

        if(type == QtFatalMsg)
        {
            abort();
        }
    }
}

int main()
{
    //Use default handler
    qDebug() <<"default handler";
    qWarning() <<"default handler";
    qCritical() <<"default handler";

    //Install verbose handler
    qInstallMessageHandler(verboseMessageHandler);

    qDebug() <<"verbose handler";
    qWarning() <<"verbose handler";
    qCritical() <<"verbose handler";

    //Restore default handler
    qInstallMessageHandler(0);

    qDebug() <<"default handler";
    qWarning() <<"default handler";
    qCritical() <<"default handler";

    return 0;
}

您可以使用标准C ++的__LINE____FILE__。另外,看看__PRETTY_FUNCTION____FUNCTION____func__ SO问题之间有什么区别。如果使用GCC,则可以编写__PRETTY_FUNCTION__来获取有关代码执行位置的功能的信息。只需准备调试定义您喜欢的。

例如,这是一个小的可编译应用程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <QApplication>
#include <QDebug>
#include <iostream>

// Qt-way
#define MyDBG (qDebug()<<__FILE__<<__LINE__<<__PRETTY_FUNCTION__)
// GCC
#define MyStdDBG (std::cout<< __FILE__<<":"<<__LINE__<<" in"<<__PRETTY_FUNCTION__<<std::endl)

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // Qt-way
    MyDBG;
    MyDBG <<"Something happened!";

    // GCC
    MyStdDBG;

    return a.exec();
}

它给出下一个输出:

1
2
3
../path/main.cpp 14 int main(int, char**)
../path/main.cpp 15 int main(int, char**) Something happened!
../path/main.cpp:18 in int main(int, char**)

UPD:向输出添加了纯C ++方式。


这取决于您的Qt版本号,是否使用Qt的调试版本或发布版本以及是否在应用程序中自定义了Qt消息处理。

根据以源代码" qlogging.cpp"编写的Qt 5.4文档:

1
2
3
4
5
QMessageLogger is used to generate messages for the Qt logging framework. Usually one uses
it through qDebug(), qWarning(), qCritical, or qFatal() functions,
which are actually macros: For example qDebug() expands to
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()
for debug builds, and QMessageLogger(0, 0, 0).debug() for release builds.

因此,如果您在输出中看不到文件,行和函数名称信息,则很可能您正在使用Qt的发行版。

如果您仍然想在Qt的发行版中查看输出中的文件,行和函数名称信息,可以通过多种方法来实现,如先前的一些答案中所解释的。


根据文档,qDebug()已经是QMessageLogger()的宏。默认消息处理程序仅将消息打印到stderr。我认为您可能想使用qInstallMessageHandler()安装自己的消息处理程序,该消息处理程序使用上下文

编辑:

手册中有相关部分介绍了此问题。在Qt4中,上下文变量未传递到已安装的消息处理程序,因此此解决方案仅是Qt5 +。默认消息处理程序不使用在上下文中传递的内容,但是您可以轻松安装自己的消息处理程序,它只是一个函数指针。手册中甚至有一个例子。


我认为您需要定义:

1
#define qDebug() QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()

并用作

1
qDebug() <<"abc";

要么

1
#define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug()

并将其用作:

1
qDebug <<"abc";


如果您想知道如何在非调试版本中获取调试上下文,请执行以下操作:在编译代码时定义QT_MESSAGELOGCONTEXT,并且不会删除该信息:

http://doc.qt.io/qt-5/qmessagelogcontext.html