近来做项目发现,多个窗体之间要通信真的好麻烦,比如:A调出B,B调出C,那么C给A发消息,那就得经过B转发才能实现。对于两三层窗体,这种方法还可以接受,但嵌套太多就有点烦人了。 基于这个原因,那么要实现的东西就很清楚了,有一个全局类,去直接绑定信号槽关系,在需要触发的时候,通过这个全局类的函数,去相应的触发一下,就可以实现直连通信了。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: //因为是全局只有一个,所以直接单例模式 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_H123456789101112131415161718192021222324252627282930313233343536
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_H123456789101112131415161718192021222324252627282930313233
接下来就主要看看具体函数的实现了:
obesrverApater *obesrverApaterFactory::createObesrverApater() { return new obesrverApater(); }1234
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 - 观察者解绑函数实现 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
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
globalObserver::~globalObserver() { //释放列表数据 QList<relationData*>::iterator iter = m_oRelationList.begin(); while (iter != m_oRelationList.end()) { delete (*iter)->obesrverApater; delete *iter; iter++; } }12345678910111213 测试:
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 |
|