如何将信号连接到类的所有实例的插槽

How to connect signals to the slots of all instances of a class

本文关键字:实例 插槽 信号 连接      更新时间:2023-10-16

我有一个简单的类,我将创建该类的 100 个实例。

有没有办法在创建实例之前将他类的所有对象中的所有插槽连接到单个信号(反之亦然((因为显然,一个接一个地连接每个对象是一项令人厌烦的工作(。

提前感谢您的任何想法,我很乐意欢迎任何不同的方法。

有一种简单的方法可以通过使用单例类来实现此目的,实例化的类将通过自己的类连接到该类:


将提供单个入口点的单例类:

class Linker : public QObject
{
Q_OBJECT
public:
static Linker * getInstance(QObject *parent = 0)
{
static Linker * instance = new Linker(parent);
return instance;
}
sendSignal()
{
emit mySignal();
}
signals:
void mySignal();
};

要实例化的类:

class ClassToBeInstencied  : public QObject
{
Q_OBJECT
private slots:
void mySlot() {}
public:
ClassToBeInstencied() // constructor
{
connect(this, &ClassToBeInstencied::mySlot, Linker::getInstance(), &Linker::mySignal);
}
};

这样做的好处是可以保持代码干净和简单,因为您不必处理与类外信号/插槽的连接,因此它被很好地封装了。

您只需要创建一个新实例:

ClassToBeInstencied  * a = new ClassToBeInstencied();
ClassToBeInstencied  * b = new ClassToBeInstencied();
ClassToBeInstencied  * c = new ClassToBeInstencied();

并且连接将自动完成。

您可以通过以下方式直接向所有人发送信号:

Linker::getInstance()->sendSignal();

优点:没有列表,没有循环,无需在类外进行管理,也无需手动连接每个实例。

您可以将所有实例的指针存储在构造函数中的静态列表中,并在析构函数中删除它:

我的班级

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
class MyClass : public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = nullptr);
void myMethod1();
~MyClass();
signals:
void globalSignal();
public slots:
private:
static QList<MyClass *> m_allInstances;
void emitSignal4All();
};
#endif // MYCLASS_H

我的班级.cpp

#include <QDebug>
#include "myclass.h"
QList<MyClass *> MyClass::m_allInstances;
MyClass::MyClass(QObject *parent) : QObject(parent)
{
m_allInstances.append(this);
}
void MyClass::myMethod1()
{
//... sample usage of `emitSignal4All()`
emitSignal4All();
}
MyClass::~MyClass()
{
m_allInstances.removeOne(this);
}
void MyClass::emitSignal4All()
{
for(int i = 0; i<m_allInstances.count(); i++) {
emit m_allInstances.at(i)->globalSignal();
}
}

示例用法

MyClass instance1;
MyClass *instance2 = new MyClass();
connect(&instance1, &MyClass::globalSignal, this, [&instance1, this]() {
qDebug() << "signal of instance1 is fired!";
});
connect(instance2, &MyClass::globalSignal, this, [instance2, this]() {
qDebug() << "signal of instance2 is fired!";
});
MyClass instance3;
instance3.myMethod1();