小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Qt實(shí)現(xiàn)全局觀察者模式(多層窗體之間直接傳遞消息)

 slimfeng 2019-02-12
近來做項(xiàng)目發(fā)現(xiàn),多個(gè)窗體之間要通信真的好麻煩,比如:A調(diào)出B,B調(diào)出C,那么C給A發(fā)消息,那就得經(jīng)過B轉(zhuǎn)發(fā)才能實(shí)現(xiàn)。對(duì)于兩三層窗體,這種方法還可以接受,但嵌套太多就有點(diǎn)煩人了。
基于這個(gè)原因,那么要實(shí)現(xiàn)的東西就很清楚了,有一個(gè)全局類,去直接綁定信號(hào)槽關(guān)系,在需要觸發(fā)的時(shí)候,通過這個(gè)全局類的函數(shù),去相應(yīng)的觸發(fā)一下,就可以實(shí)現(xiàn)直連通信了。12

globalObserver.h

#ifndef GLOBALOBSERVER_H
#define GLOBALOBSERVER_H

#include <QObject>
#include "obesrverApater.h"

struct relationData
{
    QString type;
    QObject *reciver;
    obesrverApater *obesrverApater;
};

class globalObserver : public QObject
{
    Q_OBJECT
public:
    //因?yàn)槭侨种挥幸粋€(gè),所以直接單例模式
    static globalObserver* getGlobalObserver();
    static void release();
    static globalObserver *m_pInst;
    //綁定
    void attach(const QString type, QObject *reciver, const char *method);
    //解綁
    void detach(const QString type, const QObject* reciver);
    //觸發(fā)
    void notify(const QString type);
private:
    explicit globalObserver(QObject *parent = 0);
    ~globalObserver();

private:
    QList<relationData*> m_oRelationList;
};

#endif // GLOBALOBSERVER_H123456789101112131415161718192021222324252627282930313233343536
  • relationData:結(jié)構(gòu)體,保存對(duì)應(yīng)關(guān)系;

  • relationData::type:字符串類型,就相當(dāng)于信號(hào)的唯一標(biāo)識(shí)符

  • relationData::reciver:信號(hào)接收者,保存這個(gè)變量主要實(shí)在detach的時(shí)候去使用。

  • relationData::obesrverApater;這個(gè)類的作用就很重要了,具體看該類的詳解。

obesrverApater.h

#ifndef OBESRVERAPATER_H
#define OBESRVERAPATER_H

#include <QObject>
class obesrverApater;

//工廠,方便構(gòu)造對(duì)象
class obesrverApaterFactory
{
public:
    static obesrverApaterFactory *getInst();
    static void realese();
    static obesrverApaterFactory* inst;

    obesrverApater* createObesrverApater();

private:
    obesrverApaterFactory()
    {}
};

//中間層,用來連接信號(hào)槽
class obesrverApater : public QObject
{
    Q_OBJECT
public:
    explicit obesrverApater(QObject *parent = 0);

signals:
    void notify();
};

#endif // OBESRVERAPATER_H123456789101112131415161718192021222324252627282930313233
  • obesrverApater:該類的主要目的是attach的時(shí)候,將傳進(jìn)來的槽函數(shù)直接綁定到改類的notify信號(hào),因?yàn)閭鬟M(jìn)來的槽函數(shù),要想在觸發(fā)時(shí)去掉用拿不到函數(shù)名稱,所以借助中間層直接綁定,在觸發(fā)的時(shí)候直接去觸發(fā)中間層的信號(hào),就可達(dá)到目的。

  • obesrverApaterFactory:創(chuàng)建中間層的工廠,方便類創(chuàng)建。

  • -


接下來就主要看看具體函數(shù)的實(shí)現(xiàn)了:

  • 工廠類去創(chuàng)建中間層對(duì)象實(shí)體

obesrverApater *obesrverApaterFactory::createObesrverApater()
{
    return new obesrverApater();
}1234
  • 觀察者綁定函數(shù)實(shí)現(xiàn)

void globalObserver::attach(const QString type, QObject *reciver, const char *method)
{
    obesrverApater *oA = obesrverApaterFactory::getInst()->createObesrverApater();
    connect(oA, SIGNAL(notify()), reciver, method);
    relationData *data = new relationData();
    data->type = type;
    data->reciver = reciver;
    data->obesrverApater = oA;
    m_oRelationList.append(data);
}12345678910

- 觀察者解綁函數(shù)實(shí)現(xiàn)

void globalObserver::detach(const QString type, const QObject *reciver)
{
    QList<relationData*>::iterator iter = m_oRelationList.begin();

    while (iter != m_oRelationList.end())
    {
        if ((*iter)->type.compare(type) == 0 && (*iter)->reciver == reciver)
        {
            relationData *data = *iter;
            m_oRelationList.removeOne((*iter));

            delete data->obesrverApater;
            delete data;
            return;
        }
        iter++;
    }
}123456789101112131415161718
  • 觀察者觸發(fā)函數(shù)實(shí)現(xiàn)

void globalObserver::notify(const QString type)
{
    QList<relationData*>::iterator iter = m_oRelationList.begin();
    while (iter != m_oRelationList.end())
    {
        if ((*iter)->type.compare(type) == 0)
        {
            emit (*iter)->obesrverApater->notify();
        }
        iter++;
    }
}123456789101112
  • 程序結(jié)束時(shí)別忘了銷毀

globalObserver::~globalObserver()
{
    //釋放列表數(shù)據(jù)
    QList<relationData*>::iterator iter = m_oRelationList.begin();

    while (iter != m_oRelationList.end())
    {
        delete (*iter)->obesrverApater;
        delete *iter;
        iter++;
    }

}12345678910111213

測(cè)試:

  • 測(cè)試代碼

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    globalObserver::getGlobalObserver()->attach("haha", this, SLOT(haha()));
    globalObserver::getGlobalObserver()->attach("hehe", this, SLOT(hehe()));

    QPushButton *p = new QPushButton("haha", this);
    connect(p, SIGNAL(clicked()), this, SLOT(onHaha()));
    p->setGeometry(10, 10, 200, 40);
}

Widget::~Widget()
{
    globalObserver::getGlobalObserver()->detach("haha", this);
    globalObserver::getGlobalObserver()->detach("hehe", this);
}

void Widget::haha()
{
    QMessageBox::about(this, "", "haha");

}

void Widget::hehe()
{
    QMessageBox::about(this, "", "hehe");
}

void Widget::onHaha()
{
    globalObserver::getGlobalObserver()->notify("haha");
}1234567891011121314151617181920212223242526272829303132

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多