Qt信号的处理 (connect和disconnect和blockSignals的使用方法)

信号槽机制是Qt的非常重要的机制,本文不剖析信号槽机制的原理,只讲信号的主要使用方法。

信号:当某个事件发生后,比如按钮检测到自己被点击了一下,按钮会发出一个信号,这种发出是没有目的的,类似广播。

1. 信号连接槽  connect函数

connect函数最常用的一般形式:

connect(sender, signal, receiver, slot);

2. 解除信号和连接到信号的槽的连接 disconnect函数

disconect函数的原型如下:

bool QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)

一般有四种用法:

2.1  解除myObject对象的所有信号连接,调用后myObject对象发出的所有信号都得不到响应。

    disconnect(myObject, 0, 0, 0);
//等同于
    myObject->disconnect();

2.2  解除myObject对象的mySignal信号的所有连接,调用后myObject对象发出的mySignal信号得不到响应。

    disconnect(myObject, SIGNAL(mySignal()), 0, 0);
//等同于
    myObject->disconnect(SIGNAL(mySignal()));

2.3  解除myObject对象与myReceiver对象的信号连接,调用后myObject对象发出的所有信号得不到myReceiver对象的响应。

    disconnect(myObject, 0, myReceiver, 0);
//等同于
    myObject->disconnect(myReceiver);

2.4  解除myObject对象的mySignal信号与myReceiver对象的mySlot槽的连接,调用后myObject对象发出的mySignal信号得不到myReceiver对象的mySlot槽的响应。

    disconnect(myObject, SIGNAL(mySignal()), myReceiver, SLOT(mySlot()));
//等同于
    myObject->disconnect(SIGNAL(mySignal(), myReceiver, SLOT(mySlot())));

ps:上述4种用法中,0是通配符,它表示任一信号、任一接收对象、任一槽。

3. 阻塞信号  blockSignals函数

blockSignals的函数原型如下:

bool QObject::blockSignals(bool block)

用法:

//object发出的信号被阻塞,系统不会调用任何连接到object的处理。
object->blockSignals(true);

//解除信号阻塞
object->blockSignals(false);

4.案例

//widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget(){}
};

#endif // WIDGET_H

//widget.cpp

#include "widget.h"

#include <QPushButton>
#include <QGridLayout>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    /* 创建控件 */
    QPushButton *btnClick      = new QPushButton("click me", this);
    QPushButton *btnBlock      = new QPushButton("block", this);
    QPushButton *btnUnblock    = new QPushButton("unblock", this);
    QPushButton *btnDisconnect = new QPushButton("disconnect", this);

    QGridLayout *pLayout = new QGridLayout();
    pLayout->addWidget(btnClick, 0, 0);
    pLayout->addWidget(btnBlock, 0, 1);
    pLayout->addWidget(btnUnblock, 0, 2);
    pLayout->addWidget(btnDisconnect, 0, 3);
    this->setLayout(pLayout);

    /* 信号槽 */
    connect(btnClick, &QPushButton::clicked, this, [=]()
    {
        qDebug() << "点击按钮";
    });

    connect(btnBlock, &QPushButton::clicked, this, [=]()
    {
        btnClick->blockSignals(true);
        btnBlock->setEnabled(false);
        btnUnblock->setEnabled(true);
    });

    connect(btnUnblock, &QPushButton::clicked, this, [=]()
    {
        btnClick->blockSignals(false);
        btnBlock->setEnabled(true);
        btnUnblock->setEnabled(false);
    });

    connect(btnDisconnect, &QPushButton::clicked, this, [=]()
    {
        disconnect(btnClick, &QPushButton::clicked, this, 0);
    });

}

//main.c

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

结果:

1.按下"click me"按钮,窗口接收到"click me"按钮发出的clicked信号,打印"点击按钮"。

2.然后再按下"block",再次按下"click me"按钮,没有打印"点击按钮"。这是因为 "click me"按钮发出的信号被阻塞了,没有得到响应。

3.然后再按下"unblock"按钮,再次按下"click me"按钮,打印"点击按钮"。这是因为解除了"click me"按钮的信号阻塞。

4.最后按下"disconnect"按钮,此时按下"click me"按钮没有反应。这是因为解除了本窗口与"click me"按钮的clicked信号的连接。 

//----------------------分割线-------------------------

更新:

信号还可以连接信号,举例如下,当ui->mdiArea的信号发出时,proWid的信号被发出。

connect(ui->mdiArea, &QMdiArea::subWindowActivated, 
             proWid, &ProjectWidget::subWindowActivated);

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值