临时阻塞两个qobject之间的信号

时间:2022-03-14 18:45:59

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.

我希望在不修改其他信号/插槽行为和不了解它们的上下文的情况下,对两个qobject之间的信号进行一般和临时的阻塞。

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

类似QObject::blockSignals(bool),但只在两个QObject之间起作用。

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

即实现了以下信号阻滞剂::::块信号(bool)函数:

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

通过分离和重新连接对象是可能的,但是首先必须存储信号/插槽列表。自省方法似乎不足以实现这一点(我查看了QMetaObject和QSignalSpy,但没有成功)。

3 个解决方案

#1


10  

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

QT没有禁用信号槽对的能力。试试这个方法:

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;
};

#2


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)

由于您希望发送方和接收方不会在该范围内发送信号,所以我将尝试使用块信号(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);
//...

#3


0  

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

U可以使用disconnect(sender, 0, receiver, 0);将所有发送方的信号从所有接收方的槽中断开。

#1


10  

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

QT没有禁用信号槽对的能力。试试这个方法:

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;
};

#2


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)

由于您希望发送方和接收方不会在该范围内发送信号,所以我将尝试使用块信号(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);
//...

#3


0  

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

U可以使用disconnect(sender, 0, receiver, 0);将所有发送方的信号从所有接收方的槽中断开。