Difference between revisions of "Documentation/Nightly/Developers/Tutorials/CreateLoadableModule"
Line 1: | Line 1: | ||
<noinclude>{{documentation/versioncheck}}</noinclude> | <noinclude>{{documentation/versioncheck}}</noinclude> | ||
=Consider also reading= | =Consider also reading= | ||
+ | *[[Documentation/{{documentation/version}}/Training#Developing_and_contributing_extensions_for_3D_Slicer|Developing and contributing extensions for 3D Slicer]] | ||
*[[Media:QtPortInSlicer.ppt|QtPortInSlicer - How to write a module]] | *[[Media:QtPortInSlicer.ppt|QtPortInSlicer - How to write a module]] | ||
*[[Documentation/{{documentation/version}}/Developers/Tutorials/ExternalModuleWriting|How to write an external module]] | *[[Documentation/{{documentation/version}}/Developers/Tutorials/ExternalModuleWriting|How to write an external module]] |
Latest revision as of 13:47, 26 August 2016
Home < Documentation < Nightly < Developers < Tutorials < CreateLoadableModule
For the latest Slicer documentation, visit the read-the-docs. |
Contents
Consider also reading
- Developing and contributing extensions for 3D Slicer
- QtPortInSlicer - How to write a module
- How to write an external module
Initialization
1) Create the module directory
Use the extension wizard to generate files and directory based on a template.
2) Build
See Documentation/Nightly/Developers/ExtensionWizard#Building
3) Install
See Documentation/Nightly/Developers/ExtensionWizard#.22Installation.22
4) Check the module
Start Slicer and make sure the module is present (listed under "Module Template")
$ ./Slicer
To change the module title that shows up in Slicer, edit the file Slicer4/Modules/Loadable/MY_MODULE_NAME/CMakeLists.txt
set(MODULE_TITLE "Your title")
Other properties for the module such as help, acknowledgment or categories can be re-implemented directly in C++ by editing Slicer4/Modules/Loadable/MY_MODULE_NAME/qSlicerMY_MODULE_NAME.cxx
.
5) Open Qt Designer using the launcher
Slicer (the launcher) searches Qt Designer on your machine (using QT_QMAKE_EXECUTABLE
set at configure time). It starts the designer after setting the correct environment variables (QT_PLUGIN_PATH
for the widgets designer plugins and PATH/LD_LIBRARY_PATH for the libraries).
$ ./Slicer --designer
6) Change the UI
Using Qt Designer, edit the module UI file: Modules/Loadable/MY_MODULE_NAME/Resources/UI/qSlicerMY_MODULE_NAMEModule.ui
More info on how to use the designer
7) Edit the module files
Slicer4/Modules/Loadable/MY_MODULE_NAME/qSlicerMY_MODULE_NAME.[h|cxx] Slicer4/Modules/Loadable/MY_MODULE_NAME/qSlicerMY_MODULE_NAMEWidget.[h|cxx] Slicer4/Modules/Loadable/MY_MODULE_NAME/Logic/vtkSlicerMY_MODULE_NAMELogic.[h|cxx] ...
Qt Designer
- How to set icons to widgets
- In the icon property entry of the widget (Property Editor), select a resource file
- Slicer4/Modules/Loadable/MY_MODULE_NAME/Resources/qSlicerMY_MODULE_NAMEModule.qrc
- Slicer4/Libs/MRML/Widgets/Resources/qMRMLWidget.qrc
- Slicer4/Base/QTGUI/Resources/qSlicerBaseQTGUI.qrc
- In the icon property entry of the widget (Property Editor), select a resource file
- How to add an icon in a resource file
- Add the icon in Slicer4/Modules/Loadable/MY_MODULE_NAME/Resources/Icon
- Edit the resource file by adding the line
- "<file>Icons/MyIcon.png</file>"
Dependency between modules
It is possible that your module needs to access information from another module. Typically the logic or the custom MRML classes of a module. The following code is an example of what can be done to make your module dependent to the Volumes module logic:
In CMakeLists.txt:
set(MODULE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/Widgets ${CMAKE_CURRENT_BINARY_DIR}/Widgets ${vtkSlicerVolumesModuleLogic_SOURCE_DIR} ${vtkSlicerVolumesModuleLogic_BINARY_DIR} ) ... set(MODULE_TARGET_LIBRARIES ... vtkSlicerVolumesModuleLogic )
In qSlicerMY_MODULE_NAMEModule.cxx:
//----------------------------------------------------------------------------- QStringList qSlicerMY_MODULE_NAMEModule::dependencies()const { return QStringList() << "Volumes"; } //----------------------------------------------------------------------------- void qSlicerMY_MODULE_NAMEModule::setup() { this->Superclass::setup(); vtkSlicerMY_MODULE_NAMELogic* moduleLogic = vtkSlicerMY_MODULE_NAMELogic::SafeDownCast(this->logic()); qSlicerAbstractCoreModule* volumesModule = qSlicerCoreApplication::application()->moduleManager()->module("Volumes"); if (volumesModule) { vtkSlicerVolumesLogic* volumesLogic = vtkSlicerVolumesLogic::SafeDownCast(volumesModule->logic()); moduleLogic->SetVolumesLogic(volumesLogic); }
By specifying the module as a dependency, you are insured that the dependency module will be setup before your module is setup.
Follow the same pattern in CMakeLists.txt to add dependency on a module widgets:
set(MODULE_INCLUDE_DIRECTORIES ... ${qSlicerVolumesModuleWidgets_SOURCE_DIR} ${qSlicerVolumesModuleWidgets_BINARY_DIR} ... ) ... set(MODULE_TARGET_LIBRARIES ... qSlicerVolumesModuleWidgets )
It works the same if you want to access the custom MRML (vtkSlicerDEPENDENT_MODULEModuleMRML_SOURCE_DIR) or displayable manager (vtkSlicerDEPENDENT_MODULEModuleDisplayableManager_SOURCE_DIR) classes.
Examples
- Crop Volume module depends on Volumes module