Temporarily block signals between two QObjects
Asked Answered
J

3

5

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).

Jeanninejeans answered 26/3, 2013 at 9:8 Comment(0)
S
11

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;
};
Shutdown answered 22/6, 2013 at 12:28 Comment(0)
B
3

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);
//...
Boulder answered 26/3, 2013 at 16:32 Comment(2)
Unfortunately, this still doesn't solve my problem, because sender and receiver are in this case completely blocked (they cannot send messages to a third QObject, while this is what I need).Jeanninejeans
maybe its possible to create a class like SignalBlocker and give the objects a template function pointer of what you want to block ... so it would be blocking just the signal you wantBoulder
E
0

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

Emporium answered 26/3, 2013 at 10:16 Comment(2)
Indeed, but I would like to be able to retrieve the same state as before the disconnection when reconnecting the Object. So before the disconnection, I should list all the signals/slots connections between the sender and the receiver (and this is the point I'm unable to do).Jeanninejeans
Try to use something like void QObject::connectNotify ( const char * signal ) [virtual protected] or void QObject::disconnectNotify ( const char * signal ) [virtual protected] to get a list of connected/disconnected signals, but I don't think you're doing right things. Why do you need that?Emporium

© 2022 - 2024 — McMap. All rights reserved.