Qt disconnectNotify()没有调用接收器对象销毁

时间:2012-03-05 10:21:01

标签: c++ qt

我有一个发出信号S的C类.S可以连接到零,一个或多个接收器(R)(连接数随时间变化,连接由接收器产生)。

当S的侦听器数量大于零时,C需要做的事情,以及当S上的侦听器数量回到零时做其他事情。

我以为我可以使用:

connectNotify()

disconnectNotify()

阱,...

我注意到connectNotify()函数运行良好,但是当销毁接收对象时,不会调用disconnectNotify()(在类C中)。仅在使用disconnect()进行显式断开时才会调用它。

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

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

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

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

如果您可以确保在C之前销毁所有R,您可以在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 );
    }
}