NifTK  16.4.1 - 0798f20
CMIC's Translational Medical Imaging Platform
How To - Write a Plugin

Location

All GUI plugins are contained in the folder

NifTK/MITK/Plugins

and the file Plugins.cmake controls which ones are on/off by default. In order to turn them on/off in a development environment, you must re-run CMake from the build folder, change the plugin's ON/OFF flag, and re-configure and re-build.

The MITK Plugin Generator

The basic structure of each plugin can be created automatically by using the MITK Plugin Generator. Once the whole NifTK code has been built once, in the main build folder, there will be a sub folder

<my-build>/MITK-build/MITK-build/bin

Within that MITK bin folder there is a program called MITKPluginGenerator.

From the NifTK-build sub-folder (i.e. not the top-level "Super Build" folder) a new plugin can be generated with a single command such as the following example for a plugin called "Affine Transform".

../MITK-build/MITK-build/bin/MITKPluginGenerator -o ../../NifTK/MITK/Plugins -l ~/build/NifTK/Documentation/TemplateCPlusPlus.txt -v "CMIC, Centre For Medical Image Computing, UCL." -vc AffineTransformView -vn "Affine Transform" -ps uk.ac.ucl.cmic.affinetransform -pn "Affine Transform"

In the above code, the -o options outputs the generated code directly to the NifTK source tree. The newly created files will need adding to version control manually. We also use a standard template text file to create the correct copyright headers.

You can then add the name of the plugin into

NifTK/MITK/Plugins/Plugins.cmake

and build. Please manually checking the following:

As the version of MITK changes, the plugin generator may do this automatically.

Naming Conventions

For consistency sake, it is important to take care when naming plugins and providing various strings that appear in the front end of the application, and in the documentation. This set of instructions was written using the Affine Transform plugin as a template, and applied to all other plugins at the time of writing. Please make every effort to keep each plugin and its documentation up to date, and to keep the names of things consistent.

The following general rules must be applied to get nice user documentation. Again, lots of this will be automated by the MITK Plugin Generator, but it is worth checking and understanding what each feature is.

Under

<plugin>/documentation/doxygen

there is doxygen.dox and the following additional rules must be applied to get consistent code documentation. The doxygen.dox is used to generate the page within this Technical Manual. It is not seen within the GUI, and is for developers only. As mentioned above, use an example as a guideline, for example, go and look at the Affine Transform plugin.

Managing Dependencies

For each plugin, the plugin's top-level CMakeLists.txt shows the library dependencies. For example in

NifTK/MITK/Plugins/uk.ac.ucl.cmic.midasgeneralsegmentor

we see

MODULE_DEPENDENCIES CTK QmitkExt niftkMitkExt niftkQmitkExt
)

which immediately reveals that the plugin is dependent on CTK and QmitkExt, and the NifTK modules niftkMitkExt and niftkQmitkExt which are MITK based modules within this project. In addition, the top level manifest_headers.cmake we see

set(Require-Plugin uk.ac.ucl.cmic.common )

Each plugin can define plugins that it depends on at both compile time and run time. So the above line is used when generating the plugin, and in this case will set up correct include paths for compilation.

So, with this in mind, it is important to keep the number of dependencies to a minimum. Don't include extra libraries in the CMakeLists.txt by just cutting and pasting and don't make your plugin's manifest_headers.cmake depend on too many other plugins. Also remember that plugin dependencies are transitive, so if A depends on B, which depends on C, then A also depends on C. So, try and make sure all NifTK plugins only depend on MITK plugins and our own Modules, and the list of dependencies is always minimal.

User Interface

There are two ways to generate a Qt GUI component for each plugin.

Lets look at the Snapshot plugin for a simple example of how to build a GUI, with code found here:

NifTK/MITK/Plugins/uk.ac.ucl.cmic.snapshot/src/internal

The steps required for this are:

The BlueBerry framework (part of MITK) creates the GUI at the appropriate time, so we do not put GUI construction code in the View components constructor. Also if Qt GUI components are registered with their parent in the layout then when the top level widget is destroyed, so will all registered children. For this reason, you will often not see class destructors trying to destroy Qt widgets.

The second option of writing all Qt code programmatically is very similar. Any widget could be created in the View class CreateQtPartControl and signals and slots connected to methods. Thus the View class is the main GUI starting point for each new plugin. There are now several examples in NifTK and many examples in MITK to inspire and to guide.

Within the project, Qt widgets can be stored in a number of places, depending on how general purpose the Qt widget is. The following guidelines may help.

In order to become proficient at writing Qt widgets please refer to:

Functionality

The actual functionality of a plugin can obviously vary immensely depending on user requirements. The View class is the starting point for methods. Here are some guiding principals, and hopefully this list can be extended over time.

Documentation

The GUI is constructed from all the plugins. So, each plugin must provide its own documentation page, written using Doxygen. For example look in:

NifTK/MITK/Plugins/uk.ac.ucl.cmic.imagelookuptables/documentation/UserManual

The Doxygen manual is here.

Testing

Unit testing a plugin can be difficult. For this reason the NifTK project structure has been set up so that as much as possible, all the functionality is provided in libraries/modules and the plugin should be a small wrapper bringing it all together. So the initial focus should be on unit testing each class outside of a plugin.

For example

Further examples are available throughout ITK, VTK and MITK. CTK has a Qt testing framework. It may be possible to leverage that, or provide good widgets back to CTK so they are unit tested as part of that project.

Also, keep an eye on the project dashboards to see how the project is currently compiling on different platforms.

Conclusion

Writing a plugin is easy in principal. In practice it may take a few attempts to get the user interaction to work nicely, but this is a small price to pay for having a nice GUI application.