# Handle Markups events from an external module

**URL:** <https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332>\
**Category:** Development\
**Created:** [March 28, 2019, 8:37pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332 "2019-03-28T20:37:16Z")\
**Posts on this page:** 8\
**Page:** 2

<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:** [May 29, 2019, 4:39pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/22 "2019-05-29T16:39:29Z")

</div>

I’ve done some debugging and it turns out that PointModifiedEvent and similar high-level events still use integer parameters, so you can access them using

```auto
@vtk.calldata_type(vtk.VTK_INT)
def onMarkupChanged(caller,event,call_data):
    print(event)
    print(call_data)

```

More sophisticated interaction events are available at lower level (in VTK widgets) and those could be propagated to MRML nodes, but vtkEventData based objects are not Python-wrapped so they could not be used from Python. I’ve [asked about this on VTK forum](https://discourse.vtk.org/t/vtkeventdata-based-classes-are-not-python-wrapped/1044/2). We’ll proceed according to what we hear back from there (it’ll be either a VTK fix or we add a vtkObject based wrapper around the vtkEventData based object).

---

<div class="post-metadata">

**Author:** ![Johan\_Andruejol](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/johan_andruejol/32/3639_2.png) [@Johan\_Andruejol](https://discourse.slicer.org/u/Johan_Andruejol)\
**Post date:** [August 23, 2019, 8:16pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/23 "2019-08-23T20:16:02Z")

</div>

Hi,

I have been working with the Markups and more specifically the PointAddedEvent.  
I have noticed that the event is only called when you switch to one view from another (like @mirclem noticed).  
I need to be able to know when a Markup control point is added (i.e. defined) in the view. Unfortunately the PointAddedEvent doesn’t fire when the point becomes defined. Here is the snippet that I used:

```python
m = slicer.mrmlScene.AddNode(slicer.vtkMRMLMarkupsFiducialNode())

def onPointAdded(caller, event):
  print("added ", caller.GetNthControlPointPositionStatus(0))

m.AddObserver(slicer.vtkMRMLMarkupsNode.PointAddedEvent, p)

```

This prints:

```auto
added 1 # View change (PointUndefined)
added 1 # View change (PointUndefined)
#Missing added 2 (PointDefined) :(

```

It doesn’t send a signal when the status becomes PointDefined.

I am aware that I could manage that through the PointModifiedEvent and check the point’s status but that seems counter-intuitive and it makes it harder for the UI.

Do you think adding a PointAddedEvent when the point becomes defined makes sense ?

Thanks !  
Johan

---

<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 23, 2019, 9:01pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/24 "2019-08-23T21:01:58Z")

</div>

It seems to be a common need to get notification when a point becomes defined, so I’ll add a new event for this.

---

<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 27, 2019, 6:09pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/25 "2019-08-27T18:09:56Z")

</div>

I’ve added a new pair of events (available in Slicer Preview Release from tomorrow): `slicer.vtkMRMLMarkupsNode.PointPositionDefinedEvent` and `slicer.vtkMRMLMarkupsNode.PointPositionUndefinedEvent`. These are only invoked when a point is placed or a placed point is removed. Not impacted by point previews.

```python
def onMarkupPointPositionDefined(caller, event):
    markupsNode = caller
    movingMarkupIndex = markupsNode.GetDisplayNode().GetActiveControlPoint()
    logging.info(f"Markup point added: point ID = {movingMarkupIndex}")

def onMarkupPointPositionUndefined(caller, event):
    markupsNode = caller
    logging.info(f"Markup point removed.")

markupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")
markupsNode.CreateDefaultDisplayNodes()
markupsNode.AddFiducial(0,0,0)
markupsNode.AddObserver(slicer.vtkMRMLMarkupsNode.PointPositionDefinedEvent, onMarkupPointPositionDefined)
markupsNode.AddObserver(slicer.vtkMRMLMarkupsNode.PointPositionUndefinedEvent, onMarkupPointPositionUndefined)

```

---

<div class="post-metadata">

