深入理解c++实现Qt信号和槽机制

 更新时间:2023年08月08日 11:47:04   作者:ccloud11  
信号和槽机制是 Qt 的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信,本文就来深入理解c++实现Qt信号和槽机制,感兴趣的可以了解一下

简介

信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁。

信号和槽机制是 Qt 的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信。

信号

当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。这样就做到了真正的信息封装,能确保对象被当作一个真正的软件组件来使用。

用于接收信号,而且槽只是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且对象并不了解具体的通信机制。

信号与槽的连接

所有从 QObject 或其子类 ( 例如 Qwidget ) 派生的类都能够包含信号和槽。因为信号与槽的连接是通过 QObject 的 connect() 成员函数来实现的。

connect(sender, SIGNAL(signal), receiver, SLOT(slot));

其中 sender 与 receiver 是指向对象的指针,SIGNAL() 与 SLOT() 是转换信号与槽的宏。

特点

1、一个信号可以连接多个槽

当信号发射时,会以不确定的顺序一个接一个的调用各个槽。

2、多个信号可以连接同一个槽

即无论是哪一个信号被发射,都会调用这个槽。

3、信号直接可以相互连接

发射第一个信号时,也会发射第二个信号。4、连接可以被移除

这种情况用得比较少,因为在对象被删除时,Qt会自动移除与这个对象相关的所有连接。语法如下:

disconnect(sender, SIGNAL(signal), receiver, SLOT(slot));

观察者模式

定义

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

观察者模式结构图

在观察者模式中有如下角色:

1、Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
2、ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
3、Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
4、ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

实现简单的信号和槽

为什么要说观察者模式呢?因为Qt的信号和槽就是基于这种设计模式来进行设计的。通过信号和槽将对发送者信号感兴趣的对象连接起来,当发送者的信号发送的时候,就会对这个列表进行遍历,这种方式类似于广播,不关心用户是否收到,只是进行发送而已。下面是实现方式。

#include <iostream>
#include <vector>
using namespace std;
//槽函数类
template <class TParam>
class SlotBase
{
public:
    virtual void slotFuntion(TParam) = 0;
    virtual ~SlotBase() = default;
};
template <class TReceiver,class TParam>
class Slot:public SlotBase<TParam>
{
private:
    TReceiver *m_preveiver;
    void (TReceiver::*m_func)(TParam);
public:
    Slot(TReceiver * reveiver,void(TReceiver::*func)(TParam))
    {
        m_preveiver = reveiver;
        m_func = func;
    }
    void slotFuntion(TParam param) override
    {
        (m_preveiver->*m_func)(param);
    }
};
//信号类
template <class TParam>
class Signal
{
private:
    std::vector<SlotBase<TParam> *> signal_vector;
public:
    template <class TReceiver>
    void addSlot(TReceiver *reveiver,void(TReceiver::*func)(TParam))
    {
        signal_vector.push_back(new Slot(reveiver,func));
    }
    void operator()(TParam param)
    {
        for(SlotBase<TParam> *p:signal_vector)
        {
            p->slotFuntion(param);
        }
    }
};
//两个测试的接受信号类
class Receiver1
{
public:
    void func1(int param)
    {
        std::cout<<"这是Receiver1类中方法,参数为"<<param<<endl;
    }
};
class Receiver2
{
public:
    void func2(int param)
    {
        std::cout<<"这是Receiver2类中方法,参数为"<<param<<endl;
    }
};
class SendObj
{
public:
    Signal<int> valueChanged;
public:
    void testSend(int value)
    {
        valueChanged(value);
    }
};
#define connect(send,signal,reveiver,slot) send->signal.addSlot(reveiver,slot)
int main()
{
    SendObj *send=new SendObj;
    Receiver1 *r1 = new Receiver1;
    Receiver2 *r2 = new Receiver2;
    connect(send,valueChanged,r1,&Receiver1::func1);
    connect(send,valueChanged,r2,&Receiver2::func2);
    send->testSend(100);
    return 0;
}

 到此这篇关于深入理解c++实现Qt信号和槽机制的文章就介绍到这了,更多相关c++实现Qt信号和槽机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言实现学生管理系统的源码分享

    C语言实现学生管理系统的源码分享

    这篇文章主要为大家详细介绍了如何利用C语言实现学生管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • C++ 整型与字符串的互转方式

    C++ 整型与字符串的互转方式

    今天小编就为大家分享一篇C++ 整型与字符串的互转方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • VS中scanf函数报错问题的几种解决方法

    VS中scanf函数报错问题的几种解决方法

    本文主要介绍了VS中scanf函数报错问题的几种解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Qt6子窗口全屏显示的实现示例

    Qt6子窗口全屏显示的实现示例

    在Qt开发中,有时候需要让程序窗口全屏显示,本文主要介绍了Qt6子窗口全屏显示的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • C语言零基础入门(2)

    C语言零基础入门(2)

    这篇文章主要为大家详细介绍了C语言零基础入门的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言代码中调用C++代码的方法示例

    C语言代码中调用C++代码的方法示例

    这篇文章主要介绍了C语言代码中调用C++代码的方法示例,文中也介绍了C++代码调用C代码的方法,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • c语言如何实现DES加密解密

    c语言如何实现DES加密解密

    这篇文章主要介绍了c语言如何实现DES加密解密问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • C++ 实现稀疏矩阵的压缩存储的实例

    C++ 实现稀疏矩阵的压缩存储的实例

    这篇文章主要介绍了C++ 实现稀疏矩阵的压缩存储的实例的相关资料,M*N的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律,需要的朋友可以参考下
    2017-07-07
  • C语言实题讲解快速掌握单链表上

    C语言实题讲解快速掌握单链表上

    单链表是后面要学的双链表以及循环链表的基础,要想继续深入了解数据结构以及C语言,我们就要奠定好这块基石!接下来就和我一起学习吧
    2022-04-04
  • vs2019创建WebService服务的实现

    vs2019创建WebService服务的实现

    这篇文章主要介绍了vs2019创建WebService服务的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03

最新评论