Question

I would like to generically and temporarily block the signals between two QObjects without modifying the other signals/slots behavior, and without knowing their contexts.

Something like QObject::blockSignals(bool), but only acting between two QObjects.

That is, implementing the following SignalBlocker::blockSignals(bool) function:

class SignalBlocker {

public:
  SignalBlocker(QObject *sender, QObject *receiver) :
    mSender(sender), mReceiver(receiver) {}
  void blockSignals(bool block);

private:
  QObject *mSender, *mReceiver;
}

It would be possible by disconneting and re-connecting the objects, but first the list of signals/slots would have to be stored. Introspection methods don't seem to be powerful enough to achieve this (I looked at QMetaObject and QSignalSpy without success).

Was it helpful?

Solution

QT have no capabilities to disable signal-slot pair only. Try this workaround:

struct SignalDisabler
{
    SignalDisabler(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
        : sender(sender)
        , signal(signal)
        , receiver(receiver)
        , member(member)
    {
        QObject::disconnect(sender, signal, receiver, member);
    }

    ~SignalDisabler()
    {
        QObject::connect(sender, signal, receiver, member);
    }

    const QObject *sender;
    const char *signal;
    const QObject *receiver;
    const char *member;
};

OTHER TIPS

since you want that the sender and the reciever will not send signals within that scope, i would just try to use blockSignals(bool)

class SignalBlocker{
public:
SignalBlocker(QObject* obj)
{
   _o = obj;
   _o->blockSignals(true);
}
~SignalBlocker()
{
   _o->blockSignals(false);
}
private:
   QObject* _o;
};

and now just use

SignalBlocker sb1(sender);
SignalBlocker sb2(reciever);
//...

You can use disconnect(sender, 0, receiver, 0); to disconnect all sender's signals from all receiver's slots.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top