为了方便进行现场调试,我们需要使用日志记录我们关心的数据信息,而Qt提供了日志系统非常方便,只需要我们提供一个函数指针即可,定义如下
void myMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
通常,实现如下
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
static QMutex mutex;
mutex.lock();
QString text;
switch (type)
{
case QtDebugMsg:
text = QString("Debug:");
break;
case QtWarningMsg:
text = QString("Warning:");
break;
case QtCriticalMsg:
text = QString("Critical:");
break;
case QtFatalMsg:
text = QString("Fatal:");
}
QString contextInfo = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
QString currentDate = QString("(%1)").arg(currentDateTime);
QString message = QString("%1 %2 %3 %4").arg(text).arg(contextInfo).arg(msg).arg(currentDate);
QFile file("log.txt");
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream text_stream(&file);
text_stream << message << "\r\n";
file.flush();
file.close();
mutex.unlock();
}
使用
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qInstallMessageHandler(outputMessage);
return a.exec();
}
这样既捕获了我们代码中qDebug()的输出,重置时,qInstallMessageHandler(0)即可。但是,由于涉及文件IO,这样的耗时操作往往需要线程配合,我们优化如下
日志信息
class Loger : public QObject
{
Q_OBJECT
public:
explicit Loger(QObject *parent = nullptr);
static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);
signals:
void sig_sendMessage(QString mesg);
};
static Loger* g_log = nullptr;
Loger::Loger(QObject *parent) : QObject(parent)
{
g_log = this;
}
void Loger::outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QString text;
switch (type)
{
case QtDebugMsg:
text = QString("Debug:");
break;
case QtWarningMsg:
text = QString("Warning:");
break;
case QtCriticalMsg:
text = QString("Critical:");
break;
case QtFatalMsg:
text = QString("Fatal:");
}
QString contextInfo = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
QString currentDate = QString("(%1)").arg(currentDateTime);
QString message = QString("%1 %2 %3 %4").arg(text).arg(contextInfo).arg(msg).arg(currentDate);
emit g_log->sig_sendMessage(message);
}
日志写入
class LogWrite : public QObject
{
Q_OBJECT
public:
explicit LogWrite(QObject *parent = nullptr);
~LogWrite();
public slots:
void slot_writeInfo(QString info);
private:
QThread *m_pThread;
};
LogWrite::LogWrite(QObject *parent) : QObject(parent)
{
m_pThread = new QThread;
this->moveToThread(m_pThread);
m_pThread->start();
}
LogWrite::~LogWrite()
{
m_pThread->terminate();
m_pThread->deleteLater();
m_pThread = nullptr;
}
void LogWrite::slot_writeInfo(QString info)
{
QFile file("log.txt");
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream text_stream(&file);
text_stream << info << "\r\n";
file.flush();
file.close();
}
使用
Loger log;
LogWrite logWrite;
qInstallMessageHandler(&Loger::outputMessage);
QObject::connect(&log, &Loger::sig_sendMessage, &logWrite, &LogWrite::slot_writeInfo);
由于,写入log位于线程中,即连接方式为队列,因此相当安全。
本想着使用Qt线程的高级模块,对此的问题仍然。