chikuba
chikuba

Reputation: 4357

Connect all of an objects signals to a single slot

Been looking around a bit and people seem to have a similar issue but with multiple signals from different sources etc. My situation is that I have a object that signals if it succeded, failed or got canceled. These signals are passed along to another class and are'nt connected to a slot, just a signal. Now I would like to fix so that no matter what signal the object sends (failed, succeded, canceled) a slot will be called that will delete the object. In short, I want a way of connecting every signal of an object to a slot.

Want to do something like this:

connect(myObject, allSignals, this, handleObjectDone());

void handleObjectDone() {
    myObject->deleteLater();
}

Is there any way of doing this? Or should I just pass two signals everytime it does something, for example emit readyToBeDeleted() and emit succeded()?

Thanks!

Upvotes: 0

Views: 727

Answers (2)

Jeremy Friesner
Jeremy Friesner

Reputation: 73041

Setting aside any qualms about whether connecting all the signals in one object to a single slot in another object is actually a wise thing to do, below is a function that does that, along with a unit test to verify that it works.

If you watch stdout while you run this, you will see it print out all the connections it is making. When it runs, clicking on the QLineEdit will cause the QLineEdit to emit a signal, which will (of course) cause the QApplication::quit() slot to be called, so the application will exit.

#include <stdio.h>
#include <QApplication>
#include <QLineEdit>
#include <QMetaMethod>
#include <QMetaObject>

void ConnectAllSignalsToSlot(QObject * sourceObject, QObject * targetObject, const char * slotName)
{
   const QMetaObject * mo = sourceObject->metaObject();
   if (mo)
   {
      int numMethods = mo->methodCount();
      int firstMethod = mo->methodOffset();  // set to 0 instead if you want to connect signals from superclasses too
      for (int i=firstMethod; i<numMethods; i++)
      {
         QMetaMethod mm = mo->method(i);
         if (mm.methodType() == QMetaMethod::Signal)
         {
            QString signalString = QString("2") + mm.signature();
            printf("Connecting up signal [%s] on object %p to slot [%s] on object %p\n", signalString.toUtf8().constData(), sourceObject, slotName, targetObject);  // just so we can see what it's doing
            QObject::connect(sourceObject, signalString.toUtf8().constData(), targetObject, slotName);
         }
      }
   }
   else printf("Error, sourceObject has no QMetaObject????\n");
}

int main(int argc, char ** argv)
{
   QApplication app(argc, argv);

   QWidget * testSource = new QLineEdit;
   testSource->show();

   ConnectAllSignalsToSlot(testSource, &app, SLOT(quit()));

   return app.exec();
}

Upvotes: 2

Anthony
Anthony

Reputation: 8788

You can connect any number of signals to any number of slots (as well as other signals). It makes perfect sense to connect the signals to two slots for this purpose. The slots are called in the order they are connected. Emitting two signals consecutively is perfectly reasonable as well. Of course readyToBeDeleted() should be emitted after succeeded() so that the object isn't deleted before emitting its result signal.

Unless I'm misunderstanding you, it's that simple.

Upvotes: 1

Related Questions