Parcourir la source

Fix ctkVTKConnectionTestObjectDelete

* Use vtkWeakPointer to track the VTK object. The observation of the
DeleteEvent is now required only to disconnect the Qt slots. Using a weak
pointer also ensure that the pointer to VTK object will be set to zero
with/without observing deletion.

* Simplify ctkVTKConnection: There is not need to explicitly disconnect
slots when object is deleted. Indeed, according to Qt documentation, "all
signals to and from the object are automatically disconnected" there is no
need to explicitly disconnect them."
[1] http://qt-project.org/doc/qt-4.8/qobject.html#dtor.QObject

By also removing the call to 'disconnectSlots' in the 'disconnect()' function,
it resolves Slicer issue #3361 [2] where it was reported "No such slot" error.
Since the disconnect happened in the connection destructor and the connection
were destroyed in the base class but the slot belonged to the derived class,
this explained the error message.

[2] http://www.na-mic.org/Bug/view.php?id=3361

* Simplify ctkVTKConnection: There is no need to explicit remove VTK
observers where connection is deleted. Indeed, observers of a VTK object
are automatically removed when an object is deleted.
Jean-Christophe Fillion-Robin il y a 11 ans
Parent
commit
9e866356fd

+ 11 - 15
Libs/Visualization/VTK/Core/ctkVTKConnection.cpp

@@ -52,7 +52,6 @@ ctkVTKConnectionPrivate::ctkVTKConnectionPrivate(ctkVTKConnection& object)
   this->Callback    = vtkSmartPointer<vtkCallbackCommand>::New();
   this->Callback    = vtkSmartPointer<vtkCallbackCommand>::New();
   this->Callback->SetCallback(ctkVTKConnectionPrivate::DoCallback);
   this->Callback->SetCallback(ctkVTKConnectionPrivate::DoCallback);
   this->Callback->SetClientData(this);
   this->Callback->SetClientData(this);
-  this->VTKObject   = 0;
   this->QtObject    = 0;
   this->QtObject    = 0;
   this->VTKEvent    = vtkCommand::NoEvent;
   this->VTKEvent    = vtkCommand::NoEvent;
   this->Priority    = 0.0;
   this->Priority    = 0.0;
@@ -111,10 +110,12 @@ void ctkVTKConnectionPrivate::connect()
       {
       {
       this->VTKObject->AddObserver(vtkCommand::DeleteEvent, this->Callback);
       this->VTKObject->AddObserver(vtkCommand::DeleteEvent, this->Callback);
       }
       }
-    // Remove itself from its parent when vtkObject is deleted
-    QObject::connect(this->QtObject, SIGNAL(destroyed(QObject*)), 
-                     q, SLOT(qobjectDeleted()));
     }
     }
+
+  // When Qt object is destroyed: (1) remove VTK observers and
+  // (2) set QtObject pointer to 0.
+  QObject::connect(this->QtObject, SIGNAL(destroyed(QObject*)),
+                   q, SLOT(qobjectDeleted()));
   this->Connected = true;
   this->Connected = true;
 }
 }
 
 
@@ -160,7 +161,10 @@ void ctkVTKConnectionPrivate::disconnectVTKObject()
   if (this->VTKObject)
   if (this->VTKObject)
     {
     {
     q->removeObserver(this->VTKObject, this->VTKEvent, this->Callback);
     q->removeObserver(this->VTKObject, this->VTKEvent, this->Callback);
-    this->VTKObject->RemoveObservers(vtkCommand::DeleteEvent, this->Callback);
+    if (this->ObserveDeletion)
+      {
+      this->VTKObject->RemoveObservers(vtkCommand::DeleteEvent, this->Callback);
+      }
     }
     }
 }
 }
 
 
@@ -217,11 +221,7 @@ ctkVTKConnection::ctkVTKConnection(ctkVTKConnectionPrivate* pimpl, QObject* _par
 ctkVTKConnection::~ctkVTKConnection()
 ctkVTKConnection::~ctkVTKConnection()
 {
 {
   Q_D(ctkVTKConnection);
   Q_D(ctkVTKConnection);
-  if (d->ObserveDeletion)
-    {
-    d->disconnectSlots();
-    d->disconnectVTKObject();
-    }
+  d->disconnectVTKObject();
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -242,7 +242,7 @@ QObject* ctkVTKConnection::object()const
 vtkObject* ctkVTKConnection::vtkobject() const
 vtkObject* ctkVTKConnection::vtkobject() const
 {
 {
   Q_D(const ctkVTKConnection);
   Q_D(const ctkVTKConnection);
-  return const_cast<vtkObject*>(d->VTKObject);
+  return const_cast<vtkObject*>(d->VTKObject.GetPointer());
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -454,7 +454,6 @@ bool ctkVTKConnection::deletionObserved()const
 void ctkVTKConnection::disconnect()
 void ctkVTKConnection::disconnect()
 {
 {
   Q_D(ctkVTKConnection);
   Q_D(ctkVTKConnection);
-  d->disconnectSlots();
   d->disconnectVTKObject();
   d->disconnectVTKObject();
 }
 }
 
 
@@ -462,9 +461,7 @@ void ctkVTKConnection::disconnect()
 void ctkVTKConnection::vtkObjectDeleted()
 void ctkVTKConnection::vtkObjectDeleted()
 {
 {
   Q_D(ctkVTKConnection);
   Q_D(ctkVTKConnection);
-  d->VTKObject = 0;
   d->disconnectSlots();
   d->disconnectSlots();
-  d->disconnectVTKObject();
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -472,7 +469,6 @@ void ctkVTKConnection::qobjectDeleted()
 {
 {
   Q_D(ctkVTKConnection);
   Q_D(ctkVTKConnection);
   d->QtObject = 0;
   d->QtObject = 0;
-  d->disconnectSlots();
   d->disconnectVTKObject();
   d->disconnectVTKObject();
 }
 }
 
 

+ 2 - 1
Libs/Visualization/VTK/Core/ctkVTKConnection_p.h

@@ -30,6 +30,7 @@ class QObject;
 
 
 // VTK includes
 // VTK includes
 #include <vtkSmartPointer.h>
 #include <vtkSmartPointer.h>
+#include <vtkWeakPointer.h>
 class vtkObject;
 class vtkObject;
 class vtkCallbackCommand;
 class vtkCallbackCommand;
 
 
@@ -70,7 +71,7 @@ public:
   void execute(vtkObject* vtk_obj, unsigned long vtk_event, void* client_data, void* call_data);
   void execute(vtkObject* vtk_obj, unsigned long vtk_event, void* client_data, void* call_data);
 
 
   vtkSmartPointer<vtkCallbackCommand> Callback;
   vtkSmartPointer<vtkCallbackCommand> Callback;
-  vtkObject*                          VTKObject;
+  vtkWeakPointer<vtkObject>           VTKObject;
   const QObject*                      QtObject;
   const QObject*                      QtObject;
   unsigned long                       VTKEvent;
   unsigned long                       VTKEvent;
   QString                             QtSlot;
   QString                             QtSlot;