after selecting my desired Segmentation, in the Segment list I can see the list of Segments that are in the Segmentation node, but the Segments Table is empty.
How can I create this connection? It seems like there should be a connection between the qMRMLSegmentSelectorWidget and qMRMLSegmentsTableView.
As shown in the image above, I can now see the table containing the Segments in a Segmentation within a module called SegmentationSelector.
Next, I was able to select one of the Segments from the visible table and retrieve its ID using the selectedSegmentIDs function for further processing. I was able to accomplish this in the 3D Slicer Python Interactor with the following commands.
seg=slicer.qMRMLSegmentSelectorWidget()
seg.setMRMLScene(slicer.mrmlScene)
seg.setToolTip("Pick the input to the algorithm.")
table=slicer.qMRMLSegmentsTableView()
table.setMRMLScene(slicer.mrmlScene)
table.setToolTip("Pick the segments to view.")
table.setSegmentationNode(seg.currentNode())
table.show()
table.selectedSegmentIDs()
Now, I would like to have the same functionality in my module, SegmentationSelector. In other words, as shown in the image below, I want to select one of the segments from the Segments Table. Can you guide me on how to do this?
I saw something similar to what I want in the Segment Comparison module. Perhaps there is no need for qMRMLSegmentsTableView. But how can I be sure that when selecting one of the segments from the Segment Table, that segment is actually selected? I modified my module’s code as follows:
### Start (Segment node selection)
# Create a qMRMLSegmentSelectorWidget for selecting the Segmentation node
self.inputSelector1 = slicer.qMRMLSegmentSelectorWidget()
#self.inputSelector1.nodeTypes = (("vtkSegmentation"), "")
#self.inputSelector1.selectNodeUponCreation = True
#self.inputSelector1.addEnabled = False
#self.inputSelector1.removeEnabled = False
#self.inputSelector1.noneEnabled = False
#self.inputSelector1.showHidden = False
#self.inputSelector1.showChildNodeTypes = False
self.inputSelector1.setMRMLScene(slicer.mrmlScene)
self.inputSelector1.setToolTip("Pick the input to the algorithm.")
parametersFormLayout.addRow("Segmentation: ", self.inputSelector1)
# Print sement selected
self.inputSelector1.selectedSegmentIDs()
print("Segment selected: ", self.inputSelector1.selectedSegmentIDs())
However, as shown in the following figure, the output of the print statement is empty.
I expected the output of the print statement to be PTV1. In other words, when I select a segment from the list, for example PTV1, I want to use its ID for subsequent processing in the next widgets.
Please guide me.
Best regards.
Shahrokh
I must apologize for asking my question again. I tried to select one of the Segments available in a node of the type Segmentation. It is like the Segment Comparison module, but unfortunately, I couldn’t succeed. The code I have written so far includes the following lines:
import os
import unittest
from __main__ import vtk, qt, ctk, slicer
from slicer.ScriptedLoadableModule import *
import logging
#
# SegmentationSelector
#
class SegmentationSelector(ScriptedLoadableModule):
def __init__(self, parent):
ScriptedLoadableModule.__init__(self, parent)
self.parent.title = "SegmentationSelector" # TODO make this more human readable by adding spaces
self.parent.categories = ["Examples"]
self.parent.dependencies = []
self.parent.contributors = ["John Doe (AnyWare Corp.)"] # replace with "Firstname Lastname (Organization)"
#
# SegmentationSelectorWidget
#
class SegmentationSelectorWidget(ScriptedLoadableModuleWidget):
def setup(self):
ScriptedLoadableModuleWidget.setup(self)
# Instantiate and connect widgets ...
#
# Parameters Area
#
parametersCollapsibleButton = ctk.ctkCollapsibleButton()
parametersCollapsibleButton.text = "Parameters"
self.layout.addWidget(parametersCollapsibleButton)
# Layout within the dummy collapsible button
parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)
#
# input volume selector
#
self.inputSelector0 = slicer.qMRMLNodeComboBox()
self.inputSelector0.nodeTypes = ["vtkMRMLScalarVolumeNode"]
self.inputSelector0.selectNodeUponCreation = True
self.inputSelector0.addEnabled = False
self.inputSelector0.removeEnabled = False
self.inputSelector0.noneEnabled = False
self.inputSelector0.showHidden = False
self.inputSelector0.showChildNodeTypes = False
self.inputSelector0.setMRMLScene( slicer.mrmlScene )
self.inputSelector0.setToolTip( "Pick the input to the algorithm." )
parametersFormLayout.addRow("Input Volume: ", self.inputSelector0)
#
# Select Segment node
#
self.inputSelector1 = slicer.qMRMLSegmentSelectorWidget()
self.inputSelector1.setMRMLScene(slicer.mrmlScene)
self.inputSelector1.setToolTip("Pick the input to the algorithm.")
parametersFormLayout.addRow("Segmentation: ", self.inputSelector1)
self.inputSelector1.selectedSegmentIDs()
#
# Apply Button
#
self.applyButton = qt.QPushButton("Apply")
self.applyButton.toolTip = "Run the algorithm."
self.applyButton.enabled = True
parametersFormLayout.addRow(self.applyButton)
# connections
self.applyButton.connect('clicked(bool)', self.onApplyButton)
self.inputSelector1.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
# Refresh Apply button state
self.onSelect()
def cleanup(self):
pass
def onSelect(self):
self.applyButton.enabled = self.inputSelector1.currentNode()
def onApplyButton(self):
logic = SegmentationSelectorLogic()
logic.run(self.inputSelector1.currentNode())
#
# SegmentationSelectorLogic
#
class SegmentationSelectorLogic(ScriptedLoadableModuleLogic):
def run(self, inputVolume):
"""
Run the actual algorithm
"""
print("Segment selected: ", type(inputVolume))
return True
I referred to the Slicer: qMRMLSegmentSelectorWidget Class Reference, but unfortunately, I couldn’t find a method that allows me to connect a segment selected from the combobox of the qMRMLSegmentSelectorWidget to the Apply pushbutton. Also, I couldn’t find the Python code for the Segment Comparison module, which I could use as a base for my code. I also read the PDF file titled Programming tutorial for 3D Slicer, which was very useful, and I was able to implement the code up to this point. If possible, could you guide me on how I can complete this code?
It’s good that you keep working on this and I’m sure you will get it sorted out.
Regarding qMRMLSegmentSelectorWidget, here’s a snippet showing how it’s supposed to work. If it’s not working this way in your module, then experimenting in the python console like this can help.
>>> w = slicer.qMRMLSegmentSelectorWidget()
>>> w.setMRMLScene(slicer.mrmlScene)
>>> w.show()
>>> w.currentNode()
<MRMLCorePython.vtkMRMLSegmentationNode(0x7fb7b2b5c660) at 0x1b0dccb80>
>>>w.currentSegmentID()
'Segment_1_3'
If you run into behavior that doesn’t make sense to you, post small, easy to replicate snippets like this so it’s easy for people to answer without reading through all your code.
Thank you very much for your suggestion. I will follow the suggestion you mentioned and post small, easy-to-replicate snippets like this to make it easier to answer without having to read through all of my code.
Thank you so much for your guidance. I realized that my mistake was in the onSelect function. The return value of this function should be of type vtkMRMLSegmentationNode.
Based on this, the corrected code will be as follows: