【Qt开发】Qt信号与槽 示例

假设基于这样的一个情况:

在某一个程序里有两个主要的两个逻辑功能部分---UI交互的功能块和用于网络通信的网络功能块。当网络中有新的消息到达时,网络功能块需要通知UI刷新信息的显示;当用户输入新的操作命令或信息时,UI功能块将通过调用网络程序来进行数据的传送。

在非Qt程序中,我们一般是通过函数的回调或事件监听机制来实现这样的程序。打个比方,假设有类A和类B,类A对象中存有类B对象的指针,同时将自身的对象指针传到类B中去,这样便可以实现了函数的回调;A对象可以调用B的公有方法,同时B也可以根据具体情况来回调A的公有方法。

这种方式类似于通用设计模式中的观察者模式,只是观察者模式提供了更抽象的封装而已,比如对象之间互传的指针都是基于动态绑定的对象指针。

回到正题,在Qt程序中更偏向于使用信号与槽的机制来解决这样的问题。当然信号与槽机制的作用远远不止这些。

基于这种机制,不同对象之间可以发送信号,也可以接受信号,接收信号的方法称为槽。概括来说它有几个特性:(1)相对于普通的回调机制,它没有复杂的指针对象,只是指定了发送信号和接受信号的对象。(2)一个槽可以接收多个对象发出来的信号,一个信号也可以与多个槽连接。(3)在跨线程或进程的函数调用中,信号与槽的机制显得更为安全和灵活,而省去了一些非安全的显式指针调用。

下面是一个简单的例子,演示信号与槽的工作原理。

(1)定义信号

#include <QObject>

class A : public QObject
{
    Q_OBJECT

public:
    A(QObject* parent = 0);
    
signals:
    void message_arrive(QString msg);
};

#include "a.h"

A::A(QObject* parent) : QObject(parent)
{
}

作为signal与slot中的一个参与者对象,它必须是QObject对象,也就是它必须要从QObject中派生而来。同时也要求在类声明中添加宏Q_OBJECT的声明,宏Q_OBJECT的作用是默认实现了Qt对象模型所需的几个关键函数。

关于信号,有几个特点:(1)信号的定义关键字是signals,不需要添加访问级别的关键字修饰,因信号总是被默认为public的,以便在不同类之间通信。(2)信号总是只有声明,而没有定义体的,这就好比C++的纯虚函数一样。(3)信号和槽之间传递的参数必须对应。(4)信号的返回类型总是void,即没有返回值。

(2)定义槽

#include <QObject>

class B : public QObject
{
    Q_OBJECT

public:
    B(QObject* parent = 0);
    
public slots:
    void reflash_text(QString msg);
};
#include "b.h"

B::B(QObject* parent) : QObject(parent)
{
}

void B::reflash_text(QString msg)
{
    // TODO:接收信号并处理参数
}

槽的访问级别可以设置成public, proteced, private,这个根据具体情况而定;同时需要实现相应的函数体。当然,信号与

槽也可以同时定义在同一个对象中。

(3)连接信号与槽

方法调用:QObject::connect(const QObject *asender, const char *asignal,const QObject *areceive, const char *asignal, Qt::ConnectionType atype)。最后一个参数是可选的,代表采取的连接类型(连接类型会设计到安全性问题,比如不同线程间的信号与槽连接类型普遍采取QueuedConnection等)。

对于上面的示例,则可以这样连接:

QObject::connect(a, SIGNAL(message_arrive(QString)), this, SLOT(reflash_text(QString)));

其中a为类A的一个对象的指针; this指向类B的一个对象本身,也就是说这个函数connect()在B中调用。




  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值