Edit this page

NA-MIC Project Weeks

Back to Projects List

Debug - Paremeter Node and qtMRMLComboBox set to 'None' after adding to a subject hierarchy

Key Investigators

Project Description

Bug description:

  1. Sync a parameter node to a qtMRLComboBox node.
  2. Add the parameter node to a subjectHierarchy folder. Both the parameter Node and the qtMRMLComboBox node set to ‘None’.

Slicer Discourse thread

Objective

  1. Fix the bug

Approach and Plan

Here is a sample script that connect a qtMRMLComboBox node to a parameter node, and creating a subjectHierarchy folder to add the parameter node to it. Both will be set to ‘None’

import slicer, qt
from slicer.parameterNodeWrapper import parameterNodeWrapper

@parameterNodeWrapper
class SHTestParameters:
    selectedFiducial: slicer.vtkMRMLMarkupsFiducialNode

dialog = qt.QDialog(slicer.util.mainWindow())
dialog.setWindowTitle("SHComboBox move -> GUI reset -> Param wipe test")
layout = qt.QVBoxLayout(dialog)

shComboBox = slicer.qMRMLSubjectHierarchyComboBox()
shComboBox.nodeTypes = ["vtkMRMLMarkupsFiducialNode"]
shComboBox.noneEnabled = True
shComboBox.setMRMLScene(slicer.mrmlScene)

layout.addWidget(qt.QLabel("Select a fiducial (SubjectHierarchyComboBox):"))
layout.addWidget(shComboBox)

runButton = qt.QPushButton("Move selected node into folder (triggers reset)")
layout.addWidget(runButton)

parameterNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScriptedModuleNode", "SHCombo_ParamNode_Test")
parameter = SHTestParameters(parameterNode)

shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene)

def printState(tag):
    print(f"\n[{tag}]")
    print("  shComboBox.currentItem():", shComboBox.currentItem())
    print("  shComboBox.currentNode():", shComboBox.currentNode())
    print("  parameter.selectedFiducial:", parameter.selectedFiducial)

# sync combo box to the parameter node similar to the original module
def onComboChanged(itemId):
    node = shNode.GetItemDataNode(itemId)
    parameter.selectedFiducial = node
    printState("Combo changed (GUI->param sync fired)")

shComboBox.connect("currentItemChanged(vtkIdType)", onComboChanged)

#Add the parameter node to a folder
def onRun():
    currentItemID = shComboBox.currentItem()
    if currentItemID == 0:
        print("No selection (currentItemID==0)")
        return

    # seed parameter node explicitly (like your "store orbitLm/plateLm first")
    parameter.selectedFiducial = shNode.GetItemDataNode(currentItemID)

    printState("BEFORE MOVE")

    folderItemID = shNode.CreateFolderItem(shNode.GetSceneItemID(), "SHCombo_TestFolder")
    shNode.SetItemParent(currentItemID, folderItemID)

    printState("AFTER MOVE (post SetItemParent)")

runButton.connect("clicked()", onRun)

dialog.show()
dialog.raise_()
dialog.activateWindow()

Image

[AFTER MOVE (post SetItemParent)]
shComboBox.currentItem(): 0
shComboBox.currentNode(): None
parameter.selectedFiducial: None

If qt combobox signal is blocked using qt.QSignalBlocker, then parameter node will not be set to ‘None’

Progress and Next Steps

Illustrations

No response

Background and References

No response