# Update model node color once the node is selected

**URL:** <https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704>\
**Category:** Support\
**Created:** [July 23, 2020, 4:01am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704 "2020-07-23T04:01:21Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [July 23, 2020, 4:01am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/1 "2020-07-23T04:01:21Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 23, 2020, 1:42pm UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/2 "2020-07-23T13:42:01Z")

</div>

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)`.

---

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [July 23, 2020, 3:42pm UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/3 "2020-07-23T15:42:49Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 23, 2020, 3:45pm UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/4 "2020-07-23T15:45:38Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [July 24, 2020, 5:57am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/5 "2020-07-24T05:57:07Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [July 24, 2020, 6:06am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/6 "2020-07-24T06:06:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [August 6, 2020, 9:25pm UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/7 "2020-08-06T21:25:21Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 7, 2020, 3:09am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/8 "2020-08-07T03:09:31Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [August 7, 2020, 1:37pm UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/9 "2020-08-07T13:37:08Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [August 7, 2020, 8:02pm UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/10 "2020-08-07T20:02:18Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 8, 2020, 1:38am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/11 "2020-08-08T01:38:48Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![szhang](https://avatars.discourse-cdn.com/v4/letter/s/bc8723/32.png) [@szhang](https://discourse.slicer.org/u/szhang)\
**Post date:** [August 8, 2020, 2:49am UTC](https://discourse.slicer.org/t/update-model-node-color-once-the-node-is-selected/12704/12 "2020-08-08T02:49:49Z")

</div>

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)
