Qt单例模式的消息全局响应类

由来

在飞扬青云大佬的文章Qt开发经验里的第82条写道:

Qt的信号槽机制非常牛逼,也是Qt的独特的核心功能之一,有时候我们在很多窗体中传递信号来实现更新或者处理,如果窗体层级比较多,比如窗体A的父类是窗体B,窗体B的父类是窗体C,窗体C有个子窗体D,如果窗体A一个信号要传递给窗体D,问题来了,必须先经过窗体B中转到窗体C再到窗体D才行,这样的话各种信号关联信号的connect会非常多而且管理起来比较乱,可以考虑增加一个全局的单例类AppEvent,公共的信号放这里,然后窗体A对应信号绑定到AppEvent,窗体D绑定AppEvent的信号到对应的槽函数即可,干净清爽整洁。

代码

于是想办法写了一个类GlobalMessageHelper 注意这个类用的是单例的设计模式。
验证的思路是写了4个窗口ABCD,其中A点击按钮弹窗D,B点击按钮弹窗C,C里点击按钮将其中LineEdit输入的内容传递到D里去。如果普通的传递路线应该是C->B->main->A->D(当然可以直接C->D,但是如果项目里很多这种跨窗口的消息直接传递,就会形成飞扬大佬提到的复杂情况)。用GlobalMessageHelper 类后,就可以通过它实现所有sender和receiver直接连接。效果可以看下一节

// GlobalMessageHelper  h文件
#include <QWidget>
#include <QObject>
class GlobalMessageHelper : public QObject
{
  Q_OBJECT
public:

  ~GlobalMessageHelper();

  static GlobalMessageHelper *getInstance();

signals:
  void sendToAFromB(const QString &str);
  void sendToCFromD(const QString &str);
private:
  GlobalMessageHelper(QObject *parent = nullptr);
  static GlobalMessageHelper *gMessageHelper;
};


// cpp文件
#include "globalmessagehelper.h"
GlobalMessageHelper *GlobalMessageHelper::gMessageHelper;

GlobalMessageHelper::GlobalMessageHelper(QObject *parent) :
  QObject{parent}
{
}

GlobalMessageHelper::~GlobalMessageHelper()
{
}

GlobalMessageHelper *GlobalMessageHelper::getInstance()
{
  if (!GlobalMessageHelper::gMessageHelper)
    GlobalMessageHelper::gMessageHelper = new GlobalMessageHelper;

  return GlobalMessageHelper::gMessageHelper;
}


// DialogA  h文件
#include <QDialog>
#include <QWidget>
#include <QLineEdit>
class DialogA : public QDialog
{
  Q_OBJECT
public:
  DialogA(QDialog *parent = nullptr);
};


// DialogA  cpp文件
#include "dialoga.h"
#include "dialogd.h"
#include "globalmessagehelper.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QDebug>
DialogA::DialogA(QDialog *parent) : QDialog(parent)
{
  setWindowTitle("DialogA");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);
  QPushButton *btn = new QPushButton("BTN");
  lay->addWidget(btn);
  connect(btn, &QPushButton::clicked, this,
          [&]()
  {
    DialogD *dlg = new DialogD;
    dlg->show();
  });
}

// DialogB  h文件
#include <QDialog>
#include <QWidget>

class DialogB : public QDialog
{
  Q_OBJECT
public:
  DialogB(QDialog *parent = nullptr);
};


// DialogB  cpp文件
#include "dialogb.h"
#include "dialogc.h"
#include <QVBoxLayout>
#include <QPushButton>
DialogB::DialogB(QDialog *parent) : QDialog(parent)
{
  setWindowTitle("DialogB");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);
  QPushButton *btn = new QPushButton("BTN");
  lay->addWidget(btn);
  connect(btn, &QPushButton::clicked, this,
          [&]()
  {
    DialogC *dlg = new DialogC;
    dlg->show();
  });
}
// DialogC  h文件
#include <QDialog>
#include <QWidget>
#include <QLineEdit>
class DialogC : public QDialog
{
  Q_OBJECT
public:
  DialogC(QDialog *parent = nullptr);

private:
  QLineEdit *line = nullptr;
  QPushButton *btn = nullptr;
};


// DialogC  cpp文件
#include "dialogc.h"
#include "globalmessagehelper.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
DialogC::DialogC(QDialog *parent) : QDialog(parent)
{
  setWindowTitle("DialogC");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);

  line = new QLineEdit;
  lay->addWidget(line);
  btn = new QPushButton("Send");
  lay->addWidget(btn);
  connect(btn, &QPushButton::clicked, this,
          [&]()
  {
    emit GlobalMessageHelper::getInstance()->sendToAFromB(line->text());
  });
}

// DialogD  h文件
#include <QDialog>
#include <QWidget>
class QLineEdit;
class DialogD : public QDialog
{
public:
  DialogD();
  QLineEdit *line = nullptr;
};


// DialogD  cpp文件
#include "dialogd.h"
#include "globalmessagehelper.h"
#include <QLineEdit>
#include <QVBoxLayout>
DialogD::DialogD()
{
  setWindowTitle("DialogD");
  setMinimumSize(QSize(300, 100));
  QVBoxLayout *lay = new QVBoxLayout;
  setLayout(lay);
  line = new QLineEdit;
  lay->addWidget(line);
  connect(GlobalMessageHelper::getInstance(), &GlobalMessageHelper::sendToAFromB, this,
          [&](const QString &s)
  {
    Q_ASSERT(GlobalMessageHelper::getInstance() != nullptr);

    line->setText(s);
  });
}

// main.cpp  文件

#include "globalmessagehelper.h"
#include "dialoga.h"
#include "dialogc.h"
#include "dialogb.h"

#include <QApplication>

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

  DialogA dlgA;
  DialogB dlgB;
  dlgA.show();
  dlgB.show();
  return a.exec();
}

结果

结果

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值