NifTK
16.4.1 - 0798f20
CMIC's Translational Medical Imaging Platform
|
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 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".
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.
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.
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
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
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.
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:
NifTK/MITK/Plugins/uk.ac.ucl.cmic.snapshot/CMakeLists.txt
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.
NifTK/Libraries/QtWidgetsNotice that the TARGET_LINK_LIBRARIES only depends on default Qt libraries. So, widgets here, know NOTHING about the application they will be used for.
NifTK/MITK/Moduleswe have Modules called niftkMitkExt and niftkQmitkExt. These folder names simply refer to the fact that they are NifTK specifc extensions to the MITK libraries called MitkExt and QmitkExt. Qt widgets can be placed in niftkQmitkExt and NOT niftkMitkExt. Widgets in this folder are somewhat specific to NiftyView.
<plugin-name>/src/internalfolder.
In order to become proficient at writing Qt widgets please refer to:
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.
NifTK/MITK/Plugins/uk.ac.ucl.cmic.midasmorphologicalsegmentor/src/MIDASMorphologicalSegmentorViewPreferencePage.h/.cxx.and this page is added to files.cmake to compile it, plugin.xml to run it at run-time and registered with the framework in MIDASMorphologicalSegmentorViewActivator.
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.
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.
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.