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

Qt单例模式的消息全局响应类,第1张

由来

在飞扬青云大佬的文章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窗D,B点击按钮d窗C,C里点击按钮将其中LineEdit输入的内容传递到D里去。如果普通的传递路线应该是C->B->main->A->D(当然可以直接C->D,但是如果项目里很多这种跨窗口的消息直接传递,就会形成飞扬大佬提到的复杂情况)。用GlobalMessageHelper 类后,就可以通过它实现所有sender和receiver直接连接。效果可以看下一节

// GlobalMessageHelper  h文件
#include 
#include 
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 
#include 
#include 
class DialogA : public QDialog
{
  Q_OBJECT
public:
  DialogA(QDialog *parent = nullptr);
};


// DialogA  cpp文件
#include "dialoga.h"
#include "dialogd.h"
#include "globalmessagehelper.h"
#include 
#include 
#include 
#include 
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 
#include 

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


// DialogB  cpp文件
#include "dialogb.h"
#include "dialogc.h"
#include 
#include 
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 
#include 
#include 
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 
#include 
#include 
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 
#include 
class QLineEdit;
class DialogD : public QDialog
{
public:
  DialogD();
  QLineEdit *line = nullptr;
};


// DialogD  cpp文件
#include "dialogd.h"
#include "globalmessagehelper.h"
#include 
#include 
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 

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

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

结果

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1353106.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-14
下一篇 2022-06-14

发表评论

登录后才能评论

评论列表(0条)

保存