Qt 中的信号与槽,连接日志库QsLog,在界面上显示出日志信息
新建一个基于QWidget的工程,在界面上添加一个QTextBrowser控件,用来在界面显示日志信息。
在pro文件中添加QsLog的头文件和lib库
INCLUDEPATH += include/QsLog.h \
include/QsLogDest.h \
include/QsLogDestConsole.h \
include/QsLogDestFile.h \
include/QsLogDestFunctor.h \
include/QsLogDisableForThisFile.h \
include/QsLogLevel.h
LIBS += $$PWD/lib/QsLog2.lib
在widget.h中添加槽函数:
public slots:
void logSlot(const QString &message, int level);
widget.h文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void initLogger();
void destroyLogger();
public slots:
void logSlot(const QString &message, int level);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp文件:
#include "widget.h"
#include "ui_widget.h"
#include "include/QsLog.h"
#include "include/QsLogDest.h"
#include <QCoreApplication>
#include <QDir>
//#include <iostream>
using namespace QsLogging;
/*
void logFunction(const QString &message, QsLogging::Level level)
{
std::cout << "From log function: " << qPrintable(message) << " " << static_cast<int>(level)
<< std::endl;
}
*/
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
initLogger();
}
Widget::~Widget()
{
delete ui;
destroyLogger();
}
void Widget::initLogger()
{
// 1. init the logging mechanism
Logger& logger = Logger::instance();
logger.setLoggingLevel(QsLogging::TraceLevel);
//设置log位置
const QString sLogPath(QDir(QCoreApplication::applicationDirPath()).filePath("log.txt"));
// 2. add two destinations
DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(
sLogPath, EnableLogRotation, MaxSizeBytes(512), MaxOldLogCount(2)));
DestinationPtr debugDestination(DestinationFactory::MakeDebugOutputDestination());
//DestinationPtr functorDestination(DestinationFactory::MakeFunctorDestination(&logFunction));
//这样和槽函数连接
DestinationPtr sigsSlotDestination(DestinationFactory::MakeFunctorDestination(this, SLOT(logSlot(QString,int))));
logger.addDestination(debugDestination);
logger.addDestination(fileDestination);
//logger.addDestination(functorDestination);
logger.addDestination(sigsSlotDestination);
// 3. start logging
QLOG_INFO() << "Program started";
QLOG_INFO() << "Built with Qt" << QT_VERSION_STR << "running on" << qVersion();
QLOG_TRACE() << "Here's a" << QString::fromUtf8("trace") << "message";
QLOG_DEBUG() << "Here's a" << static_cast<int>(QsLogging::DebugLevel) << "message";
QLOG_WARN() << "Uh-oh!";
qDebug() << "This message won't be picked up by the logger";
QLOG_ERROR() << "An error has occurred";
qWarning() << "Neither will this one";
QLOG_FATAL() << "Fatal error!";
}
void Widget::destroyLogger()
{
QsLogging::Logger::destroyInstance();
}
void Widget::logSlot(const QString &message, int level)
{
ui->textBrowser->append(qPrintable(message));
}
运行效果:
查看函数调用过程:
DestinationPtr DestinationFactory::MakeFunctorDestination(QsLogging::Destination::LogFunction f)
{
return DestinationPtr(new FunctorDestination(f));
}
stinationPtr DestinationFactory::MakeFunctorDestination(QObject *receiver,
const char *member)
{
return DestinationPtr(new FunctorDestination(receiver, member));
}
继续看FunctorDestination的构造函数:
只有两个构造函数
explicit FunctorDestination(LogFunction f);
FunctorDestination(QObject *receiver, const char *member);
第二个构造函数,找到了连接信号与槽的地方,这就是我们需要的函数。
QsLogging::FunctorDestination::FunctorDestination(QObject *receiver, const char *member)
: QObject(NULL)
, mLogFunction(NULL)
{
connect(this, SIGNAL(logMessageReady(QString,int)), receiver, member, Qt::QueuedConnection);
}