Help Building Slicelet with Segment Editor Functionality

Hi,

I’m working with a group of physicians and graduate students to develop Slicelets as part of a computer vision initiative at my hospital. I’m a long time Slicer user and fan, and am looking for guidance in constructing parts or all of the Segment Editor module within a custom Slicelet.

I’ve been studying the Slicelet Documentation page, and looking for a .py file similar to the Editor.py file to try and build a Slicelet with Segment Editor features within it. But I’m not having any luck finding what seems like the correct files. Does anyone have any suggestions on how to approach this? Perhaps there’s an existing Slicelet that incorporates some or all of the Segment Editor that someone may be willing to share?

Thanks for your help!

Best,

Brett

Segment Editor module serves as an example how you can use the Segment Editor widget in a scripted module by writing only a few ten lines of code. Copy and paste source code of this module in your slicelet and modify as needed.

Sounds very straightforward to implement the Segment Editor widget into a Slicelet.

Is there somewhere specific in Slicer’s source code you recommend I look?

Segment Editor module source code is available here: https://github.com/Slicer/Slicer/blob/master/Modules/Scripted/SegmentEditor/SegmentEditor.py

Awesome! Was able to launch into a Slicelet (along with the impressive additional of features available through your extension). This is really spectacular.

However, one thing I’m missing and struggling to figure out is how to load viewer windows for interacting with images. Currently all I have is the module itself and add data/add scene buttons.

I tried adding the code below as described in Slicelet documentation, but was unsure where to put it. Everywhere I tried (under all the different init methods within my Slicelet and also in the .slicerrc.py that’s launched at on start-up) did not end up launching viewers. Any thoughts on what I might be missing?

Thank you!

mainWidget = qt.QWidget()
mainWidget.objectName = "qSlicerAppMainWindow"
vlayout = qt.QVBoxLayout()
mainWidget.setLayout(vlayout)
layoutWidget = slicer.qMRMLLayoutWidget()
layoutManager = slicer.qSlicerLayoutManager()
layoutManager.setMRMLScene(slicer.mrmlScene)
layoutManager.setScriptedDisplayableManagerDirectory(slicer.app.slicerHome + "/bin/Python/mrmlDisplayableManager")
layoutWidget.setLayoutManager(layoutManager)
slicer.app.setLayoutManager(layoutManager)
layoutWidget.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)
vlayout.addWidget(layoutWidget)

A segment editor Slicelet would be a generally useful tool - @bsmarine maybe you could start a git repository for the project and put your full script there so others could help you debug?

You can gut this slicelet to only include the panel with the layout selector and the viewers, then add the Segment Editor widget into the panel

@cpinter thank you so much for sharing! This code is extensive, easy to follow and a great learning resource on how to add useful Slicelet functionality. Currently going through it with a colleague and will let you know how it works out.

@pieper I just uploaded to a git repo, specifically, the SegmentEditor.py code here.

Struggling to understand how to build viewers and module widgets in the same layout. I’m a novice with computer programming and still trying to wrap my head around how parent and child classes syntax work, which seems essential in building Slicelets.

Specifically, I’m trying to launch a SegmentEditor module within a viewer but may be making many mistakes around line 212 to 229. Any suggestions would be greatly appreciated!

Hi All,

Can anyone provide suggestions or advice on how to get SegmentEditor to work as a Slicelet using the code I have loaded up on github?

Specifically, I think that I’m not calling the viewer layout correctly in the Slicelet class (line 198) before it’s passed to the SegmentEditorSlicelet class (line 244).

/Applications/Slicer.app/Contents/MacOS/Slicer --no-main-window --python-code SegmentEditor.py

Loading Slicer RC file [/Users/brettmarinelli/.slicerrc.py]
Traceback (most recent call last):
File “<string>”, line 1, in <module>
NameError: name ‘SegmentEditor’ is not defined

Any help is greatly appreciated!

