C++ 在接收器对象销毁时未调用Qt disconnectNotify()
我有一个C类发射信号S。S可以连接到零个或多个接收器(R)(连接的数量随时间而变化,并且由接收器连接W) C需要在S的侦听器数量大于零时执行一些操作,并且在S的侦听器数量回到零时执行其他操作 我想我可以用:C++ 在接收器对象销毁时未调用Qt disconnectNotify(),c++,qt,C++,Qt,我有一个C类发射信号S。S可以连接到零个或多个接收器(R)(连接的数量随时间而变化,并且由接收器连接W) C需要在S的侦听器数量大于零时执行一些操作,并且在S的侦听器数量回到零时执行其他操作 我想我可以用: connectNotify() 及 嗯 我注意到的是connectNotify()函数工作得很好,但是当接收对象被销毁时,disconnectNotify()没有被调用(在类C中)。只有在使用显式断开连接(使用disconnect())时,才会调用它 在侦听器的析构函数中添加显式断开连接也
connectNotify()
及
嗯
我注意到的是connectNotify()函数工作得很好,但是当接收对象被销毁时,disconnectNotify()没有被调用(在类C中)。只有在使用显式断开连接(使用disconnect())时,才会调用它
在侦听器的析构函数中添加显式断开连接也不是很成功:退出整个应用程序时出现分段错误。(我想当一切都发生故障时,尝试使用disconnect()不是很好。)
当R被销毁时,我尝试使用从R实例发送到C的destroy()信号:这是可行的,但我如何确保R在销毁时已连接?(接收器R可能存在于非连接状态):
在C类中,插槽X(在接收R的destroyed()时调用)检查QObject::receivers(),似乎返回执行销毁之前的接收器数量。因为我不知道被摧毁的物体是否连接,我被卡住了
有什么想法吗?如果您能确保在C之前销毁所有R,您可以自己在C类中管理连接: 头文件:
#include <QtCore/QSet>
class C : (...)
{
(...)
public:
void connectReceiver( QObject* receiver );
private slots:
void handleReceiverDestruction( QObject* receiver );
private:
QSet< QObject* > _connectedReceivers;
};
我在一个测试应用程序中得到了同样的行为;对我来说,这似乎与文档不一致。你在析构函数中显式断开连接的想法对我很有效,但是你程序中的破坏顺序可能会把事情搞砸。我很想知道,当信号接收器被破坏时,是否有其他人可以得到一个
disconnectNotify
。这在Qt 5中是固定的。看,谢谢,这和我想做的工作非常接近。我还不时检查QOBject::receivers(),因为当接收器被销毁时,QOBject::receivers()似乎会递减(但这是在接收到C中销毁的()信号后发生的)。它们有很多可能的解决方法,但我仍然觉得disconnectNotify的行为很奇怪,再次感谢!
#include <QtCore/QSet>
class C : (...)
{
(...)
public:
void connectReceiver( QObject* receiver );
private slots:
void handleReceiverDestruction( QObject* receiver );
private:
QSet< QObject* > _connectedReceivers;
};
void C::connectReceiver( QObject* receiver )
{
// nothing to do if the receiver is already connected
if( _connectedReceivers.contains( receiver ) ) return;
_connectedReceivers.append( receiver )
connect( ... ); // <- do your connection(s) here
connect( receiver, SIGNAL( destroyed ( QObject* ) ),
this , SLOT ( handleReceiverDestruction( QObject* ) ) );
}
void C::handleReceiverDestruction( QObject* receiver )
{
if( !_connectedReceivers.contains( receiver ) )
{
// if this happens, a receiver R's destroyed() signal was connected to
// this function altough R is not a receiver of signal X.
Q_ASSERT( false );
return;
}
disconnect( ... ); // <- one or more might be necessary here
_connectedReceivers.remove( receiver );
}
C::~C()
{
if( !_connectedReceivers.isEmpty() )
{
// If you land here, a receiver was not (properly) destroyed before this object
Q_ASSERT( false );
}
}