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
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. 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).
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:
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 ?
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.
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)
As to the two events, there may be a bug in bool vtkMRMLMarkupsNode::InsertControlPoint(ControlPoint *controlPoint, int targetIndex), line 689 of vtkMRMLMarkupsNode.cxx:
// 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?
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.