QT工具 —— Signals&Slots

官网地址:https://doc.qt.io/qt-5/signalsandslots.html

0. 简介

slot是连接多个object的一种方法,很多别的框架都是使回调函数,但是QT中使用SLOT,相对与回调来说,不必考虑传入参数的类型匹配等问题。我们可以认为SLOT是一个函数,它可以被Signal激活,同时连接两个object。Qt’s signals and slots mechanism ensures that if you connect a signal to a slot, the slot will be called with the signal’s parameters at the right time.
在这里插入图片描述

1. 机制

  1. 任何继承自QObject或者其子类(e.g., QWidget) 的类都可以包含 signals and slots。
  2. Signals are emitted by objects when they change their state in a way that may be interesting to other objects. This is all the object does to communicate. It does not know or care whether anything is receiving the signals it emits.
  3. You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you need. It is even possible to connect a signal directly to another signal. (This will emit the second signal immediately whenever the first is emitted.)

2. example

一个常见的C++工程如下:

class Counter
{
public:
    Counter() { m_value = 0; }

    int value() const { return m_value; }
    void setValue(int value);

private:
    int m_value;
};

一个继承自QObject的类的写法如下:

#include <QObject>

class Counter : public QObject
{
    Q_OBJECT

public:
    Counter() { m_value = 0; }

    int value() const { return m_value; }

public slots:
    void setValue(int value);

signals:
    void valueChanged(int newValue);

private:
    int m_value;
};

这个类的状态可以被激发的信号valueChanged()改变, 并且它有slot可以让其他的function通过这个slot发送这个激活的信号。
它的slot为void setValue(int value);,下面一个它的可能实现。在这个实现中我们可以看到有一行为emit valueChanged(value);,这一句就是可以发送valuechanged(value)这个signal

void Counter::setValue(int value)
{
    if (value != m_value) {
        m_value = value;
        emit valueChanged(value);
    }
}

下面我们通过QObject::connect()这个函数来链接signalslot和两个object,用法如下:

Counter a, b;
    QObject::connect(&a, &Counter::valueChanged,
                     &b, &Counter::setValue);

    a.setValue(12);     // a.value() == 12, b.value() == 12
    b.setValue(48);     // a.value() == 12, b.value() == 48

也就是说,a通过setValue这个slot链接b,并通过valueChanged这个signal通知b。
当a调用setvalue时,会激活valueChanged这个信号,那么b就会在setValue() slot中接收它,所以b会调用它的setValue.
Calling a.setValue(12) makes a emit a valueChanged(12) signal, which b will receive in its setValue() slot, i.e. b.setValue(12) is called. Then b emits the same valueChanged() signal, but since no slot has been connected to b’s valueChanged() signal, the signal is ignored.

在链接之后,我们也可以通过disconnect()来断开两个object之间的链接。

3. A Real Example

#ifndef LCDNUMBER_H
#define LCDNUMBER_H

#include <QFrame>

class LcdNumber : public QFrame
{
    Q_OBJECT
public:
    LcdNumber(QWidget *parent = nullptr);

signals:
    void overflow();
public slots:
    void display(int num);
    void display(double num);
    void display(const QString &str);
    void setHexMode();
    void setDecMode();
    void setOctMode();
    void setBinMode();
    void setSmallDecimalPoint(bool point);
};
#endif

A slot is a receiving function used to get information about state changes in other widgets.
我们可以将不同的对象之间通过同一个信号不同的slot链接,这样就会调用不同的slot。

4. Signals And Slots With Default Arguments

如果我们要捕获一个对象销毁的信号:
The signatures of signals and slots may contain arguments, and the arguments can have default values.
比如说QObject的destory就是一个默认的信号:

void destroyed(QObject* = nullptr);

如果我们要捕获这个信号,我们可以这样实现,先自定义一个slot

void objectDestroyed(QObject* obj = nullptr);

然后把信号与对象进行链接,当sender销毁的时候,本对象会调用objectDestroyedslot:

connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);

我们也可以直接使用默认的类来实现:这三种实现方式都可以

connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));

但是下面这种不可以

connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));

because the slot will be expecting a QObject that the signal will not send. This connection will report a runtime error.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值