在飞扬青云大佬的文章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();
}
结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)