【无标题】Qt实现全局观察者模式(多层窗体之间直接传递消息)--根据原文件改编。后面添加了没有的代码,根据个人理解编写

近来做项目发现,多个窗体之间要通信真的好麻烦,比如:A调出B,B调出C,那么C给A发消息,那就得经过B转发才能实现。对于两三层窗体,这种方法还可以接受,但嵌套太多就有点烦人了。
基于这个原因,那么要实现的东西就很清楚了,有一个全局类,去直接绑定信号槽关系,在需要触发的时候,通过这个全局类的函数,去相应的触发一下,就可以实现直连通信了。

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:
    //因为是全局只有一个,所以直接单例模式
    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);
    //触发
    void notify(const QString type);
private:
    explicit globalObserver(QObject *parent = 0);
    ~globalObserver();

private:
    QList<relationData*> m_oRelationList;
};

#endif // GLOBALOBSERVER_H
  • relationData:结构体,保存对应关系;
  • relationData::type:字符串类型,就相当于信号的唯一标识符
  • relationData::reciver:信号接收者,保存这个变量主要实在detach的时候去使用。
  • relationData::obesrverApater;这个类的作用就很重要了,具体看该类的详解。

obesrverApater.h

#ifndef OBESRVERAPATER_H
#define OBESRVERAPATER_H

#include <QObject>
class obesrverApater;

//工厂,方便构造对象
class obesrverApaterFactory
{
public:
    static obesrverApaterFactory *getInst();
    static void realese();
    static obesrverApaterFactory* inst;

    obesrverApater* createObesrverApater();

private:
    obesrverApaterFactory()
    {}
};

//中间层,用来连接信号槽
class obesrverApater : public QObject
{
    Q_OBJECT
public:
    explicit obesrverApater(QObject *parent = 0);

signals:
    void notify();
};

#endif // OBESRVERAPATER_H
  • obesrverApater:该类的主要目的是attach的时候,将传进来的槽函数直接绑定到改类的notify信号,因为传进来的槽函数,要想在触发时去掉用拿不到函数名称,所以借助中间层直接绑定,在触发的时候直接去触发中间层的信号,就可达到目的。
  • obesrverApaterFactory:创建中间层的工厂,方便类创建。
  • 接下来就主要看看具体函数的实现了:

  • #include "obesrverApater.h"
    obesrverApaterFactory* obesrverApaterFactory::inst;
    
    obesrverApaterFactory* obesrverApaterFactory::getInst()
    {
    	if (!inst)
    	{
    		inst = new obesrverApaterFactory();
    	}
    	return inst;
    }
    
    void obesrverApaterFactory::realese()
    {
    	if (inst)
    	{
    		delete inst;
    	}
    }
    
    obesrverApater* obesrverApaterFactory::createObesrverApater()
    {
    	return new obesrverApater(nullptr);
    }
    
    obesrverApater::obesrverApater(QObject* parent)
    {
    
    }
    obesrverApater::~obesrverApater()
    {
    
    }

  • 工厂类去创建中间层对象实体
  • obesrverApater *obesrverApaterFactory::createObesrverApater()
    {
        return new obesrverApater();
    }
  • globalObserver* globalObserver::m_pInst;
    globalObserver::globalObserver(QObject* parent)
    {
    
    }
    
    globalObserver::~globalObserver()
    {
    	//释放列表数据
    	QList<relationData*>::iterator iter = m_oRelationList.begin();
    
    	while (iter != m_oRelationList.end())
    	{
    		delete (*iter)->obesrverApater;
    		delete* iter;
    		iter++;
    	}
    
    }
    
    globalObserver* globalObserver::getGlobalObserver()
    {
    	if (!m_pInst)
    	{
    		m_pInst = new globalObserver();
    	}
    	return m_pInst;
    }
    
    void globalObserver::release()
    {
    	if (m_pInst)
    		delete m_pInst;
    }
    

  • 观察者绑定函数实现
  • 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);
    }

    - 观察者解绑函数实现

    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++;
        }
    }
  • 观察者触发函数实现
  • 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++;
        }
    }
  • 程序结束时别忘了销毁
  • globalObserver::~globalObserver()
    {
        //释放列表数据
        QList<relationData*>::iterator iter = m_oRelationList.begin();
    
        while (iter != m_oRelationList.end())
        {
            delete (*iter)->obesrverApater;
            delete *iter;
            iter++;
        }
    
    }

    测试:

  • 测试代码
  • 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");
    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT C++中,可以使用信号和槽机制来实现观察者模式的异步通信。 具实现步骤如下: 1. 定义一个观察者类,其中包含一个槽函数,用于处理被观察者发出的信号。 2. 定义一个被观察者类,其中包含一个信号,用于通知观察者。 3. 在被观察者类中,发出信号时调用 emit 关键字,并传递需要传递的参数。 4. 在观察者类中,将自己的槽函数与被观察者的信号连接起来,使用 connect 函数实现连接。 这样,当被观察者发出信号时,观察者的槽函数会被自动调用,实现了异步通信。 下面是一个简单的示例代码: ``` // 观察者类 class Observer : public QObject { Q_OBJECT public slots: void handleMessage(const QString& message) { qDebug() << "Received message: " << message; } }; // 被观察者类 class Subject : public QObject { Q_OBJECT signals: void messageReceived(const QString& message); public: void sendMessage(const QString& message) { emit messageReceived(message); } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建观察者和被观察者对象 Observer observer; Subject subject; // 将观察者的槽函数与被观察者的信号连接起来 QObject::connect(&subject, SIGNAL(messageReceived(QString)), &observer, SLOT(handleMessage(QString))); // 发送消息 subject.sendMessage("Hello World!"); return a.exec(); } ``` 在上面的示例代码中,当被观察者发出 messageReceived 信号时,观察者的 handleMessage 槽函数会被自动调用,并输出接收到的消息

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值