# Minimal draw tube effect

**URL:** <https://discourse.slicer.org/t/minimal-draw-tube-effect/32511>\
**Category:** Development\
**Created:** [October 31, 2023, 6:23pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511 "2023-10-31T18:23:29Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [October 31, 2023, 6:23pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/1 "2023-10-31T18:23:29Z")

</div>

Hi

I have a side panel with two widgets laid out vertically: first one is a groupbox to execute simplified segmentation actions by using the second widget, a qMRMLSegmentEditorWidget, that’s hidden.

I have to use the drawTubeEffect from the 2nd widget (only the buttons inside red marks):

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/4/2487721cdd2e42a07c7d33686566863b3ebdede9.jpeg)

I’d like to move the widgets in red to my firstly mentioned widget to keep all connections/logic working.

And I’d like to avoid duplicating the GUI of the segment editor widget inside the first widget to achieve that (but I’ll do it if there is not a simpler way to get it working)

Could you advice? Thanks 🙂

---

<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 31, 2023, 7:47pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/2 "2023-10-31T19:47:04Z")

</div>

Widgets are not guaranteed to work if they are extracted from the widget that is managing them. Developers of all the reusable high-level widgets assume that the internal widgets are only accessed and displayed through the public API that the widgets provides, otherwise they would never know what they can change in their implementation.

I would recommend to add whatever widgets you need to your own module. Code duplication should be minimal, because you only need to add a markup place widget and a push-button. If you find that you need to add more than a couple of lines of code then you can suggest changes to refactor the Draw Tube effect that avoids any need for substantial code duplication.

---

<div class="post-metadata">

**Author:** ![chir.set](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/chir.set/32/66982_2.png) [@chir.set](https://discourse.slicer.org/u/chir.set)\
**Post date:** [October 31, 2023, 8:23pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/3 "2023-10-31T20:23:53Z")

</div>

> [@mau\_igna\_06](#):
>
> move the widgets in red

This concerns the default segment editor widget as a suggestion, yours is hidden, but it is the same widget class.

The ‘place fiducial’ widget may be obtained thus:

```auto
sew = slicer.modules.SegmentEditorWidget.editor
sew.setActiveEffectByName("Draw tube")
dt = sew.activeEffect()
fpt = dt.self().fiducialPlacementToggle

```

On a quick try, it seems to work more or less when reparented:

`fpt.setParent(MyContainerWidget)`

If the segment editor is next shown and the ‘Draw tube’ effect is activated with the mouse, then the scene of the re-parented point placement widget needs to be set again. But yours is private and hidden.

All this may just worth a try, may be it’s too much of an ugly hack as @lassoan advised.

Regards.

---

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [October 31, 2023, 8:59pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/4 "2023-10-31T20:59:37Z")

</div>

Thanks for your answer

---

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [October 31, 2023, 9:06pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/5 "2023-10-31T21:06:19Z")

</div>

> [@lassoan](#):
>
> Code duplication should be minimal, because you only need to add a markup place widget and a push-button.

A problem arise from otherwise straightforward solution:

- cannot access all internal widgets of the above markupsPlaceWidget to disconnect the default established signals and proxy (i.e. connect) them to the effect’s markupsPlaceWidget slots (i.e. both default and draw-tube-logic ones)

Don’t you agree?

---

<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 31, 2023, 9:09pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/6 "2023-10-31T21:09:35Z")

</div>

All the widgets are synchronized via MRML nodes. You should not need to do such low level things like connect/disconnect signals. Let me know if you run into any specific problem.

---

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [October 31, 2023, 9:59pm UTC](https://discourse.slicer.org/t/minimal-draw-tube-effect/32511/7 "2023-10-31T21:59:41Z")

</div>

Right 👌

My example:

```auto
import SampleData
# Load master volume
sampleDataLogic = SampleData.SampleDataLogic()
masterVolumeNode = sampleDataLogic.downloadCTChest()
# Create segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes()
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment("test")

slicer.util.selectModule("SegmentEditor")

segmentEditorWidget = mainWindow().findChildren('qMRMLSegmentEditorWidget')[0]
segmentEditorWidget.setActiveEffectByName('Draw tube')
drawTubeEffect = segmentEditorWidget.activeEffect()
drawTubeEffect.self().logic.radius=15
drawTubeEffect.self().updateModelFromSegmentMarkupNode()

```

Then, I expected just adding points like this would not work, _ **but it does:** _

```auto
drawTubeEffect.self().segmentMarkupNode.AddControlPoint([0,0,0])
drawTubeEffect.self().segmentMarkupNode.AddControlPoint([100,0,0])
drawTubeEffect.self().segmentMarkupNode.AddControlPoint([0,200,0])
drawTubeEffect.self().segmentMarkupNode.AddControlPoint([0,0,-300])
drawTubeEffect.self().segmentMarkupNode.AddControlPoint([0,-400,0])

```

Thanks!
