Pārlūkot izejas kodu

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 11 gadi atpakaļ
vecāks
revīzija
9e866356fd

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

@@ -52,7 +52,6 @@ ctkVTKConnectionPrivate::ctkVTKConnectionPrivate(ctkVTKConnection& object)
   this->Callback    = vtkSmartPointer<vtkCallbackCommand>::New();
   this->Callback->SetCallback(ctkVTKConnectionPrivate::DoCallback);
   this->Callback->SetClientData(this);
-  this->VTKObject   = 0;
   this->QtObject    = 0;
   this->VTKEvent    = vtkCommand::NoEvent;
   this->Priority    = 0.0;
@@ -111,10 +110,12 @@ void ctkVTKConnectionPrivate::connect()
       {
       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;
 }
 
@@ -160,7 +161,10 @@ void ctkVTKConnectionPrivate::disconnectVTKObject()
   if (this->VTKObject)
     {
     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()
 {
   Q_D(ctkVTKConnection);
-  if (d->ObserveDeletion)
-    {
-    d->disconnectSlots();
-    d->disconnectVTKObject();
-    }
+  d->disconnectVTKObject();
 }
 
 //-----------------------------------------------------------------------------
@@ -242,7 +242,7 @@ QObject* ctkVTKConnection::object()const
 vtkObject* ctkVTKConnection::vtkobject() const
 {
   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()
 {
   Q_D(ctkVTKConnection);
-  d->disconnectSlots();
   d->disconnectVTKObject();
 }
 
@@ -462,9 +461,7 @@ void ctkVTKConnection::disconnect()
 void ctkVTKConnection::vtkObjectDeleted()
 {
   Q_D(ctkVTKConnection);
-  d->VTKObject = 0;
   d->disconnectSlots();
-  d->disconnectVTKObject();
 }
 
 //-----------------------------------------------------------------------------
@@ -472,7 +469,6 @@ void ctkVTKConnection::qobjectDeleted()
 {
   Q_D(ctkVTKConnection);
   d->QtObject = 0;
-  d->disconnectSlots();
   d->disconnectVTKObject();
 }
 

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

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