Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer...

38
Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6

Transcript of Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer...

Page 1: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Port of 3D Slicer to Qt

Julien FinetKitware Inc.Jan. 05th 2010 Updated May 14th 2010 for Slicer 3.6

Page 2: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Background

• 3D 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

• NIH Supplement to help with port– 9/17/2009 - 9/16/2011

Page 3: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Qt – How to get Qt

• Required version: Qt 4.6• Building Slicer with Qt

– http://wiki.slicer.org/slicerWiki/index.php/Slicer3:Developers:Projects:QtSlicer/Tutorials/CompileWithQt

• Links: – Doc: http://qt.nokia.com/doc/4.6/index.html– Tutorials:

http://qt.nokia.com/doc/4.6/tutorials.html

Page 4: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

First steps with Qt

First Steps with Qt

Julien FinetKitware Inc.Jan. 05th 2010

Page 5: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Qt in Slicer

• Events with KWWidgets1. Fire event

2. Connect

3. Process

void vtkSlicerCamerasGUI::AddGUIObservers(){ … this->ViewSelectorWidget->AddObserver( vtkSlicerNodeSelectorWidget::NodeSelectedEvent, (vtkCommand *)this->GUICallbackCommand ); …}

void vtkSlicerCamerasGUI::ProcessGUIEvents( vtkObject *caller, unsigned long event, void *callData ){ if (vtkSlicerNodeSelectorWidget::SafeDownCast(caller)) { if (event == vtkSlicerNodeSelectorWidget::NodeSelectedEvent) { …}

void vtkSlicerNodeSelectorWidget::ProcessCommand(char *selectedID){ … this->InvokeEvent(vtkSlicerNodeSelectorWidget::NodeSelectedEvent, NULL); …} vtkSlicerNodeSelectorWidget.cxx

vtkSlicerCamerasGUI.cxx

vtkSlicerCamerasGUI.cxx

Page 6: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Qt in Slicer

• Events with Qt1. Fire event

2. Connect

3. Process

void qSlicerCamerasModuleWidget::setup(){ … connect(d->ViewNodeSelector, SIGNAL(currentNodeChanged(vtkMRMLNode*)), this, SLOT(onCurrentViewNodeChanged(vtkMRMLNode*))); …}

void qSlicerCamerasModuleWidget::onCurrentViewNodeChanged(vtkMRMLNode* mrmlNode){ vtkMRMLViewNode* currentViewNode = vtkMRMLViewNode::SafeDownCast(mrmlNode); …}

void qMRMLNodeSelector::nodeIdSelected(int index){ … emit currentNodeChanged(d->MRMLCurrentNode);}

qSlicerCamerasModuleWidget.cxx

qSlicerCamerasModuleWidget.cxx

qMRMLNodeSelector.cxx

Page 7: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Qt and VTK

• qVTKConnect() – Based on

VTK/GUISupport/Qt/vtkEventQtSlotConnect

void qMRMLNodeSelector::addNode(vtkMRMLNode* mrmlNode){ … this->qvtkConnect(mrmlNode, vtkCommand::ModifiedEvent, this, SLOT(onMRMLNodeModified(vtkObject*, void*))); …}

// qVTK includes#include <qVTKObject.h>…class QMRML_WIDGETS_EXPORT qMRMLNodeSelector : public qCTKAddRemoveComboBox{ Q_OBJECT QVTK_OBJECTpublic: … qMRMLNodeSelector.h

qMRMLNodeSelector.cxx

QVTK_OBJECT adds the function qvtkConnect()

Page 8: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Porting Slicer to Qt

• Create Qt/KWW co-existence layer (done!)• Prototype a few modules (done!)• Create an architecture for Qt based modules

(in process)• Train developers (first session at January

2010 Project Week)• Port modules (ongoing through 2010…)• Turn off KWW (by end of 2010?)• Continual Improvement (through end of

supplement and beyond…)

Page 9: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Porting Slicer to Qt

• Slicer: Qt only

• Slicer: KWWidgets + Qt

Executable: Slicer3

Executable: SlicerQT

Page 10: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Modules

• Core Modules: Slicer3/Base/QTCoreModules

– Transforms qSlicerTransformsModule

– …• Loadable Modules: Slicer3/QTModules

– TractographyFiducialSeeding libqSlicerTractographyFiducialSeedingModule.so

– Volumes libqSlicerVolumesModule.so– …

• CLI Modules: Slicer3/Applications/CLI

– …

Page 11: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

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: …};

…Q_EXPORT_PLUGIN2(qSlicerVolumesModule, qSlicerVolumesModule);…

QPluginLoader loader;loader.setFileName(pluginPath);loader.load();QObject * object = this->Loader.instance();qSlicerAbstractLoadableModule* module = qobject_cast<qSlicerAbstractLoadableModule*>(object); Plugin Loader

Plugin implementation

Plugin header

Page 12: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Modules: Logic + UI

Logic(vtkSlicerModuleLogic)

create()create() create()create()

UI (qSlicerAbstractModuleWidget)

Module(qSlicerAbstractModule)

vtkMRMLScene

QWidget

QObject

qSlicer…ModuleWidget.ui

Designer UI file

Page 13: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

How to write a loadable module

• Create directories in Slicer3/QTModules– MyModule– MyModule/Resources– MyModule/Resources/UI– MyModule/Resources/Icons (optional)

• Create the files– MyModule/CMakeLists.txt– MyModule/qSlicerMyModule.[h/cxx]– MyModule/qSlicerMyModuleWidget.[h/cxx]– MyModule/Logic/vtkSlicerMyModuleLogic.[h/cxx] (optional)

• Can also reuse the module logic in Modules/MyModule/Logic– MyModule/Resources/qSlicerMyModule.qrc (optional)– MyModule/Resources/UI/qSlicerMyModule.ui

Page 14: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

MyModule UI – 1 / 4

• Open Qt designer – “cd Slicer3-build; Slicer3.exe --designer” – Warning: on Windows, plugins must be

compiled under the same mode than Qt (Release/Debug)

– More info on http://wiki.slicer.org/slicerWiki/index.php/Slicer3:Developers:Projects:QtSlicer/Tutorials/QtDesigner

Page 15: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

My Module UI – 2 / 4

• Create a UI form:– MyModule/Resources/UI/qSlicerMyModule.ui

• qSlicerWidget has the signal mrmlSceneChanged()

Qt Designer

Page 16: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

MyModule UI – 3 / 4

Drag widgets on the form

Names are important Qt Designer

Page 17: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

My Module UI – 4 / 4

Connect widgets together with the signals/slots

Here the MRMLScene of the module is propagated to the NodeSelector

Qt Designer

Page 18: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

MyModule Resources

• If icons are used, they should go in – MyModule/Resources/Icons/

• Update the resource .qrc file– MyModule/Resources/qSlicerMyModule.qrc

<!DOCTYPE RCC><RCC version="1.0"> <qresource> <file>Icons/MyIcon.png</file> …</qresource></RCC> qSlicerMyModule.qrc

Page 19: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

qSlicerMyModule.h#ifndef __qSlicerMyModule_h#define __qSlicerMyModule_h

// SlicerQT includes#include "qSlicerAbstractLoadableModule.h“

#include "qSlicerMyModuleWin32Header.h“ // generated by CMakeclass qSlicerMyModulePrivate;

class Q_SLICER_QTMODULES_MYMODULE_EXPORT qSlicerMyModule : public qSlicerAbstractLoadableModule{ Q_OBJECTpublic: qSlicerTransformsModule(QObject *parent=0);

virtual QString title()const { return “Transforms”; }

virtual QString helpText()const; virtual QString acknowledgementText()const;

protected: // Create and return a widget representation of the object virtual qSlicerAbstractModuleWidget * createWidgetRepresentation(); virtual vtkSlicerModuleLogic* createLogic();};#endif qSlicerMyModule.h

Page 20: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

qSlicerMyModule.cxx#include "qSlicerMyModule.h"

// SlicerQT includes#include "qSlicerMyModuleWidget.h"

// QT includes#include <QtPlugin>//-----------------------------------------------------------------------------Q_EXPORT_PLUGIN2(qSlicerMyModule, qSlicerMyModule);//-----------------------------------------------------------------------------qSlicerMyModule(QObject* parent) :public qSlicerAbstractLoadableModule(parent){}//-----------------------------------------------------------------------------qSlicerAbstractModuleWidget * qSlicerTransformsModule::createWidgetRepresentation(){ return new qSlicerMyModuleWidget;}//-----------------------------------------------------------------------------vtkSlicerModuleLogic* qSlicerTransformsModule::createLogic(){ return 0;}

Instantiate the UI widget

qSlicerMyModule.cxx

Don’t forget to export the module

Page 21: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

qSlicerMyModuleWidget.h

#ifndef __qSlicerMyModuleWidget_h#define __qSlicerMyModuleWidget_h

// SlicerQT includes#include "qSlicerAbstractModuleWidget.h"

// qCTK includes#include <qCTKPimpl.h>

#include "qSlicerMyModuleExport.h"

class qSlicerMyModuleWidgetPrivate;

class Q_SLICER_QTMODULES_MYMODULE_EXPORT qSlicerMyModuleWidget : public qSlicerAbstractModuleWidget{ Q_OBJECTpublic: typedef qSlicerAbstractModuleWidget Superclass; qSlicerMyModuleWidget(QWidget *parent=0);

protected: virtual void setup();

private: QCTK_DECLARE_PRIVATE(qSlicerMyModuleWidget);};

#endif

Configured by CMake

Setup the UI

qSlicerMyModuleWidget.h

Page 22: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

qSlicerMyModuleWidget.cxx

#include "qSlicerMyModuleWidget.h"#include "ui_qSlicerMyModule.h"

//-----------------------------------------------------------------------------struct qSlicerMyModuleWidgetPrivate: public qCTKPrivate<qSlicerMyModuleWidget>, public Ui_qSlicerMyModule{};

//-----------------------------------------------------------------------------qSlicerMyModuleWidget ::qSlicerMyModuleWidget( QWidget* parent) :qSlicerAbstractModuleWidget(parent){ QCTK_INIT_PRIVATE(qSlicerMyModuleWidget);}

//-----------------------------------------------------------------------------void qSlicerWelcomeModuleWidget::setup(){ QCTK_D(qSlicerWelcomeModuleWidget); d->setupUi(this);}

Generated by CMake (via uic) from qSlicerMyModule.ui

Creates the QWidgets

…void setupUi(qSlicerWidget *qSlicerMyModule){ … verticalLayout = new QVBoxLayout(qSlicerMyModule); CTKCollapsibleButton = new qCTKCollapsibleButton(qSlicerMyModule); CTKCollapsibleButton->setCollapsed(true);

horizontalLayout = new QHBoxLayout(CTKCollapsibleButton); label = new QLabel(CTKCollapsibleButton); horizontalLayout->addWidget(label);

horizontalSlider = new QSlider(CTKCollapsibleButton); …} Ui_qSlicerMyModule.h

qSlicerMyModuleWidget.cxx

Page 23: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

MyModule project

• Create a CMakeLists.txt in MyModule

• Add your module in QTModules/CMakeLists.txt

SET(qt_module_SRCS qSlicerMyModule.cxx qSlicerMyModule.h qSlicerMyModuleWidget.cxx qSlicerMyModuleWidget.h )Slicer3_build_qtmodule( NAME “MyModule” TITLE “My Module” EXPORT_DIRECTIVE "Q_SLICER_QTMODULES_MYMODULE_EXPORT“ SRCS ${qt_module_SRCS} MOC_SRCS qSlicerMyModuleWidget.h UI_SRCS Resources/UI/qSlicerMyModule.ui TARGET_LIBRARIES ${qt_module_target_libraries} RESOURCES Resources/qSlicerMyModule.qrc ) QTModules/MyModule/CMakeLists.txt

Page 24: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Tadam !

MyModule Panelhere

MyModule

Slicer3

Page 25: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Module: with a logic and slots:qSlicerTransformsModuleWidget

class … qSlicerTransformsModuleWidget : public qSlicerAbstractModuleWidget{ Q_OBJECT …public slots: void loadTransform();…};

class qSlicerTransformsModuleWidgetPrivate: public qCTKPrivate<qSlicerTransformsModuleWidget>, public Ui_qSlicerTransformsModule{public: qSlicerTransformsModuleLogic* logic() const;};

void qSlicerTransformsModuleWidget::loadTransform(){ QCTK_D(qSlicerTransformsModuleWidget); QString fileName = QFileDialog::getOpenFileName(this); d->logic()->AddTransform(fileName);}

void qSlicerTransformsModuleWidget::setup(){ QCTK_D(qSlicerTransformsModuleWidget); d->setupUi(this); …this->connect(d->LoadTransformPushButton, SIGNAL(clicked()), SLOT(loadTransform()));}

Called by the “Load Transform” pushbutton

Page 26: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Widgets

Library QT VTK MRML

qCTKWidgets Yes

qVTKWidgets Yes Yes

qMRMLWidgets Yes Yes Yes

qSlicerBaseQTGUI Yes Yes Yes

Page 27: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

qCTKWidgets

• Common Toolkit (CTK)

• Currently hosted on the Slicer repository

qCTKCollapsibleButton

qCTKCollapsibleGroupBox

qCTKColorPickerButton qCTKTreeComboBox

qCTKFixedTitleComboBox

Page 28: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

qMRMLWidgets• Depends on QT and MRML• Usually contains the slot

setMRMLScene(vtkMRMLScene*)

qMRMLNodeSelector

qMRMLMatrixWidget

qMRMLTreeWidget

qMRMLListWidget

Page 29: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Private Implementation

• Hide the implementation details of an interface

• http://en.wikipedia.org/wiki/Opaque_pointer

// qCTK includes#include "qCTKPimpl.h"

// QT includes#include <QAbstractButton>

class qCTKCollapsibleButtonPrivate;

class QCTK_WIDGETS_EXPORT qCTKCollapsibleButton : public QAbstractButton{ Q_OBJECT public: qCTKCollapsibleButton(QWidget *parent = 0);…private: QCTK_DECLARE_PRIVATE(qCTKCollapsibleButton);};

#endif

friend class qCTKCollapsibleButtonPrivate; qCTKPrivateInterface<qCTKCollapsibleButton, qCTKCollapsibleButtonPrivate> qctk_d;

Don’t forget to declare the private class

Page 30: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Private Implementation//-----------------------------------------------------------------------------class qCTKCollapsibleButtonPrivate : public qCTKPrivate<qCTKCollapsibleButton>{public: QCTK_DECLARE_PUBLIC(qCTKCollapsibleButton); void init();

bool Collapsed; …};

//-----------------------------------------------------------------------------void qCTKCollapsibleButtonPrivate::init(){ QCTK_P(qCTKCollapsibleButton); p->setCheckable(true); // checked and Collapsed are synchronized: checked != Collapsed p->setChecked(true);

this->Collapsed = false;}

//-----------------------------------------------------------------------------qCTKCollapsibleButton::qCTKCollapsibleButton(QWidget* parent) :QAbstractButton(parent){ QCTK_INIT_PRIVATE(qCTKCollapsibleButton); qctk_d()->init();}

//-----------------------------------------------------------------------------void qCTKCollapsibleButton::collapse(bool c){ QCTK_D(qCTKCollapsibleButton); if (c == d->Collapsed) { return; } …}

friend class qCTKCollapsibleButton

qctk_d.setPublic(this)

qCTKCollapsibleButtonPrivate* d = qctk_d()

qCTKCollapsibleButton* p = qctk_p()

Page 31: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Widgets in Qt Designer

• A plugin must be created– Slicer3/Libs/qCTKWidgets/Plugins/

qMRMLNodeSelectorPlugin.[h|cxx]– Slicer3/Libs/qMRMLWidgets/Plugins/

qMRMLNodeSelectorPlugin.[h|cxx]

• More info on– http://wiki.slicer.org/slicerWiki/index.php/

Slicer3:Developers:Projects:QtSlicer/Tutorials/WidgetWriting

Page 32: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Widget ExampleQt 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

Page 33: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

QTCLI

• Same idea than KWWidgets– Parse XML to build UI

• Support– Shared Libraries– Executables– Python

UI panel in Slicer

Page 34: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

QTCLI: Example…<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>…

…qCTKCollapsibleButton* registrationParameters = new qCTKCollapsibleButton(“Registration Parameters”, this);QLabel* histogramBinLabel = new QLabel(“Histogram Bins”, registrationParameters);QSlider* histogramBin = new QSlider(registrationParameters);histogramBin->setMinimum(1);histogramBin->setMaximum(500);histogramBin->setStep(5);histogramBin->setValue(30);QObject::connect(histogramBin, SIGNAL(valueChanged(int)), this, SIGNAL(onHistogramValueChanged(int)));…

UI panel in SlicerXml description

Generated code

Page 35: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Slicer Architecture

QTBaseqSlicerAbstractModule

QTCLIqSlicerCLIModule

QTCoreModulesqSlicerCamerasModules, qSlicerTransformsModule

QTCoreqSlicerModuleFactory, , qSlicerCoreIOManager

QTGUIqSlicerModulePanel, qSlicerApplication, qSlicerIOManager

Page 36: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

What’s coming soon ?

• CLI modules

• Node tree widgets

• 3D view widget

• Lookup table editor

• Slice view widget

• …

Page 37: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

What’s in the Pipeline ?

• Wizards

• Python

• More widgets – help from the CTK community– http://www.commontk.org/cgi-bin/trac.cgi/

wiki/WidgetPlans

Page 38: Port of 3D Slicer to Qt Julien Finet Kitware Inc. Jan. 05 th 2010 Updated May 14 th 2010 for Slicer 3.6.

Questions

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