Page MenuHomePhabricator

Compare responsibilities of QmitkSliceNavigationController related classes
Open, NormalPublic


Three classes exist that somehow deal with handling the changed positions of slice navigation controller:

  • QmitkSliceNavigationListener
  • QmitkSliderNavigatorWidget
  • QmitkStepperAdapter

The QmitkSliceNavigationListener was extracted from MatchPoint to be reused in other plugins. It is currently used inside QmitkVolumeVisualizationView, QmitkImageStatisticsView, QmitkMatchPointRegistrationEvaluator, QmitkMatchPointRegistrationManipulator and ModelFitInspectorView.
It is used in the following way:

  • the QmitkSliceNavigationListener connects upon initialization the events of the QmitkSliceNavigationController (e.g. GeometrySliceEvent) with an internal function
  • this internal functions retrieves the new time / position from the active render window part
  • if the time / position has changed, one event for each of the two changes is sent
  • these two events are typically connected by a class (that is using the QmitkSliceNavigationListener) to some internal functions that need to perform an action with the new time / position

--> In general the goal of this class is to easily allow to be notified about a new selected time point / selected position of the render window part

Problem with this class:
The selected time point / selected position is retrieved from the current render window part. The signal to retrieve this information is sent by the slice navigation controller.
There is an indirection involved: The render window part also needs to know its selected time point / selected position and get updated if a slice navigation controller has changed. How does it do that? The TimeNavigationController is controlled by the RenderingManager. A RenderingManager is a singleton and only one RenderingManager should exist inside the MITK Workbench. The render window parts (i.e. SimpleRenderWindowView or QmitkAbstractRenderEditor) simply use the RenderingManager to get the TimeNavigationController to get the selected time point. So why does the QmitkSliceNavigationListener not directly return the selected time point of the globally accessible TimeNavigationController?
Maybe because the slice navigation listener should be implementation-independent and not care if this assumption of a single, globally accessible TimeNavigationController is always valid? If so, the the class is maybe not a SliceNavigationListener but a RenderWindowPartListener.

The QmitkSliderNavigatorWidget is a Qt-widget to display a slider with a spinbox (and some labels), which allow to change the current position of a single connected QmitkSlicenavigationController. It is currently used inside QmitkImageNavigatorView, QmitkBasicImageProcessingView
The widget works the following way:

  • the QmitkSliderNavigatorWidget provides a ctkDoubleSpinBox and a ctkDoubleSlider that can be modified by the user via the GUI
  • they are connected to internal functions that update the member variable m_Stepper according to the new value
    • this involves calling a Refetch-function, which will update the slider- and spingbox-widget
  • the m_Stepper has to be set from outside
    • a dependent class has to provide the Stepper of a SliceNavigationController for this variable

--> In general the goal of this class is to provide Qt-UI elements for the user to interact with a stepper (which typically comes from a SliceNavigationController)

Problem with this class:
The QmitkSliderNavigatorWidget is only used in conjunction with the QmitkStepperAdapter, where the navigation widget and a slice navigation controller are used as arguments for the constructor (more details see below).
The QmitkStepperAdapter-adapter already reacts on the changes of a stepper by transforming the itk::ModifiedEvent into a Qt-Signal, which is then received by the QmitkSliderNavigatorWidget. However, if the slider or the spinbox changes, a call to this->Refetch() happens anyway, so Refetch is called twice.

QmitkStepperAdapter is a Qt-Adapter class to connect a QObject with a stepper. It is currently used inside QmitkPreprocessingResamplingView, QmitkImageNavigatorView, QmitkBasicImageProcessingView, QmitkSliceWidget and QmitkSimpleExampleView.
It is used in the following way:

  • the constructor takes a QObject and an mitk::Stepper
  • the stepper's itk::ModifiedEvent is connected with the StepperAdapter's own Refetch-signal
  • the refetch signal is connected to the QObject's Refetch-slot
  • additionally a dependent class can react on the Refetch-signal of the StepperAdapter

--> In general the goal of this class is to transform the itk::ModifiedEvent into a Qt-Signal, which can be connected to the QObject-navigator (typically a QmitkSliderNavigatorWidget) and emitted to every other class that uses the QmitkStepperAdapter.

Problems with this class:
This class only adds another level of indirection in order to forward a itk::ModifiedEvent() to the QObject (the slice navigation widget). This could simply be done by using the command inside the slice navigation widget itself.
Furthermore the QmitkStepperAdapter is not fully implemented: setting a new stepper via SetStepper will not replace the existing one / remove the observer.
(Also I think the comment inside the mitkSliceNavigationController.h is wrong: The QmitkStepperAdapter converts the Qt-signals to Qt-independent itk-events. As far as I can see it is the other way around, turning itk-events from the stepper into a "Refetch" Qt-Signal.

All in all I think this class was not cleanly designed and should be removed. It is a small class but not easy to understand since it consists mainly of signals and events.
Btw., it was also mentioned in T22122: Eliminate uses of itkSetMacro, introduce blocking/unblocking events that listening to this modified-event of the stepper although the geometry of the corresponding renderer might not completely be updated is not a good idea.

Revisions and Commits

Restricted Differential Revision
Restricted Differential Revision
Restricted Differential Revision