# Markup nodes - option for locked/unlocked on creation?

**URL:** <https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981>\
**Category:** Development\
**Created:** [August 13, 2020, 5:46pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981 "2020-08-13T17:46:01Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [August 13, 2020, 5:46pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/1 "2020-08-13T17:46:01Z")

</div>

It looks like the default lock status for markup nodes is unlocked by default - looking in the vtkMRMLMarkupsNode() constructor, it sets Locked to 0 on the second line of code.

I almost never move markups, unless to move them back after creating them and accidentally moving them if they’re unlocked. I basically have added hitting the “lock all” button periodically to my workflow to make sure I don’t inadvertently move them around.

Is there a reason they’re unlocked by default? Would there be any interest in an option for toggling unlocked/locked on creation?

Thanks!

-Hollister

---

<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 13, 2020, 6:05pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/2 "2020-08-13T18:05:09Z")

</div>

As far as I can see, moving markup points is very common: most often you place it approximately in one view, potentially in 3D, then you verify and fine-tune the position in multiple, zoomed-in slice views. If that’s not your workflow then no problem, you can modify default properties of new nodes by specifying a default node - see [examples in script repository](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#Set_all_slice_views_linked_by_default). You can put those few lines into your `.slicerrc.py` file to make it always the default on your computer.

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [August 13, 2020, 6:08pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/3 "2020-08-13T18:08:00Z")

</div>

Ah, ok - that’s MUCH cleaner than my solution. Right now I have a hotkey set to place a fiducial, and in that function I run SetAllMarkupsLocked().

Thanks Andras! Hope you’re doing well.

-Hollister

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [October 4, 2021, 1:15pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/4 "2021-10-04T13:15:55Z")

</div>

This is a _very_ stale thread, sorry, but I’m finally getting to doing this the right way rather than my old hacky solution.

I’m trying to make a default markups node like this:

```
defaultMarkupNode = slicer.vtkMRMLMarkupsNode()
defaultMarkupNode.SetLocked(1)
slicer.mrmlScene.AddDefaultNode(defaultMarkupNode)

```

but when I do this, new markups still show up as unlocked. What am I doing wrong here?

THANKS!

-Hollister

---

<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:** [October 4, 2021, 1:26pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/5 "2021-10-04T13:26:22Z")

</div>

It is all good, you just need to create more concreate default node class(es). To prevent moving line node endpoints after placement:

```python
defaultMarkupNode = slicer.vtkMRMLMarkupsLineNode()
defaultMarkupNode.SetLocked(1)
slicer.mrmlScene.AddDefaultNode(defaultMarkupNode)

```

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [October 4, 2021, 1:44pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/6 "2021-10-04T13:44:20Z")

</div>

Hmph… something still missing, I put both these code snippets in my `.slicerrc.py` file and when I make a new markup node and add points, they’re still unlocked. Is there something I need to do to tell the `vtkMRMLMarkupsFiducialNode` that it needs to use those particular `vtkMRMLMarkupsNode`s as defaults? (This question likely doesn’t make any sense…)

---

<div class="post-metadata">

**Author:** ![jamesobutler](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jamesobutler/32/7511_2.png) [@jamesobutler](https://discourse.slicer.org/u/jamesobutler)\
**Post date:** [October 4, 2021, 2:57pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/7 "2021-10-04T14:57:41Z")

</div>

For a Fiducial node, the following works for me where the control points are not movable and are locked. If it doesn’t work for you, download a new Slicer version, don’t install any extensions, and test this snippet.

```python
defaultMarkupNode = slicer.vtkMRMLMarkupsFiducialNode() # fiducial node markup
defaultMarkupNode.SetLocked(1)
slicer.mrmlScene.AddDefaultNode(defaultMarkupNode)

```

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [October 4, 2021, 3:05pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/8 "2021-10-04T15:05:18Z")

</div>

OK, that does make the point immovable, but it does not show as locked in the control points list. I’m also not able to rename the point by right-clicking on the point - it’s completely locked and not modifiable.

What I’m looking for is to lock the position by default but be able to rename it via right clicking.

My hacky work-around has been okay thus far, so if this takes any real amount of time to look into, no need to bother.

Thanks!!!

---

<div class="post-metadata">

**Author:** ![jamesobutler](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jamesobutler/32/7511_2.png) [@jamesobutler](https://discourse.slicer.org/u/jamesobutler)\
**Post date:** [October 4, 2021, 3:13pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/9 "2021-10-04T15:13:23Z")

</div>

Yes the example code has been setting the Locked state for the node which applies to all control points rather than setting the locked state for the individual control point. The locked state in the example code is indicated by the locked icon in the GUI as shown with the tooltip.  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/4/a/4a74b0ee415451db02463120c7860358898e317f.png)

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [October 4, 2021, 3:14pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/10 "2021-10-04T15:14:46Z")

</div>

Ah, okay. Is it possible to make a default control point that is locked?

---

<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:** [October 4, 2021, 4:16pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/11 "2021-10-04T16:16:56Z")

</div>

Control points are currently always initialized unlocked. You could lock them without Slicer core change by adding an observer to control point add event and lock every newly added control points. However, if “locked by default” is a common need then it would be quite easy to add a flag for this in the markups node.

I guess you need locking because you want to avoid accidental modification of placed points (e.g., when you rotate the view you may accidently click on a control point), which must be a common need. @smrolfe How do your users solve the problem of accidentally misplaced control points?

@hherhold would you mind describing your use case on [this page](https://github.com/Slicer/Slicer/wiki/Markups-rework) so that we can get more complete picture of how people use markups?

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [October 4, 2021, 5:19pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/12 "2021-10-04T17:19:40Z")

</div>

Yeah, as described in the use case I added (below), I set up a shortcut key to run a quick function that locks all control points. The minus is that it locks all the ones done thus far, so the one just placed is unlocked, but it’s been better than nothing. (Yes, very hacky.)

I’ll take a look at adding an observer - that’s far more elegant.

> [@lassoan](#):
>
> @hherhold would you mind describing your use case on [this page](https://github.com/Slicer/Slicer/wiki/Markups-rework) so that we can get more complete picture of how people use markups?

Done.

---

<div class="post-metadata">

**Author:** ![smrolfe](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/smrolfe/32/3659_2.png) [@smrolfe](https://discourse.slicer.org/u/smrolfe)\
**Post date:** [October 4, 2021, 5:51pm UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/13 "2021-10-04T17:51:30Z")

</div>

> [@lassoan](#):
>
> guess you need locking because you want to avoid accidental modification of placed points (e.g., when you rotate the view you may accidently click on a control point), which must be a common need.

Yes, this is a common need. We’ve had some requests for an undo button to correct these kind of mistakes. Using a landmark template should help with this. If the landmark points are locked when the template is created, they can be placed but not moved in the scene (by default) when the template is imported.

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [July 11, 2023, 5:53am UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/14 "2023-07-11T05:53:15Z")

</div>

> [@smrolfe](#):
>
> g a landmark template should help with thi

how to individually lock control points (python script) when they are created? are they still locked when saving and when opening them with a new application program.

regards,  
saima

---

<div class="post-metadata">

**Author:** ![hherhold](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/hherhold/32/12199_2.png) [@hherhold](https://discourse.slicer.org/u/hherhold)\
**Post date:** [July 11, 2023, 11:18am UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/15 "2023-07-11T11:18:58Z")

</div>

This is how I do it, it is _absolutely_ not the best way, and not even the right way, but it works for my workflow. I have a 5-button programmable mouse, so I’ve set a hotkey/shortcut of `;` to add a markup point and then programmed a mouse button to type that key. You can also just type `;` from the keyboard. Anyway, this shortcut runs a python function that sets the interaction node to placement node, then locks all markups for that node. For whatever reason, it locks all nodes except the one that’s just been placed, but since I place a lot of points in a row, it’s good enough for me.

Locked markups are saved as locked and reloaded as locked. You can look at the JSON file that has the markups and check the “locked” attribute and see that it is set to “on”.

The right way, as described above, is to change the default markup node to be locked. I’ve been unable to get this to work but I haven’t spent enough time debugging it since my _very_ hacky method works for me.

The shortcut function is:

```auto
def hh_place_fiducial():
    try:
        interactionNode = slicer.app.applicationLogic().GetInteractionNode()
        interactionNode.SetCurrentInteractionMode(interactionNode.Place)
        mod = slicer.util.getModule("Markups")
        ml = mod.logic()
        n = slicer.util.getNode(ml.GetActiveListID())
        ml.SetAllMarkupsLocked(n, True)
    except AttributeError:
        pass

```

And to set it as a hotkey/shortcut: (You don’t need the loop below for setting only one, I have a number of shortcuts I’ve defined but edited those out for clarity.)

```auto
shortcuts = [
  (';', lambda: hh_place_fiducial())
]

for (shortcutKey, callback) in shortcuts:
    shortcut = qt.QShortcut(slicer.util.mainWindow())
    shortcut.setKey(qt.QKeySequence(shortcutKey))
    shortcut.connect( 'activated()', callback)

```

(As an aside, this what I have tried for setting the default node to be locked, but it does _not_ work. If anybody’s got ideas on why, any help would be awesome.)

```auto
### THIS DOES NOT WORK
defaultMarkupNode = slicer.vtkMRMLMarkupsFiducialNode() 
defaultMarkupNode.SetLocked(1)
slicer.mrmlScene.AddDefaultNode(defaultMarkupNode)

```

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [July 13, 2023, 5:31am UTC](https://discourse.slicer.org/t/markup-nodes-option-for-locked-unlocked-on-creation/12981/16 "2023-07-13T05:31:34Z")

</div>

Hi,  
Thanks for your reply. I am locking the control points while creating them using the markupnode.SetNthFiducialControlPointLocked(cp\_no, True).

regards,  
Saima