**Author:** ![Johan\_Andruejol](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/johan_andruejol/32/3639_2.png) [@Johan\_Andruejol](https://discourse.slicer.org/u/Johan_Andruejol)\
**Post date:** [August 28, 2019, 7:32pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/26 "2019-08-28T19:32:13Z")

</div>

This is great ! Thanks so much !  
I was able to quickly make my code work with these.

P.S.:  
What’s the [`PointPlacedEvent`](https://github.com/Slicer/Slicer/blob/master/Modules/Loadable/Markups/MRML/vtkMRMLMarkupsNode.h#L202) ? Was it added for future use ?

---

<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 28, 2019, 7:44pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/27 "2019-08-28T19:44:17Z")

</div>

> [@Johan\_Andruejol](#):
>
> What’s the [`PointPlacedEvent`](https://github.com/Slicer/Slicer/blob/master/Modules/Loadable/Markups/MRML/vtkMRMLMarkupsNode.h#L202) ? Was it added for future use ?

I added that event ID but finally did not end up using it. I’ll write some tests and with that commit remove `PointPlacedEvent`.

---

<div class="post-metadata">

**Author:** ![Fangwen\_Zhai](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/fangwen_zhai/32/6001_2.png) [@Fangwen\_Zhai](https://discourse.slicer.org/u/Fangwen_Zhai)\
**Post date:** [March 24, 2020, 6:44am UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/28 "2020-03-24T06:44:01Z")

</div>

> [@lassoan](#):
>
> I’ve added a new pair of events (available in Slicer Preview Release from tomorrow): `slicer.vtkMRMLMarkupsNode.PointPositionDefinedEvent` and `slicer.vtkMRMLMarkupsNode.PointPositionUndefinedEvent`. These are only invoked when a point is placed or a placed point is removed. Not impacted by point previews.
> 
> ```python
> def onMarkupPointPositionDefined(caller, event):
> markupsNode = caller
> movingMarkupIndex = markupsNode.GetDisplayNode().GetActiveControlPoint()
> logging.info(f"Markup point added: point ID = {movingMarkupIndex}")
> 
> def onMarkupPointPositionUndefined(caller, event):
> markupsNode = caller
> movingMarkupIndex = markupsNode.GetDisplayNode().GetActiveControlPoint()
> logging.info(f"Markup point removed: point ID = {movingMarkupIndex}")
> 
> markupsNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")
> markupsNode.CreateDefaultDisplayNodes()
> markupsNode.AddFiducial(0,0,0)
> markupsNode.AddObserver(slicer.vtkMRMLMarkupsNode.PointPositionDefinedEvent, onMarkupPointPositionDefined)
> markupsNode.AddObserver(slicer.vtkMRMLMarkupsNode.PointPositionUndefinedEvent, onMarkupPointPositionUndefined)
> 
> ```

As to the two events, there may be a bug in `bool vtkMRMLMarkupsNode::InsertControlPoint(ControlPoint *controlPoint, int targetIndex)`, line 689 of vtkMRMLMarkupsNode.cxx:

```C++
// let observers know that a markup was added
  this->InvokeCustomModifiedEvent(vtkMRMLMarkupsNode::PointAddedEvent, static_cast<void*>(&targetIndex));
  if (controlPoint->PositionStatus == vtkMRMLMarkupsNode::PositionDefined)
    {
    this->InvokeCustomModifiedEvent(vtkMRMLMarkupsNode::PointPositionUndefinedEvent, static_cast<void*>(&targetIndex));
    }
  this->UpdateMeasurements();

```

I think PointPositionUndefinedEvent should be PointPositionDefinedEvent?

---

<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:** [March 24, 2020, 12:19pm UTC](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332/29 "2020-03-24T12:19:13Z")

</div>

Good catch, thank you, indeed when a point was inserted into a curve then wrong event ID was used. I’ve pushed a fix now, which will be available in the Slicer Preview Release from tomorrow.

[Previous page](https://discourse.slicer.org/t/handle-markups-events-from-an-external-module/6332.md?page=1)