There are a couple of small issues:

  • Starting the slicelet: if you want to specify a file name then you need to use --python-script argument. See details here. For example, this worked for me: "c:\Program Files\Slicer 4.9.0-2018-08-25\Slicer.exe" --python-script c:\\D\\SinaiSlicelets\\SegmentEditor.py
  • SegmentEditor module name is already taken by a Slicer core module. Choose a different one.
  • There is a syntax error in your code at line 225. To fix it, replace self.parent.vlayout by self.parent.layout().

Hi Andras, thanks for your guidance on this. I was able to pull into a Slicelet successfully.

Had to put this project down for a bit and am starting it back up. While the SegmentEditor shows up in my Slicelet, it does not seem to recognize any loaded volumes. Is there a way to generally establish connection with SegmentEditor and any present volumeNodes?

I have posted code here on GitHub. Lines 10, 278 and 937 refer to SegmentEditor relevant portions.

Thank you for your help!

Best,

Brett

You create a segment editor widget here but then you would need to call setMRMLScene and setMRMLSegmentEditorNode to be able to use the widget. To make your widget truly and independent widget, do not reuse the same singleton node as Slicer’s built-in segment editor module: change "SegmentEditor" singleton tag to something like "SinaiSegmentEditor".

Hi Andras,

I’ve done as you instructed here and sure enough I can now select new Segmentations and set Master Volume!

But a soon as I hit paint brush or eraser the Slicelet closes :\

I cleaned up the code on git hub. Relevant lines are at 14, 84 and 97. Do you happen to see what I may have done incorrectly?

Unsure if it’s related, but I receive this error message below on start-up now.

QObject::connect: Cannot connect (null)::layoutChanged(int) to qMRMLSegmentEditorWidget::onLayoutChanged(int)

Sorry, but I cannot even figure out what would you expect to happen. Please either use the skeleton generated by Extension Wizard (keep all the folders and files that the wizard generates) or follow working examples more closely. Only put a single .py files in the module’s folder (additional Python files are only allowed in subfolders).

Hi Andras,

The expectation is to have a SegmentEditor within a Slicelet, using example code that Csaba shared earlier in this chain as a skeleton. This is not meant to be an extension.

I have rearranged the folder structure on the repo so that now only a single .py appears, with other .py files in subfolders.

With your help I’ve been able to get the data loading portion of this Slicelet to work, meaning it loads specific files from a desired study folder to specific views with axial orientations.

Next, I would like ideally to have a SegmentEditor but am unsure how to add it as Csaba suggested back on this chain August 13th. I have no formal training in object-oriented programming and apologize if my approaches have been confusing to help troubleshoot.

Is it possible to import the SegmentEditorWidget Class directly to line 131 here? (Btw, I have renamed the singleton tag to “SinaiSegmentEditor” per your suggestion)

Or do I need to include some of the SegmentEditorWidget initialization code directly into the Slicelet initialization code? Apologies if I’m using these terms incorrectly or if it’s confusing.

Thanks for your guidance!

Brett

There are two main approaches to use Slicer with simple user interface: create slicelet scripts or create regular modules that hide unnecessary user interface elements (toolbar, menu, etc.). It is much more difficult to write correct slicelet scripts, so I would recommend you to follow the latter approach.

First of all, complete Slicer programming tutorial. Then:

  • Create a new extension using the Extension Wizard
  • Add a new Python scripted module
  • Replace the new scripted module with a clone of Slicer’s current SegmentEditor module, with renaming the Python filename and all class names inside
  • Test if simple segment editing features work well
  • Add all the custom user interface elements to this module (from your current code snippets)
  • Test if it all works as expected
  • Ask us how to simplify user interface, start the module from command-line, etc.
1 Like

Hi all, I have an update / extension to this question:
@lassoan

The error Brett reported:

QObject::connect: Cannot connect (null)::layoutChanged(int) to qMRMLSegmentEditorWidget::onLayoutChanged(int)

Is due to this line: https://github.com/Slicer/Slicer/blob/3402898aabbd40761bed8198f89ebc8832594662/Modules/Loadable/Segmentations/Widgets/qMRMLSegmentEditorWidget.cxx#L1698

Essentially, the SegmentEditorWidget explicitly links to the main window layout manager, so it cannot function if the main window is hidden.

Is there some we can change this to point the Widget towards a Slicelet layout?