暂时阻塞两个 QObject 之间的信号

Posted

技术标签:

【中文标题】暂时阻塞两个 QObject 之间的信号【英文标题】:Temporarily block signals between two QObjects 【发布时间】:2013-03-26 09:08:10 【问题描述】:

我想在不修改其他信号/插槽行为且不知道它们的上下文的情况下,一般性地暂时阻止两个 QObjects 之间的信号。

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

即实现如下SignalBlocker::blockSignals(bool)函数:

class SignalBlocker 

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

private:
  QObject *mSender, *mReceiver;

可以通过断开和重新连接对象来实现,但首先必须存储信号/插槽列表。 自省方法似乎没有足够强大来实现这一点(我查看了QMetaObjectQSignalSpy 没有成功)。

【问题讨论】:

【参考方案1】:

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】:

由于您希望发送方和接收方不会在该范围内发送信号,所以我会尝试使用blockSignals(bool)

class SignalBlocker
public:
SignalBlocker(QObject* obj)

   _o = obj;
   _o->blockSignals(true);

~SignalBlocker()

   _o->blockSignals(false);

private:
   QObject* _o;
;

现在只需使用

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

【讨论】:

不幸的是,这仍然不能解决我的问题,因为在这种情况下,发送方和接收方完全被阻止(他们无法将消息发送到第三个 QObject,而这是我需要的)。 也许可以创建一个像SignalBlocker 这样的类,并为对象提供一个模板函数指针,指示您要阻止的内容......所以它只会阻止您想要的信号【参考方案3】:

您可以使用disconnect(sender, 0, receiver, 0); 断开所有sender 的信号与所有receiver 的插槽。

【讨论】:

确实,但我希望在重新连接对象时能够检索到与断开连接之前相同的状态。所以在断开连接之前,我应该列出发送方和接收方之间的所有信号/插槽连接(这是我无法做到的一点)。 尝试使用 void QObject::connectNotify ( const char * signal ) [virtual protected]void QObject::disconnectNotify ( const char * signal ) [virtual protected] 之类的东西来获取连接/断开信号的列表,但我认为你做的不对。为什么需要它?

以上是关于暂时阻塞两个 QObject 之间的信号的主要内容,如果未能解决你的问题,请参考以下文章

Qt智能指针

PyQt5 支持不从 QObject 继承的类中的信号

QObject三大核心功能——信号与槽

linux都有哪些信号不会被阻塞

PyQt5中的信号与槽,js 与 Qt 对象之间互相调用

信号与槽(可以与第三方库混用,首次见到QObject::destroyed的使用)