暂时阻塞两个 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;
可以通过断开和重新连接对象来实现,但首先必须存储信号/插槽列表。
自省方法似乎没有足够强大来实现这一点(我查看了QMetaObject
和QSignalSpy
没有成功)。
【问题讨论】:
【参考方案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 之间的信号的主要内容,如果未能解决你的问题,请参考以下文章