Qt: класс одиночного журналирования получает разные экземпляры по плагинам и потокам - PullRequest
1 голос
/ 17 декабря 2011

Я часами пытался понять, почему мой класс логгера не работает. Идея состоит в том, чтобы подключить существующие qDebug , qWarning и qFatal к одному из моих слотов, а также расширить список макросов новыми ( qInfo * 1008). * в этом примере) Я пытался следовать следующим рекомендациям: Использование класса Singleton в приложении Qt и его плагинах

#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 Ответ

3 голосов
/ 15 января 2012

Решение состоит в том, чтобы передать указатель на MsgHandler каждому плагину.

...