【问题标题】:Temporarily block signals between two QObjects暂时阻塞两个 QObject 之间的信号
【发布时间】: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 没有成功)。

【问题讨论】:

    标签: qt signals qobject slot


    【解决方案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] 之类的东西来获取连接/断开信号的列表,但我认为你做的不对。为什么需要它?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 2014-03-10
      • 1970-01-01
      • 2013-11-29
      相关资源
      最近更新 更多