//Qt5开始提供了日志上下文信息输出,比如输出当前打印消息所在的代码文件、行号、函数名等。 //如果是release还需要在pro中加上 DEFINES += QT_MESSAGELOGCONTEXT 才能输出上下文,默认release关闭的。 //切记不要在日志钩子函数中再写qdebug之类的,那样就死循环了。 //日志重定向一般就三种处理 //1: 输出到日志文件比如txt文本文件。 //2: 存储到数据库,可以分类存储,以便相关人员查询分析。 //3: 重定向到网络,对方用小工具连接程序后,所有打印信息通过tcp发过去。 //日志重定向 #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) void Log(QtMsgType type, const QMessageLogContext &context, const QString &msg) #else void Log(QtMsgType type, const char *msg) #endif { //加锁,防止多线程中qdebug太频繁导致崩溃 static QMutex mutex; QMutexLocker locker(&mutex); QString content; //这里可以根据不同的类型加上不同的头部用于区分 switch (type) { case QtDebugMsg: content = QString("%1").arg(msg); break; case QtWarningMsg: content = QString("%1").arg(msg); break; case QtCriticalMsg: content = QString("%1").arg(msg); break; case QtFatalMsg: content = QString("%1").arg(msg); break; } //加上打印代码所在代码文件、行号、函数名 #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) if (SaveLog::Instance()->getUseContext()) { int line = context.line; QString file = context.file; QString function = context.function; if (line > 0) { content = QString("行号: %1 文件: %2 函数: %3\n%4").arg(line).arg(file).arg(function).arg(content); } } #endif //将内容传给函数进行处理 SaveLog::Instance()->save(content); } //安装日志钩子,输出调试信息到文件,便于调试 void SaveLog::start() { #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) qInstallMessageHandler(Log); #else qInstallMsgHandler(Log); #endif } //卸载日志钩子 void SaveLog::stop() { #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) qInstallMessageHandler(0); #else qInstallMsgHandler(0); #endif }