From bc7d4e5e4cbdf300226b5a2886023d0da5309ed1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Sun, 29 Oct 2023 14:42:13 -0400 Subject: [PATCH] BUG: Ensure virtual functions can be called from derived ctkVTK view pimpl Add protected constructor to ctkVTKRenderView and ctkVTKSliceView for associating a derived pimpl. This is required to have the complete virtual function chain executed when virtual function are called in the pimpl init() function. --- .../VTK/Widgets/ctkVTKAbstractView.cpp | 3 ++ .../VTK/Widgets/ctkVTKAbstractView_p.h | 1 + .../VTK/Widgets/ctkVTKRenderView.cpp | 28 +++++++++++++++---- .../VTK/Widgets/ctkVTKRenderView.h | 3 ++ .../VTK/Widgets/ctkVTKRenderView_p.h | 4 ++- .../VTK/Widgets/ctkVTKSliceView.cpp | 21 +++++++++++++- .../VTK/Widgets/ctkVTKSliceView.h | 1 + .../VTK/Widgets/ctkVTKSliceView_p.h | 6 +++- 8 files changed, 59 insertions(+), 8 deletions(-) diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.cpp b/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.cpp index 965108b671..2a44ce1991 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.cpp +++ b/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.cpp @@ -64,6 +64,9 @@ ctkVTKAbstractViewPrivate::ctkVTKAbstractViewPrivate(ctkVTKAbstractView& object) this->PauseRenderCount = 0; } +// -------------------------------------------------------------------------- +ctkVTKAbstractViewPrivate::~ctkVTKAbstractViewPrivate() = default; + // -------------------------------------------------------------------------- void ctkVTKAbstractViewPrivate::init() { diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView_p.h b/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView_p.h index 76693d7508..e2f9ff863f 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView_p.h +++ b/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView_p.h @@ -52,6 +52,7 @@ class ctkVTKAbstractViewPrivate : public QObject public: ctkVTKAbstractViewPrivate(ctkVTKAbstractView& object); + virtual ~ctkVTKAbstractViewPrivate(); /// Convenient setup methods virtual void init(); diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.cpp b/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.cpp index 620bccc95c..0ce88a8f16 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.cpp +++ b/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.cpp @@ -60,6 +60,21 @@ ctkVTKRenderViewPrivate::ctkVTKRenderViewPrivate(ctkVTKRenderView& object) this->Orientation->SetOrientationMarker(this->Axes); } +// -------------------------------------------------------------------------- +ctkVTKRenderViewPrivate::~ctkVTKRenderViewPrivate() = default; + +// -------------------------------------------------------------------------- +void ctkVTKRenderViewPrivate::init() +{ + this->ctkVTKAbstractViewPrivate::init(); + + // The interactor in RenderWindow exists after the renderwindow is set to + // the QVTKWidet + this->Orientation->SetInteractor(this->RenderWindow->GetInteractor()); + this->Orientation->SetEnabled(1); + this->Orientation->InteractiveOff(); +} + // -------------------------------------------------------------------------- void ctkVTKRenderViewPrivate::setupCornerAnnotation() { @@ -204,18 +219,21 @@ ctkVTKRenderView::ctkVTKRenderView(QWidget* parentWidget) { Q_D(ctkVTKRenderView); d->init(); +} - // The interactor in RenderWindow exists after the renderwindow is set to - // the QVTKWidet - d->Orientation->SetInteractor(d->RenderWindow->GetInteractor()); - d->Orientation->SetEnabled(1); - d->Orientation->InteractiveOff(); +// -------------------------------------------------------------------------- +ctkVTKRenderView::ctkVTKRenderView(ctkVTKRenderViewPrivate* pimpl, QWidget* parentWidget) + : Superclass(pimpl, parentWidget) +{ + // derived classes must call init manually. Calling init() here may results in + // actions on a derived public class not yet finished to be created } //---------------------------------------------------------------------------- ctkVTKRenderView::~ctkVTKRenderView() { } + //---------------------------------------------------------------------------- void ctkVTKRenderView::setInteractor(vtkRenderWindowInteractor* newInteractor) { diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.h b/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.h index c82458a930..73273593a0 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.h +++ b/Libs/Visualization/VTK/Widgets/ctkVTKRenderView.h @@ -186,6 +186,9 @@ public Q_SLOTS: /// Return zoom factor double zoomFactor()const; +protected: + ctkVTKRenderView(ctkVTKRenderViewPrivate* pimpl, QWidget* parent); + private: Q_DECLARE_PRIVATE(ctkVTKRenderView); Q_DISABLE_COPY(ctkVTKRenderView); diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKRenderView_p.h b/Libs/Visualization/VTK/Widgets/ctkVTKRenderView_p.h index bda5088ab7..d03b572beb 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKRenderView_p.h +++ b/Libs/Visualization/VTK/Widgets/ctkVTKRenderView_p.h @@ -43,15 +43,17 @@ class vtkRenderWindowInteractor; //----------------------------------------------------------------------------- /// \ingroup Visualization_VTK_Widgets -class ctkVTKRenderViewPrivate : public ctkVTKAbstractViewPrivate +class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKRenderViewPrivate : public ctkVTKAbstractViewPrivate { Q_OBJECT Q_DECLARE_PUBLIC(ctkVTKRenderView); public: ctkVTKRenderViewPrivate(ctkVTKRenderView& object); + virtual ~ctkVTKRenderViewPrivate(); /// Convenient setup methods + void init() override; void setupCornerAnnotation() override; void setupRendering() override; diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.cpp b/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.cpp index eadd1e0706..b1aea4c146 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.cpp +++ b/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.cpp @@ -50,6 +50,18 @@ ctkVTKSliceViewPrivate::ctkVTKSliceViewPrivate(ctkVTKSliceView& object) this->OverlayRenderer = vtkSmartPointer::New(); } +// -------------------------------------------------------------------------- +ctkVTKSliceViewPrivate::~ctkVTKSliceViewPrivate() = default; + +// -------------------------------------------------------------------------- +void ctkVTKSliceViewPrivate::init() +{ + Q_Q(ctkVTKSliceView); + this->ctkVTKAbstractViewPrivate::init(); + + q->VTKWidget()->installEventFilter(q); +} + // -------------------------------------------------------------------------- void ctkVTKSliceViewPrivate::setupCornerAnnotation() { @@ -100,7 +112,14 @@ ctkVTKSliceView::ctkVTKSliceView(QWidget* parentWidget) { Q_D(ctkVTKSliceView); d->init(); - this->VTKWidget()->installEventFilter(this); +} + +// -------------------------------------------------------------------------- +ctkVTKSliceView::ctkVTKSliceView(ctkVTKSliceViewPrivate* pimpl, QWidget* parentWidget) + : Superclass(pimpl, parentWidget) +{ + // derived classes must call init manually. Calling init() here may results in + // actions on a derived public class not yet finished to be created } // -------------------------------------------------------------------------- diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.h b/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.h index dff19ce135..6d5ad29b37 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.h +++ b/Libs/Visualization/VTK/Widgets/ctkVTKSliceView.h @@ -133,6 +133,7 @@ public Q_SLOTS: void resized(const QSize& size); protected: + ctkVTKSliceView(ctkVTKSliceViewPrivate* pimpl, QWidget* parent); bool eventFilter(QObject *object, QEvent *event) override; private: diff --git a/Libs/Visualization/VTK/Widgets/ctkVTKSliceView_p.h b/Libs/Visualization/VTK/Widgets/ctkVTKSliceView_p.h index c3148e0031..6ab2097e5c 100644 --- a/Libs/Visualization/VTK/Widgets/ctkVTKSliceView_p.h +++ b/Libs/Visualization/VTK/Widgets/ctkVTKSliceView_p.h @@ -41,13 +41,17 @@ class vtkRenderWindowInteractor; //----------------------------------------------------------------------------- /// \ingroup Visualization_VTK_Widgets -class ctkVTKSliceViewPrivate : public ctkVTKAbstractViewPrivate +class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKSliceViewPrivate : public ctkVTKAbstractViewPrivate { Q_OBJECT + Q_DECLARE_PUBLIC(ctkVTKSliceView); + public: ctkVTKSliceViewPrivate(ctkVTKSliceView&); + virtual ~ctkVTKSliceViewPrivate(); /// Convenient setup methods + void init() override; void setupCornerAnnotation() override; void setupRendering() override;