Qt 全局信号转发单例类

前言

Qt项目开发,信号槽是必然使用到的。简单项目直接绑定对象信号传递没问题,但项目稍具规模对象父子关系变多,那么信号的传递必然要跨越多层,需要多层连续转发,这种多层传递是可以使用,原理上也没有任何问题,但是增大了代码复杂度也容易遗漏造成逻辑错误。这时可以考虑引入全局信号转发类优化代码,优雅的解决此问题。

原理

思路其实很简单,对于三层关系A-B-C,A到C的信号通知可以通过B来转发。但实际开发项目中的层级关系往往更深,A-B-C-D、A-B-C-D-E大于三层这种占比更大。增加一个全局信号单例类便可以只进行一次转发即可,如A-转发类-D,A-转发类-E。因为一般只是转发没什么太大性能消耗,所以一个全局转发类设置为单例即可,当然设置多个全局转发类也可以但没必要。

代码

代码摘抄自个人FFmpeg播放器核心剖析AVPlayer项目中。对于单例模式网上资料很多不再赘述,个人喜欢饿汉模式,主要原因有两点:1.不需要考虑线程安全性问题 2. 单例既然设计一般程序逻辑中或早或晚都是会用到的,不如直接创建准备好,内存优先级小于程序稳定性。选择因人而异,下面贴出代码。

头文件

#ifndef GLOBAL_H
#define GLOBAL_H

#include <QObject>

//全局信号转发单例类
class GlobalObj : public QObject
{
    Q_OBJECT

public:
    //获取单实例
    static GlobalObj* getInstance();
    //释放单实例
    static void deleteInstance();

signals:
    //时长
    void sigMediaDuration(int duration);
    //播放位置
    void sigSendPlayPos(qint64 pos);
    //播放结束
    void sigMediaFinish();


private:
    //构造、析构、拷贝构造、赋值构造私有
    GlobalObj(){}
    ~GlobalObj(){}
    GlobalObj(const GlobalObj &){}
    const GlobalObj &operator=(const GlobalObj &){}

private:
    //单实例对象指针
    static GlobalObj *obj;
};


//全局参数类
class GlobalData
{
public:
    static QString version;
};

实现文件

#include "global.h"

//全局信号转发单例类
GlobalObj* GlobalObj::obj = new GlobalObj();
GlobalObj *GlobalObj::getInstance()
{
    return obj;
}

void GlobalObj::deleteInstance()
{
    if(obj)
    {
        delete obj;
        obj = nullptr;
    }
}

//全局参数类
QString GlobalData::version = "1.0";

更新版

更新新的单例实现方式,基于C++11

class GlobalObj : public QObject
{
    Q_OBJECT

public:
    //获取单实例 线程安全
    //静态局部变量只在第一次被调用时初始化,位于静态存储区,生命周期从初始化起至程序结束止
    static GlobalObj *getInstance()
    {
        static GlobalObj obj;
        return &obj;
    }
    
signals:
    //时长
    void sigMediaDuration(int duration);
    //播放位置
    void sigSendPlayPos(qint64 pos);
    //播放结束
    void sigMediaFinish();

private:
    //构造、析构、拷贝构造、赋值构造私有
    GlobalObj(){}
    ~GlobalObj(){}
    GlobalObj(const GlobalObj &) = delete; 
    const GlobalObj &operator=(const GlobalObj &) = delete;  
};

调用示例

 //底层信号发至转发类
 GlobalObj *obj = GlobalObj::getInstance();
 connect(this, &AVDemuxer::sigMediaDuration, obj, &GlobalObj::sigMediaDuration);
 connect(this, &AVDemuxer::sigMediaFinish, obj, &GlobalObj::sigMediaFinish);
 //to do other..
   
 //转发类信号发至界面
 GlobalObj *obj = GlobalObj::getInstance();
 connect(obj, &GlobalObj::sigMediaDuration, this, &Widget::slotMediaDuration);
 connect(obj, &GlobalObj::sigSendPlayPos, this, &Widget::slotSendPlayPos);
 connect(obj, &GlobalObj::sigMediaFinish, this, &Widget::slotMediaFinish);
 //to do other..
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Qt是一个功能强大的C++跨平台应用程序开发框架。Qt中提供了单例模式的实现方法,在Qt中实现一个单例需要使用Q_GLOBAL_STATIC宏来创建单例,并使用connect()连接信号和槽。 全局信号是指可以被应用程序中的任何对象接收的信号。由于应用程序中的对象可以在应用程序的不同线程中运行,因此使用单例模式实现全局信号是一个很好的解决方案。 单例模式是一种创建单个实例的方式,确保只有一个实例被创建并在应用程序的整个生命周期中使用。Qt中使用Q_GLOBAL_STATIC宏定义单例,该宏的第一个参数是单例型。 例如,下面的代码定义了一个名为MySingleton的单例: ``` class MySingleton { public: static MySingleton* getInstance(); private: MySingleton(); Q_DISABLE_COPY(MySingleton) }; MySingleton *MySingleton::getInstance() { static const QScopedPointer<MySingleton> instance(new MySingleton()); return instance.data(); } typedef QGlobalStatic<MySingleton> MySingletonPtr; Q_GLOBAL_STATIC(MySingletonPtr, mySingleton) ``` 全局信号可以使用Qt中的QObject来实现。QObject中定义了signal和slot,可以在应用程序中的不同对象之间传递消息和数据。 为了实现全局信号,可以在单例中添加一个QObject对象,并在其中定义信号和槽。在接收信号的对象中,可以使用connect()函数将对象的槽函数连接到全局信号。 例如,下面的代码向MySingleton中添加了一个QObject对象,并定义一个全局信号: ``` class MySingleton : public QObject { public: static MySingleton* getInstance(); signals: void mySignal(); private: MySingleton(); Q_DISABLE_COPY(MySingleton) }; MySingleton *MySingleton::getInstance() { static const QScopedPointer<MySingleton> instance(new MySingleton()); return instance.data(); } typedef QGlobalStatic<MySingleton> MySingletonPtr; Q_GLOBAL_STATIC(MySingletonPtr, mySingleton) MySingleton::MySingleton() : QObject() {} ``` 现在,就可以在应用程序中的其他对象中接收全局信号: ``` MySingleton::getInstance()->emit mySignal(); ``` 可以将mySignal()信号连接到任何具有匹配参数的槽函数中: ``` connect(MySingleton::getInstance(), &MySingleton::mySignal, this, &MyObject::mySlot); ``` 使用单例模式和QObjectQt可以非常方便地实现全局信号。通过这种方式,任何对象都可以接收应用程序中发生的事件,从而更加灵活和可扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhou_Xintong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值