深度解析qt信号与槽(2)-观察者模式在信号和槽的应用

qt中的信号和槽机制本质上是应用了观察者模式进行设计的

1.qt中的信号和槽

QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)

Qt::ConnectionType = Qt::AutoConnection
如果接收器位于发出信号的线程中,则使用Qt::DirectConnection。否则,将使用Qt::QueuedConnection。连接类型在发出信号时确定。

即绑定信号和槽函数,用信号触发槽函数执行

2.观察者模式解析信号和槽

在这里插入图片描述

在这里插入图片描述
这里被观察者的Notify(),即为一个signal,观察者的Updata()即为slot,connect函数把观察者和被观察者连接,从而达到signal触发slot的目的,实现解耦合

3.信号和槽的使用

connect(this, &Widget::sig1, this, &Widget::slot1);
void Widget::on_pushButton_clicked()
{
    qDebug()<<"sig1 begin";
    emit sig1();
    QThread::sleep(3);
    qDebug()<<"sig1 end";
}

void Widget::slot1()
{
    for(int i=0; i <3; ++i)
    {
        qDebug()<<QString("in for: %1").arg(i);
        QThread::sleep(1);
    }

    qDebug()<<"slot1";
}

运行结果
sig1 begin
“in for: 0”
“in for: 1”
“in for: 2”
slot1
sig1 end

将Qt::ConnectionType type改为Qt::QueuedConnection后

void Widget::slot1()
{
    int i=0;
    while(true)
    {
        qDebug()<<QString("in while: %1").arg(++i);
        QThread::sleep(1);
    }
    qDebug()<<"slot1";
}

运行结果
sig1 begin
sig1 end
“in for: 0”
“in for: 1”
“in for: 2”
slot1

从以上运行结果可以知道,emit 信号后,当connect不设置Qt::ConnectionType,默认的AutoConnection会将类型设置为DirectConnection,此模式必须等槽函数执行完毕,当前流程才能向下正常运行,即需要槽函数立即执行完,当前发射信号的流程阻塞,Qt::ConnectionType type改为Qt::QueuedConnection后,即不需要阻塞当前流程,当前函数执行完毕才会执行槽函数,即qt把信号放入信号连接的队列

4.解析DirectConnection 和 QueuedConnection

用观察者模式解释:
在这里插入图片描述
在这里插入图片描述

DirectConnection:为在SomeoneOperation()中直接调用信号函数,信号函数中Notify()中把槽函数执行完才返回,继而SomeoneOperation()函数才能执行完毕
QueuedConnection:为在SomeoneOperation()中,把信号函数添加到信号队列中,当前SomeoneOperation()添加后继续执行,另外有个线程专门检测信号队列,检测到Notify()后执行

本质上,所谓的阻塞非阻塞即为同步与异步处理信号

与Windows API的比较
信号队列,DirectConnection,QueuedConnection的绑定信号与槽函数与 Windows API SendMessage 和PostMessage相同功能

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值