您的位置:

Qt Event System中qtemit的使用

一、qtemit的定义和作用

qtemit是Qt Event System中的一个类,用于在Qt对象之间通信,它定义了一个通信机制,使得发送和接收信号更为灵活方便

qtemit最基本功能即是信号的发送和接收。信号作为Qt中非常特殊的一种成员函数,在对象被创建时自动产生。因此只需知道信号的原型就可以向对象发送信号了。而qtemit则为Qt中提供了另一种通过一种简单的机制实现信号传递的方式。

qtemit解决了Qt信号传递的一些限制。在Qt中,信号连接的时候必须知道发送者和接收者的类型,要么使用整个类名,要么使用QObject的指针或引用。而使用qtemit,可以做到将这个限制降到最小程度,提高程序的灵活性和可维护性

二、qtemit的使用方式

1. qtemit的包含

#include <qtemit/qtemit.h>

由于qtemit不是Qt的标准组件,所以需要先包含头文件,为了与其他头文件区分,建议使用qtemit/qtemit.h的形式

2. 定义发送者和接收者

#include <qtemit/qtemit.h>
#include <QObject>

class Sender : public QObject
{
    Q_OBJECT

public:
    Sender(QObject *parent = nullptr) : QObject(parent) {}

signals:
    void signal1(int value);
    void signal2(int value);
};

class Receiver : public QObject
{
    Q_OBJECT

public:
    Receiver(QObject *parent = nullptr) : QObject(parent) {}

public slots:
    void slot1(int value)
    {
        qDebug() << "Received signal1: " << value;
    }

    void slot2(int value)
    {
        qDebug() << "Received signal2: " << value;
    }
};

这里定义了一个发送者Sender和一个接收者Receiver。Sender中定义了两个信号signal1和signal2,Receiver中定义了两个槽函数slot1和slot2。signal1和slot1,signal2和slot2是一一对应的

3. 使用qtemit连接信号和槽函数

Sender sender;
Receiver receiver;

QObject::connect(&sender, qtemit::signal(&Sender::signal1), &receiver, qtemit::slot(&Receiver::slot1));
QObject::connect(&sender, qtemit::signal(&Sender::signal2), &receiver, qtemit::slot(&Receiver::slot2));

这里使用qtemit::signal函数和qtemit::slot函数将信号和槽函数连接起来。不同于Qt中需要使用QString作为参数表示信号和槽函数的名称,qtemit使用函数指针的方式,更加安全和可靠

4. 发送信号

sender.emit(qtemit::signal(&Sender::signal1), 1);
sender.emit(qtemit::signal(&Sender::signal2), 2);

在对象sender中,使用sender.emit函数来发送信号,信号的名称由qtemit::signal函数指定,它是一个函数指针

三、qtemit的优势和局限性

1. 优势

使用qtemit,可以将信号和槽函数更加灵活地连接起来。在这种方法下,连接的耦合关系只由信号和槽函数的函数指针决定,而不再依赖于发送者和接收者实际的类型。

使用qtemit之后,扩展连接方式变得更加简单易行。在qtemit的基础上,可以轻松地实现多个信号、多个槽函数绑定,而不需要编写繁琐的代码,使得我们的代码更加简洁

2. 局限性

使用qtemit虽然更为灵活,但是信号和槽函数的函数指针连接起来的方式会对安全性和可维护性产生影响。因此在实际应用中,请务必关注安全和可维护性问题。

四、qtemit的代码示例

1. Sender和Receiver的定义文件

#include <qtemit/qtemit.h>
#include <QObject>

class Sender : public QObject
{
    Q_OBJECT

public:
    Sender(QObject *parent = nullptr) : QObject(parent) {}

signals:
    void signal1(int value);
    void signal2(int value);
};

class Receiver : public QObject
{
    Q_OBJECT

public:
    Receiver(QObject *parent = nullptr) : QObject(parent) {}

public slots:
    void slot1(int value)
    {
        qDebug() << "Received signal1: " << value;
    }

    void slot2(int value)
    {
        qDebug() << "Received signal2: " << value;
    }
};

2. 使用qtemit连接信号和槽函数

Sender sender;
Receiver receiver;

QObject::connect(&sender, qtemit::signal(&Sender::signal1), &receiver, qtemit::slot(&Receiver::slot1));
QObject::connect(&sender, qtemit::signal(&Sender::signal2), &receiver, qtemit::slot(&Receiver::slot2));

3. 发送信号

sender.emit(qtemit::signal(&Sender::signal1), 1);
sender.emit(qtemit::signal(&Sender::signal2), 2);