How to convert a custom 3D Slicer plugin with ParameterNodes into a CLI-friendly module?

Hi everyone,

I’ve been working on a custom plugin for 3D Slicer, and I’ve run into a design issue that makes it hard to reuse the logic outside of the GUI.

Right now, my ModuleWidget class is tightly coupled to the Slicer GUI elements:

  • self.ui and Qt widgets

  • qt.QSettings

  • slicer.util helpers

  • ParameterNodes via self._parameterNode

  • event filters, dialogs, and signal connections

This setup works fine inside Slicer, but it makes it unsuitable for running the same functionality in a pure Python CLI script (no Slicer GUI).

The functionality right now it’s tied into the widget/ParameterNode infrastructure.

My idea is to move the main logic into a separate class and make it GUI-independent. Then the widget would only handle the GUI and parameter syncing, while the new class could be imported and used in a CLI context. But this is more work.

Questions for the community:

  • What is the best way to convert any Custom Module to CLI module?

  • What is the recommended way to refactor a Slicer plugin if I want to reuse its logic outside of the GUI?

  • Is there a standard pattern for decoupling ParameterNodes from the processing logic?

  • Has anyone done a similar migration from a ScriptedLoadableModuleWidget to a CLI-usable module?

Any advice, best practices, or examples would be really helpful!

Thanks :folded_hands:

Can you be more specific about what your module does?

If you are using all these features of Slicer and you want to work outside of Slicer then you would need to find replacements somehow. Mostly when we factor out Logic classes it’s for things with few dependencies on application-level features. Things like image processing or linear algebra can factor out more easily, but signals, slots, and dialogs not so much.

I’ve addressed the issue by moving the logic into a separate class, whereas previously it was integrated directly into the Widget class.