Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations

Presentation on theme: "Port of 3D Slicer to Qt Julien Finet & Jean-Christophe Fillion-Robin Kitware Inc. June 22 th 2010."— Presentation transcript:

1 Port of 3D Slicer to Qt Julien Finet & Jean-Christophe Fillion-Robin Kitware Inc. June 22 th 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.2Qt Building Slicer with Qt –Use Superbuild – r4:Build_Instructions r4:Build_Instructions

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

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

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

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

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

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

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

11 Events with Qt Object 1 Object 2 Node Selected Signal

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

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

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

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 Usage // CTK includes #include … 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); … } QVTK_OBJECT adds the function qvtkConnect()

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

18 Private Implementation Hide the implementation details of an interface #include "qCTKPimpl.h" … class MyButtonPrivate; … class MyButton : public QAbstractButton { Q_OBJECT public: … private: CTK_DECLARE_PRIVATE(MyButton); }; friend class MyButtonPrivate; ctkPrivateInterface ctk_d; Dont forget to declare the private class

19 Private Implementation class MyButtonPrivate : public qCTKPrivate { 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; } … } MyButtonPrivate* d = ctk_d() MyButton* p = ctk_p()

20 Slicer3 vs SlicerQt SlicerQt Qt only Slicer3 KWWidgets + Qt

21 Slicer qMRML Widgets QtGUI Slicer Architecture QtCore CTK Core CTK Widgets Base/QTCore Base/QTGUI Base/LogicMRML

22 Modules Core Modules: Slicer3/Base/QTCoreModules –Transforms qSlicerTransformsModule –… Loadable Modules: Slicer3/QTModules –TractographyFiducialSeeding –Volumes –… 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 QTCLI: Example … Registration Parameters Parameters used for registration HistogramBins b histogrambins Number of histogram bins to use for Mattes Mutual Information. Histogram Bins … 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) … 3) Dynamically created panel 1) Xml description 2) Parse parameters and generate UI

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

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

27 Widgets Awareness LibraryQTCoreQtGuiVTKMRMLApp. CTK/Libs/CoreYes CTK/Libs/WidgetsYes CTK/Libs/Visualization/VTK/CoreYes CTK/Libs/Visualization/VTK/WidgetsYes Slicer3/Libs/qMRMLWidgetsYes Slicer3/Base/QTCoreYes Slicer3/Base/QTGUIYes

28 CTK Widgets ctkCollapsibleButton ctkCollapsibleGroupBox ctkColorPickerButton ctkTreeComboBox ctkFixedTitleComboBox

29 qMRMLWidgets Projects:QtSlicer/Gallery Projects:QtSlicer/Gallery Usually contains the slot setMRMLScene(vtkMRMLScene*) qMRMLNodeSelector qMRMLTreeWidget qMRMLListWidget qMRMLWindowLevelWidget

30 Widgets in Qt Designer A plugin must be created –Slicer3/Libs/qMRMLWidgets/Plugins/qMRMLNodeSel ectorPlugin. [ h|cxx ] More info on – opers:Projects:QtSlicer/Tutorials/WidgetWriting opers:Projects:QtSlicer/Tutorials/WidgetWriting

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

32 Questions More info: cer3:Developers:Projects:QtSlicer cer3:Developers:Projects:QtSlicer

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

Similar presentations

Ads by Google