Issues separating logic, widget and main classes

I am trying to separate my module into separate files for readability, and I’ve structured it similar to the Slicer DataProbe: Slicer/Modules/Scripted/DataProbe at 01984729eca68f0417ead58d87d3358912f094d4 · Slicer/Slicer · GitHub

Essentially, I have my main ModuleName.py:

import ModuleLib
class ModuleName(ScriptedLoadableModule):
...
def registerSampleData():
...
class ModuleNameTest(ScriptedLoadableModuleTest):
...

In the same directory, I have a subdirectory called ModuleNameLib with:
init.py:

from .Logic import ModuleNameLogic
from .Widget import ModuleNameWidget

Logic.py:

from . import Widget

class ModuleNameLogic(ScriptedLoadableModuleLogic):
...

And Widget.py:

from . import Logic

class ModuleNameWidget(ScriptedLoadableModuleWidget, VTKObservationMixin):
...

I have also updated my CMakeLists.txt with:

set(MODULE_PYTHON_SCRIPTS
  ${MODULE_NAME}.py
  ${MODULE_NAME}Lib/__init__
  ${MODULE_NAME}Lib/Logic
  ${MODULE_NAME}Lib/Widget
  )

When I run the module, I get a blank screen with the viewers on the right but no widget. I’m not sure if I’ve missed anything or made a mistake somewhere - I’m new to Slicer module development so any help would be appreciated. TIA!

This may not be the only issue, but the logic class shouldn’t know about the widget. The widget can use the logic to modify data (the nodes in the MRML scene) and the widget should update the GUI based on events that it observes. this way the GUI can be kept up to date with any scene changes made by it’s own or any other logic.

Good practice is to start with the Extension Wizard and make a module that is working and then incrementally change it to meet your needs, testing that it works at every step.

The logic class doesn’t actually use the widget, I had included it in the imports since I thought that may avoid the error. I have since removed it. I’ve added the widget class back to the main module file and kept the logic class in its own file based on this thread stating that the widget must be in the main module file, and this works fine. Another thread says that the widget can be kept in its own file, but I am having issues recreating it the same way.

Is there a way to keep the widget separate from the main module class, and if so, how can I correctly point to the right locations so the module class is aware of the widget?

The .py file at the top of the module’s directory is a special convention to have the entry points for the module to facilitate the discovery process. You can make a GUILib subfolder or similar that has helper classes for the GUI, such as composite widgets that also make use of the logic. There are several ways to organize this, but looking at the DICOMLib folder should give you an idea. I don’t recall now why this isn’t a subfolder of the DICOM module folder, but in any case it’ll give an idea how widgets and logic are organized.

1 Like