在接收器对象销毁时未调用Qt disconnectNotify()

Qt disconnectNotify() not called on receiver object destruction

本文关键字:Qt 调用 disconnectNotify 接收器 对象      更新时间:2023-10-16

我有一个发出信号S的C类。S可能连接到零、一个或多个接收器(R)(连接数量随时间变化,连接sw由接收器建立)。

当S的监听器数量超过零时,C需要做一些事情,当S上的监听器数量回到零时,C还需要做其他事情。

我想我可以使用:

connectNotify()

disconnectNotify()

嗯,。。。

我注意到connectNotify()函数运行良好,但当接收对象被破坏时,disconnectNotify(在类C中)不会被调用。只有在使用disconnect()显式断开连接时才会调用它。

在侦听器的析构函数中添加显式断开连接也不太成功:在退出整个应用程序时出现分段错误。(我想在一切都不正常的时候尝试使用disconnect()不是很好。)

当R被销毁时,我试图使用从R实例发送到C的destroy()信号:这很有效,但我如何确定R在销毁时是连接的?(接收器R可能处于非连接状态):

在类C中,插槽X(在接收R的destroyed()时调用),检查QObject::receivers(),似乎返回执行销毁之前的接收器数量。由于我不知道被摧毁的物体是否相连,我被卡住了!

有什么想法吗?

如果您可以确保所有R在C之前被销毁,那么您可以在类C:中自己管理连接

头文件:

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