Reputation: 347
I have a simple class, and I will create let's say, 100 instances of that class.
Is there a way to connect a slot in all and any of this his class' objects' to a single signal (or vice versa) before creating the instances (since connecting every object one by one is tiresome work, obviously).
Thanks for any ideas in advance and I gladly welcome any different approaches.
Upvotes: 1
Views: 1900
Reputation: 5246
you can store pointers of all instances in an static list within constructor and remove it within destructor:
myclass.h
#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
myclass.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();
}
}
sample usage
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();
Upvotes: 2
Reputation: 1552
There is a simple way to do it by using a singleton class to which the instantiated class will connect by their own:
Singleton class which will provide a single entry point:
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 to be instantiated:
class ClassToBeInstencied : public QObject
{
Q_OBJECT
private slots:
void mySlot() {}
public:
ClassToBeInstencied() // constructor
{
connect(this, &ClassToBeInstencied::mySlot, Linker::getInstance(), &Linker::mySignal);
}
};
This has the advantage to keep your code clean and simple as you don't have to handle the connection to the signal / slot outside of the class, so it is well encapsulated.
You just need to create a new instance:
ClassToBeInstencied * a = new ClassToBeInstencied();
ClassToBeInstencied * b = new ClassToBeInstencied();
ClassToBeInstencied * c = new ClassToBeInstencied();
and the connection will be automatically done.
You can send a signal to all directly with:
Linker::getInstance()->sendSignal();
Advantage: No list, no loop nothing necessary to manage outside the class and no need of manually connecting each instance.
Upvotes: 3