信号阻塞器QSignalBlocker、blockSignals用法

QSignalBlocker在构造函数中阻塞信号,在析构函数中它将状态重置为构造函数运行前的状态。

QSignalBlocker用来代替blockSignals()。当使用blockSignals()来阻塞信号时,总要成对使用blockSignals(true)和blockSignals(false)。一不小心少写一个则信号一直阻塞后果难料,使用QSignalBlocker代替则不会有问题。当QSignalBlocker对象出了作用域范围后,根据C++规则会自动调用其析构函数,从而将状态重置为构造函数运行前的状态。如下代码:

#include "QSignalBlockerDemo.h"
#include <QDebug>
#include <QDateTime>
#include<QPushButton>
QSignalBlockerDemo::QSignalBlockerDemo(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    connect(ui.pushButton, &QAbstractButton::clicked, this, &QSignalBlockerDemo::blockTimer);
    connect(&timer, &QTimer::timeout, this, &QSignalBlockerDemo::onTimer);
    timer.start(1000);
}
void QSignalBlockerDemo::onTimer()
{
    qDebug() << "xxxxxxx" << QDateTime::currentDateTime();
}
void QSignalBlockerDemo::blockTimer()
{
    QSignalBlocker blocker(timer);
    QEventLoop eventloop;
    QTimer::singleShot(5000, &eventloop, SLOT(quit()));
    eventloop.exec();
    qDebug() << QString::fromLocal8Bit("过了5秒");
}

输入结果如下:


 

可以看到,当单击按钮时,信号被阻塞,从而使每隔1s的定时器timer的timeout信号失效,等5s后QEventLoop类的eventloop事件循环退出后,blockTimer()函数执行完,导致QSignalBlocker类型的对象eventloop被析构,之后因为没有QSignalBlocker类型信号阻塞器对象了,就不会再阻塞timer的timeout信号,程序继续每隔1s打印出日志。QEventLoop类使用参考

QEventLoop的简单使用(一)

QEventLoop的简单使用(二)

 如下图,当我改变左边框的文字,右边的也会对应填写数据,当我在右边填写文字的时候,左边也跟着变化。

 它的逻辑图如下:

 这个时候我们可能就发现问题了,如果是信号的话,就会走1-2-3-4-5-2-3... 这样无限循环下去,我们想一下,要是能切断信号4,就可以左边写什么右边写什么,同理切断2的信号,就可以完成右边写什么,左边就写什么了。

    当然你直接使用textChanged  也会判断,至少会多发一个消息。如果只是接受到信号就发送的话,也就会出现死循环的问题;实现右边写什么,左边就写什么的功能就会失败,所以我们要用下面的方式来写:

void MainWindow::on_lineEditleft_textChanged(const QString &arg1)
{
   ui->lineEditright->blockSignals(true);
   ui->lineEditright->setText(arg1);
   ui->lineEditright->blockSignals(false);
}
 
void MainWindow::on_lineEditright_textChanged(const QString &arg1)
{
   ui->lineEditleft->blockSignals(true);
   ui->lineEditleft->setText(arg1);
   ui->lineEditleft->blockSignals(false);
}

效果图如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值