Qt:单例日志记录类在插件和线程中获得不同的实例

时间:2011-12-17 17:05:13

标签: qt thread-safety singleton

我花了好几个小时试图理解为什么我的记录器类不起作用。 我的想法是将现有的 qDebug qWarning qFatal 挂钩到我的一个插槽中,并使用新的扩展宏列表(这个例子中的qInfo ) 我试图遵循以下准则: Using a Singleton Class across a Qt Application and its Plugins

#pragma once

#include <QtGui>
#include <QMutex>

//! Creates a fake call, to have a cleaner design.
extern void qInfo(const char* fmt);

#define QtTraceMsg  QtMsgType(6)
#define QtInfoMsg   QtMsgType(7)

class MsgHandler: public QObject
{
    Q_OBJECT

signals:
    void newMsg(QtMsgType type, const QString &msg);

public:
    static MsgHandler *instance();
    static void Handler(QtMsgType type, const char *msg);

private:
    MsgHandler() { qRegisterMetaType<QtMsgType>("QtMsgType"); } // important
    static MsgHandler* _instance;
};

和cpp:

#include "MsgHandler.h"

MsgHandler* MsgHandler::_instance = NULL;

MsgHandler * MsgHandler::instance()
{
    static QMutex mutex;

    if (_instance == NULL)
    {
        mutex.lock();
        if (_instance == NULL)
            _instance = new MsgHandler;
        mutex.unlock();
    }

    return _instance;
}

void MsgHandler::Handler(QtMsgType type, const char *msg)
{
    QString s = msg;
    emit instance()->newMsg(type, s);
}

///////////////////////////////////////////////////////////////////////////////
void qInfo(const char *msg)
{
    MsgHandler::instance()->Handler(QtInfoMsg, msg);
}

然后在主要我注册我的处理程序

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Handle error messages
    qInstallMsgHandler(MsgHandler::Handler);
}

一切都在主线程中完美运行。但是从一个运行自己的线程的插件中它失败了:

void MyPlugin::run()
{
    qWarning("Test debug"); //works fine
    MsgHandler::instance()->Handler(QtInfoMsg, "info 2"); //creates a new instance!
    qInfo("test info"); //also creates a new instance!
}

1 个答案:

答案 0 :(得分:3)

解决方案是将指向MsgHandler的指针传递给每个插件。