Update model node color once the node is selected

Hello, I would like to learn in a scripted module, how to update the model color display once the model is selected in the slicer.qMRMLNodeComboBox() type of drop-down menu.
For example, is it about to update this line? or something else?

self.parent.connect(‘mrmlSceneChanged(vtkMRMLScene*)’, self.someModelNodeSelector, ‘setMRMLScene(vtkMRMLScene*)’)

Thank you very much.

Setting MRML scene in the node combobox is necessary, so leave this line as is. Instead connect a method to the currentNodeChanged signal and in that method change the model’s color using modelNode.GetDisplayNode().SetColor(r,g,b).

1 Like

Thanks, @lassoan
A follow-up question, to avoid all nodes turned to same highlight color, how should I return the previous selection to its original color upon every new selection in qMRMLNodeComboBox?

Yes, you should save the previously selected node and its color and restore it when a new model is selected.

Agree, I am not sure how to store the “previously selected node”, could you please provide some examples? Thanks a lot!

You store the node that you have just changed and its original color in member variables. Next time you change a new node, these member variables contain the previously selected node and its color.

I see, but I am afraid I still have trouble in implementing this, currently it is like this in the Widget main body setup

changedNodeColor = self.abcModelsNodeSelector.currentNode().GetDisplayNode().GetColor()
changedNode = self.abcModelsNodeSelector.currentNode()
self.abcModelsNodeSelector.connect(“currentNodeChanged(vtkMRMLNode*)”,self.onUpdateColor(changedNode,changedNodeColor))

and then the class definition is like this

def onUpdateColor(self,rNode,rNodeColor):
rNode.CreateDefaultDisplayNodes()
rNode.GetDisplayNode().SetColor(rNodeColor)
self.abcModelsNodeSelector.currentNode().GetDisplayNode().SetColor(0,1,0)

It did not generate error until I selected a new node, with the message of

TypeError: ‘NoneType’ object is not callable

Could you please kindly advise? Thanks a lot!

You need to save the previous node and color to member variables (self.previousModelNode, self.previousModelColor).

I see, I just changed the code to

self.changedNodeColor = self.abcModelsNodeSelector.currentNode().GetDisplayNode().GetColor()
self.changedNode = self.abcModelsNodeSelector.currentNode()
self.abcModelsNodeSelector.connect(“currentNodeChanged(vtkMRMLNode*)”, self.onUpdateColor(self.changedNode,self.changedNodeColor))

and keep the class definition the same, but the same error message appears

TypeError: ‘NoneType’ object is not callable

Am I missing something? Thank you again!

Hi @lassoan, I suppose it is related to some syntax in Qt Signals and Slots which I am trying to read upon, but I am not sure why self.changedNode will become empty once “currentNodechanged” happens, could you please help a bit further? Thank you!

In Python, the callback funcrion is specified by only its name (no argument list). Look at examples in the programming tutorials to see the correct syntax of connect.

Oh right, there is no need to put member variables as arguments, thank you very much @lassoan , it worked!
Here’s how the definition looks like for restoring the previous node, to wrap up this thread of discussion.

def onUpdateColor(self)
self.changedNode.CreateDefaultDisplayNodes()
self.changedNode.GetDisplayNode().SetColor(self.changedNodeColor)
self.changedNode = self.abcModelsNodeSelector.currentNode()
self.changedNodeColor = self.abcModelsNodeSelector.currentNode().GetDisplayNode().GetColor()
self.abcModelsNodeSelector.currentNode().GetDisplayNode().SetColor(1,0,0)

1 Like