Qt5的Log打印
2016-03-17 22:33
525 查看
背景:
一般情况下,我们调试版本会在code里面添加一些qDebug来帮助我们修改代码。
但是当我们的软件版本发布出去,用户告诉我们软件使用出问题了,并且我们在自己的实验室无法复现问题怎么办?
这个时候怎么依靠我们之前在代码里面添加的qDebug呢?
只要用户动动小手,改个配置文件就会把原来代码里面的log输出到一个txt里,然后送给我们分析问题。
方法:
首先,我们使用帮助文档看下Qt5的这个方法
显而易见,它给我们举了个例子,告诉我们怎么使用,并且也详细描述了。
The message handler is a function that prints out debug messages, warnings, critical and fatal error messages. The Qt library (debug mode) contains hundreds of warning messages that
are printed when internal errors (usually invalid function arguments) occur. Qt built in release mode also contains such warnings unless QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during compilation. If you implement your own message handler,
you get total control of these messages.
我们只需要把他的信息保留到txt文件中就可以了。
同时在代码里面定义个宏,
注意:
如果Release模式下,在软件运行输出日志到txt的时候,用户这时关闭软件,我们必须要有个关闭txt文件的操作。
这个时候你需要了解下 这个函数
used to add cleanup routines for program-wide functionality.
以上基本就可以满足我们的要求了。
下来请赏脸看下我写的例子:
运行顺序:
1. 判断是否为Release
2. installReleaseMsgHandler // 初始化 ini信息,和log文件位置
3. installMsgHandler // 打开文件,并调用 qInstallMessageHandler
4. myMessageOutput // 根据之前 读取的log等级 按照要求输出log
5. qAddPostRoutine // 检测软件是否关闭,调用关闭文件函数
6. SoftWareShutDown // 关闭文件
同时说明下,我的RunInfo.ini文件信息
就两行
[TraceSet]
TraceLevel=4
平时为1 ,当我们需要打log的时候改为4(全部信息,qDebug/qWarning/qCritical/qInfo),改为3的时候....自己试试吧。
上面代码的CSDN链接:http://download.csdn.net/detail/c3060911030/9464986
主要 ini文件要放置正确位置,在运行目录下。
一般情况下,我们调试版本会在code里面添加一些qDebug来帮助我们修改代码。
但是当我们的软件版本发布出去,用户告诉我们软件使用出问题了,并且我们在自己的实验室无法复现问题怎么办?
这个时候怎么依靠我们之前在代码里面添加的qDebug呢?
只要用户动动小手,改个配置文件就会把原来代码里面的log输出到一个txt里,然后送给我们分析问题。
方法:
首先,我们使用帮助文档看下Qt5的这个方法
QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)我们可以看到下面信息。
#include <qapplication.h> #include <stdio.h> #include <stdlib.h> void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); abort(); } } int main(int argc, char **argv) { qInstallMessageHandler(myMessageOutput); QApplication app(argc, argv); ... return app.exec(); }
显而易见,它给我们举了个例子,告诉我们怎么使用,并且也详细描述了。
The message handler is a function that prints out debug messages, warnings, critical and fatal error messages. The Qt library (debug mode) contains hundreds of warning messages that
are printed when internal errors (usually invalid function arguments) occur. Qt built in release mode also contains such warnings unless QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during compilation. If you implement your own message handler,
you get total control of these messages.
我们只需要把他的信息保留到txt文件中就可以了。
同时在代码里面定义个宏,
#ifndef QT_DEBUG installReleaseMsgHandler(); #endifDebug模式在QtCreater里面显示,Release模式编译输出文件流。
注意:
如果Release模式下,在软件运行输出日志到txt的时候,用户这时关闭软件,我们必须要有个关闭txt文件的操作。
这个时候你需要了解下 这个函数
void qAddPostRoutine(QtCleanUpFunction ptr)Adds a global routine that will be called from the QCoreApplication destructor. This function is normally
used to add cleanup routines for program-wide functionality.
以上基本就可以满足我们的要求了。
下来请赏脸看下我写的例子:
#include <QApplication> #include <stdio.h> #include <stdlib.h> #include <QCoreApplication> #include <QSettings> #include <QDebug> #include <QTime> #include <QDir> #define _TIME_ qPrintable(QTime::currentTime().toString("hh:mm:ss:zzz")) static FILE *q_fileStream = NULL; static int g_logLevel = 0; enum TraceLevel { TL_NULL = 0, TL_CRIT, TL_ERRO, TL_WARN, TL_INFO }; static const int g_TraceLevel [] = { TL_INFO, TL_WARN, TL_ERRO, TL_CRIT, TL_NULL }; static void SoftWareShutDown () { if (NULL != q_fileStream) { qDebug("Close log file."); fclose (q_fileStream); q_fileStream = NULL; } } void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { Q_UNUSED(type); QByteArray localMsg = msg.toLocal8Bit(); if (g_logLevel && q_fileStream) { int iLevel = g_TraceLevel[type]; if (g_logLevel < iLevel) { return; } fprintf (q_fileStream, "%s: %s (%s:%u, %s)\n", _TIME_, localMsg.constData(), context.file, context.line, context.function); fflush (q_fileStream); } } static void installMsgHandler(QString strLogFile) { QByteArray byteArrayLogFile = strLogFile.toLatin1(); if (NULL != q_fileStream) { fclose (q_fileStream); q_fileStream = NULL; } q_fileStream = fopen (byteArrayLogFile.constData (), "w+"); if (NULL != q_fileStream) { qDebug("Opened log file."); qInstallMessageHandler(myMessageOutput); } else { qDebug("Failed to open log file."); } } static void installReleaseMsgHandler () { QString strAppPath = QCoreApplication::applicationDirPath(); QString strIniFile = strAppPath + "/RunInfo.ini"; QString strLogFile = strAppPath + "/log.txt"; QSettings pSettings(strIniFile, QSettings::IniFormat); g_logLevel = pSettings.value("TraceSet/TraceLevel", 1).toInt(); installMsgHandler (strLogFile); } int main(int argc, char *argv[]) { QApplication a(argc, argv); #ifndef QT_DEBUG bool bAddQuitFunc = false; installReleaseMsgHandler(); if (!bAddQuitFunc) { qAddPostRoutine (SoftWareShutDown); bAddQuitFunc = true; } #endif Window w; w.show(); return a.exec(); }
运行顺序:
1. 判断是否为Release
2. installReleaseMsgHandler // 初始化 ini信息,和log文件位置
3. installMsgHandler // 打开文件,并调用 qInstallMessageHandler
4. myMessageOutput // 根据之前 读取的log等级 按照要求输出log
5. qAddPostRoutine // 检测软件是否关闭,调用关闭文件函数
6. SoftWareShutDown // 关闭文件
同时说明下,我的RunInfo.ini文件信息
就两行
[TraceSet]
TraceLevel=4
平时为1 ,当我们需要打log的时候改为4(全部信息,qDebug/qWarning/qCritical/qInfo),改为3的时候....自己试试吧。
上面代码的CSDN链接:http://download.csdn.net/detail/c3060911030/9464986
主要 ini文件要放置正确位置,在运行目录下。
相关文章推荐
- Qt输出日志文件
- QT5学习:分割窗口类的使用
- Qt之QLCDNumber
- Qt之QLCDNumber
- Qt Creator 窗体控件自适应窗口大小布局
- Qt之模型/视图(自定义进度条)
- Qt之模型/视图(自定义进度条)
- QT 格式化字符串功能
- qt中文乱码问题
- Qt在Windows下的三种编程环境搭建
- Qt学习之QSplitter分割窗口
- Qt串口通信接收数据不完整的解决方法
- Qt 错误总结
- Qt5.0解析JSON
- QML中的state 状态
- QT连接多种数据库f方法及测试
- Qt for Windows:Qt 5.6.0 MinGW 静态编译版本制作
- QT中的QPainter类
- vs2013+Qt5.5.1+opencv2.4.11配置
- Qt使用教程之指定编辑器设置