소스 검색

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 년 전
부모
커밋
9e866356fd
2개의 변경된 파일13개의 추가작업 그리고 16개의 파일을 삭제
  1. 11 15
      Libs/Visualization/VTK/Core/ctkVTKConnection.cpp
  2. 2 1
      Libs/Visualization/VTK/Core/ctkVTKConnection_p.h

+ 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;