1 / 32

Port of 3D Slicer to Qt

Port of 3D Slicer to Qt. Julien Finet & Jean-Christophe Fillion -Robin Kitware Inc. June 22 th 2010. Background. Slicer version 3.x use KWWidgets VTK-style interface to Tk 3D Slicer 1.x, 2.x used Tk directly Qt

Download Presentation

Port of 3D Slicer to Qt

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Port of 3D Slicer to Qt Julien Finet & Jean-Christophe Fillion-Robin Kitware Inc. June 22th 2010

  2. Background • Slicer version 3.x use KWWidgets • VTK-style interface to Tk • 3D Slicer 1.x, 2.x used Tk directly • Qt • Embedded Linux, Mac OS X, Windows, Linux/X11, Windows CE/Mobile, Symbian, Maemo • Commercial/LGPL • 600+ classes • Tens of thousands of applications • 15+ millions of users

  3. Qt – How to get Qt • Required version: Qt 4.6.2 • Building Slicer with Qt • Use Superbuild • http://www.slicer.org/slicerWiki/index.php/Slicer4:Build_Instructions

  4. Events with KWWidgets • Connect vtkCallbackCommand vtkObject::AddObserver • Fire event vtkObject::InvokeEvent() • Process myClass::myMethod()

  5. Events with KWWidgets Object2 Callback Node Selected Event Object 1 Object 2

  6. Events with KWWidgets 1) Connect this->CallbackCommand = vtkCallbackCommand::New(); this->CallbackCommand->SetClientData(object2); this->CallbackCommand->SetCallback(vtkObject2::MethodX); Object2 Callback Node Selected Event Object 1 Object 2 MethodX

  7. Events with KWWidgets 1) Connect object1>AddObserver(vtkObject1::NodeSelectedEvent, this>CallbackCommand); Object2 Callback Node Selected Event Object 1 Object 2

  8. Events with KWWidgets 2) Signal void vtkObject1::Method2(){ … this->InvokeEvent(vtkObject1::NodeSelectedEvent, NULL); } Object2 Callback Node Selected Event Object 1 Object 2 Method2

  9. Events with KWWidgets 3) Process void vtkObject2::MethodX(vtkObject *caller, unsigned long event, void *callData ) { if (vtkObject2::SafeDownCast(caller) && event == vtkObject2::NodeSelectedEvent) { … Object2 Callback Node Selected Event Object 1 Object 2 MethodX

  10. Events with Qt • Connect QObject::connect(obj1,signal, obj2, slot); • Fire event emit mySignal(); • Process myClass::mySlot();

  11. Events with Qt Node Selected Signal Object 1 Object 2

  12. Events with Qt 1) Connect this->QObject::connect(obj1, SIGNAL(nodeSelected(vtkMRMLNode*)), obj2, SLOT(methodX(vtkMRMLNode*))); Node Selected Signal Object 1 Object 2

  13. Events with Qt 2) Signal void vtkObject1::Method2(){ … emit this->currentNodeSelected(node); } Node Selected Signal Object 1 Object 2

  14. Events with Qt 3) Process void vtkObject2::MethodX(vtkMRMLNode* node) { … } Node Selected Signal Object 1 Object 2 MethodX

  15. Qt and VTK: qVTKConnect • qvtkConnect( vtkObject* vtk_obj, unsigned long vtk_event,const QObject* qt_obj, const char* qt_slot, float priority = 0.0) • Also: qvtkReconnect, qvtkDisconnect, qvtkDisconnectAll…

  16. Qt and VTK: qVTKConnect QVTK_OBJECT adds the function qvtkConnect() Usage // CTK includes #include <ctkVTKObject.h> … class MyWidget: public QWidget { Q_OBJECT QVTK_OBJECT public: void setNode(vtkMRMLNode* mrmlNode); protected slots: void onMRMLNodeModified(vtkObject* sender); }; … void MyWidget ::setNode(vtkMRMLNode* mrmlNode) { … qvtkConnect( mrmlNode, vtkCommand::ModifiedEvent, this, SLOT(onMRMLNodeModified(vtkObject*))); … } void MyWidget ::onMRMLNodeModified(vtkObject* sender) { vtkMRMLNode* node = vtkMRMLNode::SafeDowncast(sender); … }

  17. Interaction between MRML & Qt valueChanged(double) Modified Event Qt Slider MRML Node Module Widget void onNodeModified( vtkMRMLNode* node) { slider->setValue(node->GetValue()); } void onValueChanged(double newValue) { node->SetValue(newValue); }

  18. Private Implementation • Hide the implementation details of an interface • http://en.wikipedia.org/wiki/Opaque_pointer #include "qCTKPimpl.h" … class MyButtonPrivate; … class MyButton : public QAbstractButton { Q_OBJECT public: … private: CTK_DECLARE_PRIVATE(MyButton); }; Don’t forget to declare the private class friend class MyButtonPrivate; ctkPrivateInterface<MyButton, MyButtonPrivate> ctk_d;

  19. Private Implementation class MyButtonPrivate : public qCTKPrivate<MyButton> { public: CTK_DECLARE_PUBLIC(MyButton); void init(); bool Collapsed; … }; void MyButtonPrivate::init() { CTK_P(MyButton); p->setCheckable(true); this->Collapsed = false; } MyButton::MyButton(QWidget* parent) :QAbstractButton(parent) { CTK_INIT_PRIVATE(MyButton); ctk_d()->init(); } void MyButton::collapse(bool c) { CTK_D(MyButton); if (c == d->Collapsed) { return; } … } MyButton* p = ctk_p() MyButtonPrivate* d = ctk_d()

  20. Slicer3 vsSlicerQt • SlicerQtQt only • Slicer3 KWWidgets + Qt

  21. Slicer Architecture Slicer Base/Logic MRML CTK Core QtCore Base/QTCore Base/QTGUI qMRMLWidgets CTK Widgets QtGUI

  22. Modules • Core Modules: Slicer3/Base/QTCoreModules • Transforms qSlicerTransformsModule • … • Loadable Modules: Slicer3/QTModules • TractographyFiducialSeedinglibqSlicerTractographyFiducialSeedingModule.so • Volumes libqSlicerVolumesModule.so • … • CLI Modules: Slicer3/Applications/CLI • …

  23. QTCLI • Same idea than KWWidgets • Parse XML to build UI • Support • Shared Libraries • Executables • Python UI panel in Slicer

  24. 3) Dynamically created panel QTCLI: Example 1) Xml description … <parameters> <label>Registration Parameters</label> <description>Parameters used for registration</description> <integer> <name>HistogramBins</name> <flag>b</flag> <longflag>histogrambins</longflag> <description>Number of histogram bins to use for Mattes Mutual Information. </description> <label>Histogram Bins</label> <default>30</default> <constraints> <minimum>1</minimum> <maximum>500</maximum> <step>5</step> </constraints> </integer> … … If (paramType == “integer”) { QSlider* intParameter = new QSlider(registrationParameters); intParameter->setMinimum(paramMin); intParameter->setMaximum(paramMax); intParameter->setStep(paramStep); intParameter->setValue(paramValue); QObject::connect(intParameter, SIGNAL(valueChanged(int)), this, SIGNAL(onParamValueChanged(int))); } else if (paramType == “double”) … 2) Parse parameters and generate UI

  25. Plugin Mechanism • Previously: itksys::DynamicLoader(dlopen) • Now: Use the QT Plugins framework … class Q_SLICER_QTMODULES_VOLUMES_EXPORT qSlicerVolumesModule : public qSlicerAbstractLoadableModule { Q_INTERFACES(qSlicerAbstractLoadableModule); public: … }; Plugin header … Q_EXPORT_PLUGIN2(qSlicerVolumesModule, qSlicerVolumesModule); … Plugin implementation QPluginLoader loader; loader.setFileName(pluginPath); loader.load(); QObject * object = this->Loader.instance(); qSlicerAbstractLoadableModule* module = qobject_cast<qSlicerAbstractLoadableModule*>(object); Plugin Loader

  26. Loadable Modules: Logic + UI Module Plugin (qSlicerAbstractModule) create() create() Module Widget (qSlicerAbstractModuleWidget) Logic (vtkSlicerModuleLogic) Module Designer UI qSlicer…ModuleWidget.ui vtkMRMLScene

  27. Widgets Awareness

  28. CTK Widgets commontk.org • http://www.commontk.org/index.php/Documentation/ImageGallery ctkFixedTitleComboBox ctkCollapsibleGroupBox ctkCollapsibleButton ctkTreeComboBox ctkColorPickerButton

  29. qMRMLWidgets • http://wiki.slicer.org/slicerWiki/index.php/Slicer3:Developers:Projects:QtSlicer/Gallery • Usually contains the slot setMRMLScene(vtkMRMLScene*) qMRMLNodeSelector qMRMLListWidget qMRMLWindowLevelWidget qMRMLTreeWidget

  30. Widgets in Qt Designer • A plugin must be created • Slicer3/Libs/qMRMLWidgets/Plugins/qMRMLNodeSelectorPlugin.[h|cxx] • More info on • http://wiki.slicer.org/slicerWiki/index.php/Slicer3:Developers:Projects:QtSlicer/Tutorials/WidgetWriting

  31. Widget Example class QCTK_WIDGETS_EXPORT qCTKCollapsibleButton : public QAbstractButton { Q_OBJECT Q_PROPERTY(bool collapsed READ collapsed WRITE setCollapsed) Q_PROPERTY(intcollapsedHeight READ collapsedHeight WRITE setCollapsedHeight) … public: void setCollapsed(bool); bool collapsed()const; void setCollapsedHeight(int); intcollapsedHeight()const; Qt Designer qCTKCollapsibleButton.h 10 = default value void qCTKCollapsibleButtonPrivate::init() { QCTK_P(qCTKCollapsibleButton); … this->Collapsed = false; … this->CollapsedHeight = 10; … } qCTKCollapsibleButton.cxx

  32. Questions • More info: http://wiki.slicer.org/slicerWiki/index.php/Slicer3:Developers:Projects:QtSlicer

More Related