QT窗口容器层层嵌套过于耦合的解决办法

目录

零、多层嵌套窗口使用信号槽通信遇到的问题

一、单例模式的消息中间类

1.创建消息中间类

transmitsignals.h内容如下:

transmitsignals.cpp内容如下:

2.在需要发信号的sender类中使用

3.需要接收信号的receiver类中使用

MainWindow::doProcessReceiveMsg槽函数:

4.点击按钮测试是否可行

5.使用消息中间类可能会遇到一些问题

6.其他方法

1.)观察者模式

2.)循环发送,定时接收的情况


零、多层嵌套窗口使用信号槽通信遇到的问题

稍微复杂点的项目可能就会遇到一个窗口套一个窗口的情况,两个窗口之间使用信号槽还是很方便的,一但嵌套的层数在三个以上,使用信号槽就有点麻烦,比如下图这种。

 第一个窗口套第二个窗口,第二个窗口里面有第三个窗口,而有时候第三个窗口需要直接给第一个窗口发信息,但是第一个窗口没有关联第三个窗口,所以只能先向第二个窗口发信号,再由第二个窗口向第一个窗口发信号。

好像也不是太麻烦,但如果层次再深一点呢?五层、六层、七层.....如果还是层层传递信号,工作量增加不说,写出来的代码也不便阅读。

那么怎么解决这个问题?QT是否有提供轮子?QT的事件机制似乎全局都可以接收,那么是否可以用自定义事件来解决?答案是否定的。

QEvent或者自定义Event需要指定*receiver才能发送,然后在receiver中通过event()或者customEvent()方法接收,这其实已经跟信号槽很相似了。

是否还有别的办法?答案是有的。

一、单例模式的消息中间类

第一种办法是创建并使用单例模式的消息中间类,直接由消息中间类发信号,接收的窗口类绑定这个信号,并实现槽函数。

1.创建消息中间类

transmitsignals.h内容如下:

#ifndef TRANSMITSIGNALS_H
#define TRANSMITSIGNALS_H

#include <QObject>

class TransmitSignals : public QObject
{
    Q_OBJECT
public:
    static TransmitSignals &GetInstance();
private:
    TransmitSignals();
     ~TransmitSignals();

    TransmitSignals(const TransmitSignals &) = delete;
    TransmitSignals(const TransmitSignals &&) = delete;
    TransmitSignals &operator=(const TransmitSignals &) = delete;



signals:
    void SignalSendMsg(const QString msg);
    void SignalSendFlag(const bool ret);

public slots:
};

#endif // TRANSMITSIGNALS_H

transmitsignals.cpp内容如下:

#include "transmitsignals.h"

TransmitSignals::TransmitSignals( )
{

}

TransmitSignals::~TransmitSignals( )
{

}
TransmitSignals& TransmitSignals::GetInstance()
{
    static TransmitSignals RobotControl;
    return RobotControl;
}

2.在需要发信号的sender类中使用

connect(m_sendBtn, &QPushButton::clicked, this, [&]{ TransmitSignals::GetInstance().SignalSendFlag(true); });

3.需要接收信号的receiver类中使用

connect(&TransmitSignals::GetInstance(), &TransmitSignals::SignalSendFlag, this, &MainWindow::doProcessReceiveMsg  );

MainWindow::doProcessReceiveMsg槽函数:

void MainWindow::doProcessReceiveMsg(bool)
{
    QMessageBox::information(this, "msg", "接收到了!");
}

实现很简单,只是在接收到后打印信息。

4.点击按钮测试是否可行

从测试结果来说是可行的。 

5.使用消息中间类可能会遇到一些问题

比如可能有很多的信号,都放在一个类可能会很臃肿,比如多个类的信号集中在一个类中发送,可能会给阅读代码带来不便。这时或许应该按模块来构造消息中间类。

6.其他方法

1.)观察者模式

参考 Qt实现全局观察者模式(多层窗体之间直接传递消息)-支持传参

大佬的方法测试了一下,发现如果想要传参,需要根据参数的个数和类型写匹配规则,工作量巨大,最终放弃。

2.)循环发送,定时接收的情况

这样一个场景,多个发送者,每个发送者是一个定时器,一秒发送一次数据,让接收者更新界面,这时如果选择信号槽可能会降低系统效率,使用数据库的写入和读取、redis、RabbitMQ等消息中间件可能是一个更好的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值