Подключите все сигналы объектов к одному слоту

Немного огляделся, и люди, кажется, имеют аналогичную проблему, но с несколькими сигналами из разных источников и т. д. Моя ситуация такова, что у меня есть объект, который сигнализирует, если он преуспел, потерпел неудачу или был отменен. Эти сигналы передаются другому классу и не связаны со слотом, это просто сигнал. Теперь я хотел бы исправить, чтобы независимо от того, какой сигнал отправляет объект (сбой, успех, отмена), вызывался слот, который удалит объект. Короче говоря, мне нужен способ подключения каждого сигнала объекта к слоту.

Хотите сделать что-то вроде этого:

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

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

Есть ли способ сделать это? Или я должен просто передавать два сигнала каждый раз, когда он что-то делает, например emit readyToBeDeleted() и emit succeded()?

Спасибо!


person chikuba    schedule 11.04.2012    source источник
comment
вы хотите удалить объект, который излучает сигнал из подключенного слота?   -  person Kunal    schedule 11.04.2012
comment
я хочу поймать любой сигнал от объекта, чтобы знать, когда его удалить   -  person chikuba    schedule 11.04.2012
comment
вы не можете использовать deleteLater() ?   -  person Kunal    schedule 11.04.2012
comment
deleteLater удаляет что-то в конце области видимости. Мне нужно подождать, пока эти запросы не будут готовы, прежде чем я смогу удалить их, используя «Удалить позже».   -  person chikuba    schedule 11.04.2012


Ответы (2)


Оставив в стороне любые сомнения по поводу того, действительно ли разумно подключать все сигналы в одном объекте к одному слоту в другом объекте, ниже приведена функция, которая делает это, а также модульный тест, чтобы убедиться, что он работает.

Если вы посмотрите stdout во время запуска, вы увидите, что он распечатывает все соединения, которые он устанавливает. Когда он запускается, нажатие на QLineEdit приведет к тому, что QLineEdit выдаст сигнал, который (конечно) вызовет слот QApplication::quit(), поэтому приложение завершится.

#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();
}
person Jeremy Friesner    schedule 01.05.2013
comment
Любопытно: почему мы должны добавлять 2 к сигнатуре сигнала? (другими словами: не могли бы вы объяснить строку: QString signalString = QString("2") + mm.signature();) - person pestophagous; 18.11.2020
comment
Ах я вижу. 2 — эмулировать макрос # define SIGNAL(a) "2"#a. github.com/qt/qtbase/blob/ 34304e31008/src/corelib/kernel/ - person pestophagous; 18.11.2020

Вы можете подключить любое количество сигналов к любому количеству слотов (как и другие сигналы). Для этой цели имеет смысл подключить сигналы к двум слотам. Слоты вызываются в порядке их подключения. Подача двух сигналов подряд также вполне разумна. Конечно, readyToBeDeleted() следует вызывать после успешного(), чтобы объект не удалялся до выдачи сигнала результата.

Если я вас не правильно понимаю, это так просто.

person Anthony    schedule 11.04.2012
comment
из того, что я читал, порядок вызова слотов случайный. я просто хочу решить это таким образом, чтобы мне не приходилось подключать каждый сигнал дважды - person chikuba; 11.04.2012
comment
@chikuba Нет, согласно документам, если подключено несколько слотов к одному сигналу, слоты будут выполняться один за другим, в том порядке, в котором они были подключены, когда сигнал испускается. - person Anthony; 11.04.2012
comment
но я не буду подключать несколько слотов к одному сигналу. я после какого-то способа действительно подключить каждый сигнал от одного объекта к одному конкретному слоту - person chikuba; 11.04.2012
comment
@chikuba Вы не можете автоматически подключать каждый сигнал от объекта к заданному слоту. Вы должны сделать это вручную, один за другим, в том порядке, в котором вы хотите, чтобы они были уволены. Я не понимаю, в чем проблема. - person Anthony; 11.04.2012
comment
в документе указано doc.trolltech.com/4.5/signalsandslots.html#signals. Если к одному сигналу подключено несколько слотов, слоты будут выполняться один за другим, в произвольном порядке, при испускании сигнала. они, должно быть, изменили это только что тогда :) - person chikuba; 12.04.2012