Cannot import name 'vtkMRMLPathPlannerTrajectoryNode' at launch

ruffsl
Thu, 28 Aug 2025 01:29:54 +0000
Support

I have a working scripted extension that enables a user to select a path within any chosen trajectory list, as generated via the separate PathExplorer widget from the SlicerIGT extension:

SlicerIGT/PathExplorer at master · SlicerIGT/SlicerIGT · GitHub

However, after passing tests and restarting Slicer, I noticed a new ImportError during launch:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/opt/slicer/lib/Python/lib/python3.9/imp.py", line 169, in load_source
    module = _exec(spec, sys.modules[name])
  File "<frozen importlib._bootstrap>", line 613, in _exec
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/opt/air_ws/src/slicer/AirIGT/AirGUI/AirGUI.py", line 19, in <module>
    from slicer import (
ImportError: cannot import name 'vtkMRMLPathPlannerTrajectoryNode' from 'slicer' (/opt/slicer/bin/Python/slicer/__init__.py)
[Qt] loadSourceAsModule - Failed to load file "/opt/air_ws/src/air-sandbox/src/slicer/AirIGT/AirGUI/AirGUI.py"  as module "AirGUI" !
[Qt] Fail to instantiate module  "AirGUI"
[Qt] The following modules failed to be instantiated:
[Qt]    AirGUI

I import vtkMRMLPathPlannerTrajectoryNode from PathExplorer for Parameter node typing:

from slicer import (
    vtkMRMLMarkupsLineNode,
    vtkMRMLNode,
    vtkMRMLPathPlannerTrajectoryNode,
    vtkMRMLScalarVolumeNode,
)

@parameterNodeWrapper
class AirGUIParameterNode:
    inputPaths: vtkMRMLPathPlannerTrajectoryNode

Providing convent integration with nodeTypes & SlicerParameterName for the pathsSelector UI:

       <widget class="qMRMLNodeComboBox" name="pathsSelector">
        <property name="toolTip">
         <string>Pick input paths.</string>
        </property>
        <property name="nodeTypes">
         <stringlist notr="true">
          <string>vtkMRMLPathPlannerTrajectoryNode</string>
         </stringlist>
        </property>
        <property name="addEnabled">
         <bool>false</bool>
        </property>
        <property name="removeEnabled">
         <bool>false</bool>
        </property>
        <property name="SlicerParameterName" stdset="0">
         <string>inputPaths</string>
        </property>
       </widget>

SlicerIGT/PathExplorer/Resources/UI/qSlicerPathExplorerModuleWidget.ui at cc9678a9b6f91aa9ffde3ff0176cad357335616f · SlicerIGT/SlicerIGT · GitHub

Perhaps this results from some race conditions or lazily loaded imports? I did try declaring my external extension dependencies and moving/delaying the offending imports to inside my AirGUIParameterNode class as a work around for this limitation, but no dice.

class AirGUI(ScriptedLoadableModule):
    def __init__(self, parent):
        ScriptedLoadableModule.__init__(self, parent)
        self.parent.title = _("Air GUI")
        self.parent.categories = [translate("qSlicerAbstractCoreModule", "Wizards")]
        self.parent.dependencies = [
            "OpenIGTLinkIF",
            "PathExplorer",
        ]

Any recommendation for scripted modules using vtkMRML types from external C++ extentions?
Thanks!

2 posts - 1 participant