def create(self): super(PaintEffectOptions, self).create() labelVolume = self.editUtil.getLabelVolume() if labelVolume and labelVolume.GetImageData(): spacing = labelVolume.GetSpacing() dimensions = labelVolume.GetImageData().GetDimensions() self.minimumRadius = 0.5 * min(spacing) bounds = [a * b for a, b in zip(spacing, dimensions)] self.maximumRadius = 0.5 * max(bounds) else: self.minimumRadius = 0.01 self.maximumRadius = 100 self.radiusFrame = qt.QFrame(self.frame) self.radiusFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.radiusFrame) self.widgets.append(self.radiusFrame) self.radiusLabel = qt.QLabel("Radius:", self.radiusFrame) self.radiusLabel.setToolTip( "Set the radius of the paint brush in millimeters") self.radiusFrame.layout().addWidget(self.radiusLabel) self.widgets.append(self.radiusLabel) self.radiusSpinBox = qt.QDoubleSpinBox(self.radiusFrame) self.radiusSpinBox.setToolTip( "Set the radius of the paint brush in millimeters") self.radiusSpinBox.minimum = self.minimumRadius self.radiusSpinBox.maximum = self.maximumRadius self.radiusSpinBox.suffix = "mm" from math import log, floor decimals = floor(log(self.minimumRadius, 10)) if decimals < 0: self.radiusSpinBox.decimals = -decimals + 2 self.radiusFrame.layout().addWidget(self.radiusSpinBox) self.widgets.append(self.radiusSpinBox) self.radiusUnitsToggle = qt.QPushButton("px:") self.radiusUnitsToggle.setToolTip( "Toggle radius quick set buttons between mm and label volume pixel size units" ) self.radiusUnitsToggle.setFixedWidth(35) self.radiusFrame.layout().addWidget(self.radiusUnitsToggle) self.radiusUnitsToggle.connect('clicked()', self.onRadiusUnitsToggle) self.radiusQuickies = {} quickies = ((2, self.onQuickie2Clicked), (3, self.onQuickie3Clicked), (4, self.onQuickie4Clicked), (5, self.onQuickie5Clicked), (10, self.onQuickie10Clicked), (20, self.onQuickie20Clicked)) for rad, callback in quickies: self.radiusQuickies[rad] = qt.QPushButton(str(rad)) self.radiusFrame.layout().addWidget(self.radiusQuickies[rad]) self.radiusQuickies[rad].setFixedWidth(25) self.radiusQuickies[rad].connect('clicked()', callback) self.radiusQuickies[rad].setToolTip( "Set radius based on mm or label voxel size units depending on toggle value" ) self.radius = ctk.ctkDoubleSlider(self.frame) self.radius.minimum = self.minimumRadius self.radius.maximum = self.maximumRadius self.radius.orientation = 1 self.radius.singleStep = self.minimumRadius self.frame.layout().addWidget(self.radius) self.widgets.append(self.radius) self.smudge = qt.QCheckBox("Smudge", self.frame) self.smudge.setToolTip( "Set the label number automatically by sampling the pixel location where the brush stroke starts." ) self.frame.layout().addWidget(self.smudge) self.widgets.append(self.smudge) EditorLib.HelpButton( self.frame, "Use this tool to paint with a round brush of the selected radius") self.connections.append( (self.smudge, 'clicked()', self.updateMRMLFromGUI)) self.connections.append( (self.radius, 'valueChanged(double)', self.onRadiusValueChanged)) self.connections.append((self.radiusSpinBox, 'valueChanged(double)', self.onRadiusSpinBoxChanged)) # Add vertical spacer self.frame.layout().addStretch(1) # set the node parameters that are dependent on the input data self.parameterNode.SetParameter("PaintEffect,radius", str(self.minimumRadius * 10))
def setup(self): """This is called one time when the module GUI is initialized """ # Declare ALL the GUI components (depending on the context we will add different ones to the layout) self.widgetMainFrame = qt.QFrame() self.widgetMainLayout = qt.QGridLayout() self.widgetMainFrame.setLayout(self.widgetMainLayout) self.layout.addWidget(self.widgetMainFrame) ## Context self.contextLabel = qt.QLabel("Context") self.contextComboBox = qt.QComboBox() for context in self.contexts.itervalues(): self.contextComboBox.addItem(context) ## Operation self.operationLabel = qt.QLabel("Optimization") self.operationComboBox = qt.QComboBox() for operation in self.operations.itervalues(): if operation != self.OPERATION_NONE: self.operationComboBox.addItem(operation) ## Plane self.planeLabel = qt.QLabel("Plane") # Buttons group self.planesButtonGroup = qt.QButtonGroup() # Axial self.axialButton = qt.QPushButton() self.axialButton.setCheckable(True) self.axialButton.toolTip = "Axial plane" self.axialButton.setFixedSize(40, 40) self.axialButton.setIcon(SlicerUtil.getIcon("axial.png")) self.planesButtonGroup.addButton(self.axialButton, self.PLANE_AXIAL) # Sagittal self.sagittalButton = qt.QPushButton() self.sagittalButton.setCheckable(True) self.sagittalButton.toolTip = "Sagittal plane" self.sagittalButton.setFixedSize(40, 40) self.sagittalButton.setIcon(SlicerUtil.getIcon("sagittal.png")) self.widgetMainLayout.addWidget(self.sagittalButton, 2, 2, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.planesButtonGroup.addButton(self.sagittalButton, self.PLANE_SAGITTAL) # Coronal self.coronalButton = qt.QPushButton() self.coronalButton.setCheckable(True) self.coronalButton.toolTip = "coronal plane" self.coronalButton.setFixedSize(40, 40) self.coronalButton.setIcon(SlicerUtil.getIcon("coronal.png")) self.planesButtonGroup.addButton(self.coronalButton, self.PLANE_CORONAL) # Null button (to uncheck all) self.nullPlaneButton = qt.QPushButton() self.nullPlaneButton.setCheckable(True) self.planesButtonGroup.addButton(self.nullPlaneButton, -1) # Buttons labels self.axialButtonLabel = qt.QLabel("Axial") self.axialButtonLabel.setStyleSheet("margin-bottom: 10px") self.sagittalButtonLabel = qt.QLabel("Sagittal") self.sagittalButtonLabel.setStyleSheet("margin-bottom: 10px") self.coronalButtonLabel = qt.QLabel("Coronal") self.coronalButtonLabel.setStyleSheet("margin-bottom: 10px") ## Layout self.layoutLabel = qt.QLabel("Layout") # Buttons group self.layoutsButtonGroup = qt.QButtonGroup() # Single slice Button self.singleSlideViewButton = qt.QPushButton() self.singleSlideViewButton.setCheckable(True) self.singleSlideViewButton.toolTip = "Single slice view" self.singleSlideViewButton.setFixedSize(40, 40) self.singleSlideViewButton.setIcon( qt.QIcon(":/Icons/LayoutOneUpRedSliceView.png")) self.layoutsButtonGroup.addButton(self.singleSlideViewButton, self.LAYOUT_RED_ONLY) # Side by side Button self.sideBySideViewButton = qt.QPushButton() self.sideBySideViewButton.setCheckable(True) self.sideBySideViewButton.toolTip = "Side by side view" self.sideBySideViewButton.setFixedSize(40, 40) self.sideBySideViewButton.setIcon( qt.QIcon(":/Icons/LayoutSideBySideView.png")) self.layoutsButtonGroup.addButton(self.sideBySideViewButton, self.LAYOUT_SIDE_BY_SIDE) # Three over three button self.threeOverThreeViewButton = qt.QPushButton() self.threeOverThreeViewButton.setCheckable(True) self.threeOverThreeViewButton.toolTip = "Compare 2 images in their 3 planes" self.threeOverThreeViewButton.setFixedSize(40, 40) self.threeOverThreeViewButton.setIcon( qt.QIcon(":/Icons/LayoutThreeOverThreeView.png")) self.layoutsButtonGroup.addButton(self.threeOverThreeViewButton, self.LAYOUT_THREE_OVER_THREE) # Comparative MIP-MinIP button self.maxMinCompareViewButton = qt.QPushButton() self.maxMinCompareViewButton.setCheckable(True) self.maxMinCompareViewButton.toolTip = "MIP and MinIP comparison" self.maxMinCompareViewButton.setFixedSize(40, 40) self.maxMinCompareViewButton.setIcon( qt.QIcon(":/Icons/LayoutFourUpView.png")) self.layoutsButtonGroup.addButton(self.maxMinCompareViewButton, self.LAYOUT_COMPARE) # Null button (to uncheck all) self.nullLayoutButton = qt.QPushButton() self.nullLayoutButton.setCheckable(True) self.layoutsButtonGroup.addButton(self.nullLayoutButton, -2) # Reset Button self.resetViewButton = qt.QPushButton() self.resetViewButton.toolTip = "Go back to the original layout" self.resetViewButton.setFixedSize(40, 40) # self.resetViewButton.setIconSize(qt.QSize(24, 24)) self.resetViewButton.setIcon( qt.QIcon(os.path.join(SlicerUtil.CIP_ICON_DIR, "Reload.png"))) # Buttons labels self.singleSlideButtonLabel = qt.QLabel("Single") self.sideBySideButtonLabel = qt.QLabel("Side by side") self.threeOverThreeButtonLabel = qt.QLabel("3x3") self.maxMinCompareButtonLabel = qt.QLabel("MIP+MinIP") self.resetLabel = qt.QLabel("Reset") self.resetLabel.setStyleSheet("font-weight: bold") # Number of slices (different for each operation). The size of the slider also changes self.spacingSliderItems = OrderedDict() spacingLabel = qt.QLabel("Slice size " + self.operations[self.OPERATION_MIP]) spacingSlider = qt.QSlider() spacingSlider.orientation = 1 spacingSlider.setTickPosition(2) spacingSlider.minimum = 0 spacingSlider.maximum = 1000 spacingSlider.setPageStep(50) spacingMmLabel = qt.QLabel() self.spacingSliderItems[self.OPERATION_MIP] = (spacingLabel, spacingSlider, spacingMmLabel) self.setCurrentSpacingInMm(self.OPERATION_MIP, 20) spacingLabel = qt.QLabel("Slice size " + self.operations[self.OPERATION_MinIP]) spacingSlider = qt.QSlider() spacingSlider.orientation = 1 spacingSlider.setTickPosition(2) spacingSlider.minimum = 0 spacingSlider.maximum = 200 spacingSlider.setPageStep(50) spacingMmLabel = qt.QLabel() self.spacingSliderItems[self.OPERATION_MinIP] = (spacingLabel, spacingSlider, spacingMmLabel) self.setCurrentSpacingInMm(self.OPERATION_MinIP, 5) spacingLabel = qt.QLabel("Slice size " + self.operations[self.OPERATION_MEAN]) spacingSlider = qt.QSlider() spacingSlider.orientation = 1 spacingSlider.setTickPosition(2) spacingSlider.minimum = 0 spacingSlider.maximum = 200 spacingSlider.setPageStep(50) spacingMmLabel = qt.QLabel() self.spacingSliderItems[self.OPERATION_MEAN] = (spacingLabel, spacingSlider, spacingMmLabel) self.setCurrentSpacingInMm(self.OPERATION_MEAN, 20) # Crosshair self.crosshairCheckbox = qt.QCheckBox() self.crosshairCheckbox.setText("Crosshair cursor") self.crosshairCheckbox.toolTip = "Activate/Desactivate the crosshair cursor for a better visualization" self.crosshairCheckbox.setStyleSheet("margin-top:10px") # Center button self.centerButton = qt.QPushButton() self.centerButton.setText("Center volumes") self.centerButton.setFixedSize(100, 40) self.centerButton.setStyleSheet("margin-top:10px") if self.fullModeOn: ###### FULL MODE # Context self.widgetMainLayout.addWidget(self.contextLabel, 0, 0) self.widgetMainLayout.addWidget(self.contextComboBox, 0, 1, 1, 3) # Operation self.widgetMainLayout.addWidget(self.operationLabel, 1, 0) self.widgetMainLayout.addWidget(self.operationComboBox, 1, 1, 1, 3) # Plane self.widgetMainLayout.addWidget(self.planeLabel, 2, 0) self.widgetMainLayout.addWidget( self.axialButton, 2, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.coronalButton, 2, 3, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.axialButtonLabel, 3, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.sagittalButtonLabel, 3, 2, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.coronalButtonLabel, 3, 3, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) # Layout self.widgetMainLayout.addWidget(self.layoutLabel, 4, 0) self.widgetMainLayout.addWidget( self.singleSlideViewButton, 4, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.sideBySideViewButton, 4, 2, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.threeOverThreeViewButton, 4, 3, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.maxMinCompareViewButton, 4, 4, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.resetViewButton, 4, 5, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.singleSlideButtonLabel, 5, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.sideBySideButtonLabel, 5, 2, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.threeOverThreeButtonLabel, 5, 3, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.maxMinCompareButtonLabel, 5, 4, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.resetLabel, 5, 5, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) # Number of slices row = 6 for structure in self.spacingSliderItems.itervalues(): self.widgetMainLayout.addWidget(structure[0], row, 0, 1, 2) self.widgetMainLayout.addWidget(structure[1], row, 2, 1, 3) self.widgetMainLayout.addWidget(structure[2], row, 5) row += 1 self.widgetMainLayout.addWidget(self.crosshairCheckbox, row, 0, 1, 2) self.crosshairCheckbox.setChecked(True) self.widgetMainLayout.addWidget(self.centerButton, row, 2, 1, 2) else: ##### COLLAPSED MODE # Plane self.widgetMainLayout.addWidget(self.planeLabel, 0, 0) self.widgetMainLayout.addWidget( self.axialButton, 0, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.sagittalButton, 0, 2, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.coronalButton, 0, 3, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.threeOverThreeViewButton, 0, 4, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.axialButtonLabel, 1, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.sagittalButtonLabel, 1, 2, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.coronalButtonLabel, 1, 3, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) self.widgetMainLayout.addWidget( self.threeOverThreeButtonLabel, 1, 4, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER) # Number of slices row = 2 for structure in self.spacingSliderItems.itervalues(): self.widgetMainLayout.addWidget(structure[0], row, 0) self.widgetMainLayout.addWidget(structure[1], row, 1, 1, 3) self.widgetMainLayout.addWidget(structure[2], row, 4) row += 1 self.widgetMainLayout.addWidget(self.crosshairCheckbox, row, 0) self.widgetMainLayout.addWidget(self.centerButton, row, 1, 1, 2) self.layout.addStretch(1) self.__refreshUI__() # Connections self.contextComboBox.connect("currentIndexChanged (int)", self.__onContextIndexChanged__) self.operationComboBox.connect("currentIndexChanged (int)", self.__onOperationIndexChanged__) self.planesButtonGroup.connect("buttonClicked(int)", self.__onPlaneButtonClicked__) self.singleSlideViewButton.connect("clicked()", self.__onSingleSlideButtonClicked__) self.sideBySideViewButton.connect("clicked()", self.__onSideBySideButtonClicked__) self.threeOverThreeViewButton.connect( "clicked()", self.__onThreeOverThreeViewButtonClicked__) self.maxMinCompareViewButton.connect( "clicked()", self.__onMaxMinCompareViewButtonClicked__) self.resetViewButton.connect("clicked()", self.__onResetViewButtonClicked__) for slicer in (item[1] for item in self.spacingSliderItems.itervalues()): slicer.connect('valueChanged(int)', self.__onNumberOfSlicesChanged__) self.crosshairCheckbox.connect("stateChanged(int)", self.__onCrosshairCheckChanged__) self.centerButton.connect("clicked()", self.__onCenterButtonClicked__)
def setup(self): # check if the SlicerVmtk4 module is installed properly #self.__vmtkInstalled = SlicerVmtk4CommonLib.Helper.CheckIfVmtkIsInstalled() #Helper.Debug("VMTK found: " + self.__vmtkInstalled) # # the I/O panel # ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "Input/Output" self.layout.addWidget(ioCollapsibleButton) ioFormLayout = qt.QFormLayout(ioCollapsibleButton) # inputVolume selector self.__inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' self.__inputVolumeNodeSelector.toolTip = "Select the input volume. This should always be the original image and not a vesselness image, if possible." self.__inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__inputVolumeNodeSelector.noneEnabled = False self.__inputVolumeNodeSelector.addEnabled = False self.__inputVolumeNodeSelector.removeEnabled = False self.__inputVolumeNodeSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", "0") ioFormLayout.addRow("Input Volume:", self.__inputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.__inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.__inputVolumeNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged) self.__inputVolumeNodeSelector.connect('nodeActivated(vtkMRMLNode*)', self.onInputVolumeChanged) # seed selector self.__seedFiducialsNodeSelector = slicer.qMRMLNodeComboBox() self.__seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.__seedFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Seeds." self.__seedFiducialsNodeSelector.nodeTypes = [ 'vtkMRMLAnnotationHierarchyNode' ] self.__seedFiducialsNodeSelector.baseName = "Seeds" self.__seedFiducialsNodeSelector.noneEnabled = False self.__seedFiducialsNodeSelector.addEnabled = False self.__seedFiducialsNodeSelector.removeEnabled = False ioFormLayout.addRow("Seeds:", self.__seedFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.__seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.__ioAdvancedToggle = qt.QCheckBox("Show Advanced I/O Properties") self.__ioAdvancedToggle.setChecked(False) ioFormLayout.addRow(self.__ioAdvancedToggle) # # I/O advanced panel # self.__ioAdvancedPanel = qt.QFrame(ioCollapsibleButton) self.__ioAdvancedPanel.hide() self.__ioAdvancedPanel.setFrameStyle(6) ioFormLayout.addRow(self.__ioAdvancedPanel) self.__ioAdvancedToggle.connect("clicked()", self.onIOAdvancedToggle) ioAdvancedFormLayout = qt.QFormLayout(self.__ioAdvancedPanel) # inputVolume selector self.__vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector' self.__vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume. This is optional input." self.__vesselnessVolumeNodeSelector.nodeTypes = [ 'vtkMRMLScalarVolumeNode' ] self.__vesselnessVolumeNodeSelector.noneEnabled = True self.__vesselnessVolumeNodeSelector.addEnabled = False self.__vesselnessVolumeNodeSelector.removeEnabled = False self.__vesselnessVolumeNodeSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", "0") ioAdvancedFormLayout.addRow("Vesselness Volume:", self.__vesselnessVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.__vesselnessVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.__vesselnessVolumeNodeSelector.setCurrentNode(None) # stopper selector self.__stopperFiducialsNodeSelector = slicer.qMRMLNodeComboBox() self.__stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector' self.__stopperFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops." self.__stopperFiducialsNodeSelector.nodeTypes = [ 'vtkMRMLAnnotationHierarchyNode' ] self.__stopperFiducialsNodeSelector.baseName = "Stoppers" self.__stopperFiducialsNodeSelector.noneEnabled = False self.__stopperFiducialsNodeSelector.addEnabled = True self.__stopperFiducialsNodeSelector.removeEnabled = False ioAdvancedFormLayout.addRow("Stoppers:", self.__stopperFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.__stopperFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # outputVolume selector self.__outputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__outputVolumeNodeSelector.toolTip = "Select the output labelmap." self.__outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__outputVolumeNodeSelector.baseName = "LevelSetSegmentation" self.__outputVolumeNodeSelector.noneEnabled = False self.__outputVolumeNodeSelector.addEnabled = True self.__outputVolumeNodeSelector.selectNodeUponCreation = True self.__outputVolumeNodeSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", "1") self.__outputVolumeNodeSelector.removeEnabled = True ioAdvancedFormLayout.addRow("Output Labelmap:", self.__outputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.__outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # outputModel selector self.__outputModelNodeSelector = slicer.qMRMLNodeComboBox() self.__outputModelNodeSelector.objectName = 'outputModelNodeSelector' self.__outputModelNodeSelector.toolTip = "Select the output model." self.__outputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode'] self.__outputModelNodeSelector.baseName = "LevelSetSegmentationModel" self.__outputModelNodeSelector.hideChildNodeTypes = [ 'vtkMRMLAnnotationNode' ] # hide all annotation nodes self.__outputModelNodeSelector.noneEnabled = False self.__outputModelNodeSelector.addEnabled = True self.__outputModelNodeSelector.selectNodeUponCreation = True self.__outputModelNodeSelector.removeEnabled = True ioAdvancedFormLayout.addRow("Output Model:", self.__outputModelNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.__outputModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # # the segmentation panel # segmentationCollapsibleButton = ctk.ctkCollapsibleButton() segmentationCollapsibleButton.text = "Segmentation" self.layout.addWidget(segmentationCollapsibleButton) segmentationFormLayout = qt.QFormLayout(segmentationCollapsibleButton) # Threshold slider thresholdLabel = qt.QLabel() thresholdLabel.text = "Thresholding" + SlicerVmtk4CommonLib.Helper.CreateSpace( 7) thresholdLabel.toolTip = "Choose the intensity range to segment." thresholdLabel.setAlignment(4) segmentationFormLayout.addRow(thresholdLabel) self.__thresholdSlider = slicer.qMRMLRangeWidget() segmentationFormLayout.addRow(self.__thresholdSlider) self.__thresholdSlider.connect('valuesChanged(double,double)', self.onThresholdSliderChanged) self.__segmentationAdvancedToggle = qt.QCheckBox( "Show Advanced Segmentation Properties") self.__segmentationAdvancedToggle.setChecked(False) segmentationFormLayout.addRow(self.__segmentationAdvancedToggle) # # segmentation advanced panel # self.__segmentationAdvancedPanel = qt.QFrame( segmentationCollapsibleButton) self.__segmentationAdvancedPanel.hide() self.__segmentationAdvancedPanel.setFrameStyle(6) segmentationFormLayout.addRow(self.__segmentationAdvancedPanel) self.__segmentationAdvancedToggle.connect( "clicked()", self.onSegmentationAdvancedToggle) segmentationAdvancedFormLayout = qt.QFormLayout( self.__segmentationAdvancedPanel) # inflation slider inflationLabel = qt.QLabel() inflationLabel.text = "less inflation <-> more inflation" + SlicerVmtk4CommonLib.Helper.CreateSpace( 14) inflationLabel.setAlignment(4) inflationLabel.toolTip = "Define how fast the segmentation expands." segmentationAdvancedFormLayout.addRow(inflationLabel) self.__inflationSlider = ctk.ctkSliderWidget() self.__inflationSlider.decimals = 0 self.__inflationSlider.minimum = -100 self.__inflationSlider.maximum = 100 self.__inflationSlider.singleStep = 10 self.__inflationSlider.toolTip = inflationLabel.toolTip segmentationAdvancedFormLayout.addRow(self.__inflationSlider) # curvature slider curvatureLabel = qt.QLabel() curvatureLabel.text = "less curvature <-> more curvature" + SlicerVmtk4CommonLib.Helper.CreateSpace( 14) curvatureLabel.setAlignment(4) curvatureLabel.toolTip = "Choose a high curvature to generate a smooth segmentation." segmentationAdvancedFormLayout.addRow(curvatureLabel) self.__curvatureSlider = ctk.ctkSliderWidget() self.__curvatureSlider.decimals = 0 self.__curvatureSlider.minimum = -100 self.__curvatureSlider.maximum = 100 self.__curvatureSlider.singleStep = 10 self.__curvatureSlider.toolTip = curvatureLabel.toolTip segmentationAdvancedFormLayout.addRow(self.__curvatureSlider) # attraction slider attractionLabel = qt.QLabel() attractionLabel.text = "less attraction to gradient <-> more attraction to gradient" + SlicerVmtk4CommonLib.Helper.CreateSpace( 14) attractionLabel.setAlignment(4) attractionLabel.toolTip = "Configure how the segmentation travels towards gradient ridges (vessel lumen wall)." segmentationAdvancedFormLayout.addRow(attractionLabel) self.__attractionSlider = ctk.ctkSliderWidget() self.__attractionSlider.decimals = 0 self.__attractionSlider.minimum = -100 self.__attractionSlider.maximum = 100 self.__attractionSlider.singleStep = 10 self.__attractionSlider.toolTip = attractionLabel.toolTip segmentationAdvancedFormLayout.addRow(self.__attractionSlider) # iteration spinbox self.__iterationSpinBox = qt.QSpinBox() self.__iterationSpinBox.minimum = 0 self.__iterationSpinBox.maximum = 5000 self.__iterationSpinBox.singleStep = 10 self.__iterationSpinBox.toolTip = "Choose the number of evolution iterations." segmentationAdvancedFormLayout.addRow( SlicerVmtk4CommonLib.Helper.CreateSpace(100) + "Iterations:", self.__iterationSpinBox) # # Reset, preview and apply buttons # self.__buttonBox = qt.QDialogButtonBox() self.__resetButton = self.__buttonBox.addButton( self.__buttonBox.RestoreDefaults) self.__resetButton.toolTip = "Click to reset all input elements to default." self.__previewButton = self.__buttonBox.addButton( self.__buttonBox.Discard) self.__previewButton.setIcon(qt.QIcon()) self.__previewButton.text = "Preview.." self.__previewButton.toolTip = "Click to refresh the preview." self.__startButton = self.__buttonBox.addButton(self.__buttonBox.Apply) self.__startButton.setIcon(qt.QIcon()) self.__startButton.text = "Start!" self.__startButton.enabled = False self.__startButton.toolTip = "Click to start the filtering." self.layout.addWidget(self.__buttonBox) self.__resetButton.connect("clicked()", self.restoreDefaults) self.__previewButton.connect("clicked()", self.onRefreshButtonClicked) self.__startButton.connect("clicked()", self.onStartButtonClicked) # be ready for events self.__updating = 0 # set default values self.restoreDefaults() # compress the layout self.layout.addStretch(1)
def setup(self): # Instantiate and connect widgets ... # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "QuantitativeIndicesTool Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # reload and test button # (use this during development, but remove it when delivering # your module to users) self.reloadAndTestButton = qt.QPushButton("Reload and Test") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) self.reloadAndTestButton.setEnabled(False) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # grayscale volume selector # self.grayscaleSelector = slicer.qMRMLNodeComboBox() self.grayscaleSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.grayscaleSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.grayscaleSelector.selectNodeUponCreation = True self.grayscaleSelector.addEnabled = False self.grayscaleSelector.removeEnabled = False self.grayscaleSelector.noneEnabled = True self.grayscaleSelector.showHidden = False self.grayscaleSelector.showChildNodeTypes = False self.grayscaleSelector.setMRMLScene(slicer.mrmlScene) self.grayscaleSelector.setToolTip("Input grayscale volume.") parametersFormLayout.addRow("Input Volume: ", self.grayscaleSelector) self.grayscaleNode = None # # label map volume selector # self.labelSelector = slicer.qMRMLNodeComboBox() self.labelSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.labelSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 1) self.labelSelector.selectNodeUponCreation = True self.labelSelector.addEnabled = False self.labelSelector.removeEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = False self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Input label map volume.") parametersFormLayout.addRow("Label Map: ", self.labelSelector) self.labelNode = None # # CLI node name and set button # self.parameterFrame = qt.QFrame(self.parent) self.parameterFrame.setLayout(qt.QHBoxLayout()) parametersFormLayout.addRow("Parameter Set: ", self.parameterFrame) self.parameterFrameLabel = qt.QLabel(" (none generated) ", self.parameterFrame) self.parameterFrameLabel.setToolTip( "Nodes for storing parameter flags and output.") self.parameterFrame.layout().addWidget(self.parameterFrameLabel) self.parameterName = qt.QLabel("", self.parameterFrame) self.parameterName.setToolTip( "Nodes for storing parameter flags and output.") self.parameterFrame.layout().addWidget(self.parameterName) self.parameterSetButton = qt.QPushButton("Generate", self.parameterFrame) self.parameterSetButton.setToolTip( "Generate a set of parameter nodes to store with the scene") self.parameterSetButton.setEnabled(False) self.parameterFrame.layout().addWidget(self.parameterSetButton) self.cliNodes = None self.changeVolumesButton = qt.QPushButton("Change Volumes", self.parameterFrame) self.changeVolumesButton.setToolTip( "Change the grayscale volume and/or the label map. Previous calculations from the scene will be deleted." ) self.changeVolumesButton.setEnabled(False) self.parameterFrame.layout().addWidget(self.changeVolumesButton) # # label map value spin box # self.labelValueSelector = qt.QSpinBox() self.labelValueSelector.setEnabled(False) self.labelValueSelector.setMinimum(0) self.labelValueSelector.setValue(1) self.labelValueSelector.setToolTip("Label value to calculate features") parametersFormLayout.addRow("Label Value: ", self.labelValueSelector) self.totalLabels = 0 # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = False self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) #parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip( "Set scale factor for the screen shots.") #parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # # Create large list of quantitative features # self.featuresCollapsibleButton = ctk.ctkCollapsibleButton() self.featuresCollapsibleButton.text = "Features to Calculate" self.layout.addWidget(self.featuresCollapsibleButton) self.featuresFormLayout = qt.QFormLayout( self.featuresCollapsibleButton) self.QIFrame1 = qt.QFrame(self.parent) self.QIFrame1.setLayout(qt.QHBoxLayout()) self.QIFrame1.layout().setSpacing(0) self.QIFrame1.layout().setMargin(0) self.featuresFormLayout.addRow("", self.QIFrame1) self.MeanCheckBox = qt.QCheckBox("Mean", self.QIFrame1) self.QIFrame1.layout().addWidget(self.MeanCheckBox) self.MeanCheckBox.checked = False self.VarianceCheckBox = qt.QCheckBox("Variance", self.QIFrame1) self.QIFrame1.layout().addWidget(self.VarianceCheckBox) self.VarianceCheckBox.checked = False self.MinCheckBox = qt.QCheckBox("Minimum", self.QIFrame1) self.QIFrame1.layout().addWidget(self.MinCheckBox) self.MinCheckBox.checked = False self.MaxCheckBox = qt.QCheckBox("Maximum", self.QIFrame1) self.QIFrame1.layout().addWidget(self.MaxCheckBox) self.MaxCheckBox.checked = False self.QIFrame2 = qt.QFrame(self.parent) self.QIFrame2.setLayout(qt.QHBoxLayout()) self.QIFrame2.layout().setSpacing(0) self.QIFrame2.layout().setMargin(0) self.featuresFormLayout.addRow("", self.QIFrame2) self.Quart1CheckBox = qt.QCheckBox("1st Quartile", self.QIFrame2) self.QIFrame2.layout().addWidget(self.Quart1CheckBox) self.Quart1CheckBox.checked = False self.MedianCheckBox = qt.QCheckBox("Median", self.QIFrame2) self.QIFrame2.layout().addWidget(self.MedianCheckBox) self.MedianCheckBox.checked = False self.Quart3CheckBox = qt.QCheckBox("3rd Quartile", self.QIFrame2) self.QIFrame2.layout().addWidget(self.Quart3CheckBox) self.Quart3CheckBox.checked = False self.UpperAdjacentCheckBox = qt.QCheckBox("Upper Adjacent", self.QIFrame2) self.QIFrame2.layout().addWidget(self.UpperAdjacentCheckBox) self.UpperAdjacentCheckBox.checked = False self.QIFrame3 = qt.QFrame(self.parent) self.QIFrame3.setLayout(qt.QHBoxLayout()) self.QIFrame3.layout().setSpacing(0) self.QIFrame3.layout().setMargin(0) self.featuresFormLayout.addRow("", self.QIFrame3) self.Q1CheckBox = qt.QCheckBox("Q1 Distribution", self.QIFrame3) self.QIFrame3.layout().addWidget(self.Q1CheckBox) self.Q1CheckBox.checked = False self.Q2CheckBox = qt.QCheckBox("Q2 Distribution", self.QIFrame3) self.QIFrame3.layout().addWidget(self.Q2CheckBox) self.Q2CheckBox.checked = False self.Q3CheckBox = qt.QCheckBox("Q3 Distribution", self.QIFrame3) self.QIFrame3.layout().addWidget(self.Q3CheckBox) self.Q3CheckBox.checked = False self.Q4CheckBox = qt.QCheckBox("Q4 Distribution", self.QIFrame3) self.QIFrame3.layout().addWidget(self.Q4CheckBox) self.Q4CheckBox.checked = False self.QIFrame4 = qt.QFrame(self.parent) self.QIFrame4.setLayout(qt.QHBoxLayout()) self.QIFrame4.layout().setSpacing(0) self.QIFrame4.layout().setMargin(0) self.featuresFormLayout.addRow("", self.QIFrame4) self.Gly1CheckBox = qt.QCheckBox("Glycolysis Q1", self.QIFrame4) self.QIFrame4.layout().addWidget(self.Gly1CheckBox) self.Gly1CheckBox.checked = False self.Gly2CheckBox = qt.QCheckBox("Glycolysis Q2", self.QIFrame4) self.QIFrame4.layout().addWidget(self.Gly2CheckBox) self.Gly2CheckBox.checked = False self.Gly3CheckBox = qt.QCheckBox("Glycolysis Q3", self.QIFrame4) self.QIFrame4.layout().addWidget(self.Gly3CheckBox) self.Gly3CheckBox.checked = False self.Gly4CheckBox = qt.QCheckBox("Glycolysis Q4", self.QIFrame4) self.QIFrame4.layout().addWidget(self.Gly4CheckBox) self.Gly4CheckBox.checked = False self.QIFrame5 = qt.QFrame(self.parent) self.QIFrame5.setLayout(qt.QHBoxLayout()) self.QIFrame5.layout().setSpacing(0) self.QIFrame5.layout().setMargin(0) self.featuresFormLayout.addRow("", self.QIFrame5) self.TLGCheckBox = qt.QCheckBox("TLG", self.QIFrame5) self.QIFrame5.layout().addWidget(self.TLGCheckBox) self.TLGCheckBox.checked = False self.SAMCheckBox = qt.QCheckBox("SAM", self.QIFrame5) self.QIFrame5.layout().addWidget(self.SAMCheckBox) self.SAMCheckBox.checked = False self.SAMBGCheckBox = qt.QCheckBox("SAM Background", self.QIFrame5) self.QIFrame5.layout().addWidget(self.SAMBGCheckBox) self.SAMBGCheckBox.checked = False self.RMSCheckBox = qt.QCheckBox("RMS", self.QIFrame5) self.QIFrame5.layout().addWidget(self.RMSCheckBox) self.RMSCheckBox.checked = False self.QIFrame6 = qt.QFrame(self.parent) self.QIFrame6.setLayout(qt.QHBoxLayout()) self.QIFrame6.layout().setSpacing(0) self.QIFrame6.layout().setMargin(0) self.featuresFormLayout.addRow("", self.QIFrame6) self.PeakCheckBox = qt.QCheckBox("Peak", self.QIFrame6) self.QIFrame6.layout().addWidget(self.PeakCheckBox) self.PeakCheckBox.checked = False self.VolumeCheckBox = qt.QCheckBox("Volume", self.QIFrame6) self.QIFrame6.layout().addWidget(self.VolumeCheckBox) self.VolumeCheckBox.checked = False self.selectAllButton = qt.QPushButton("Select All") self.selectAllButton.toolTip = "Select all quantitative features." self.QIFrame6.layout().addWidget(self.selectAllButton) self.deselectAllButton = qt.QPushButton("Deselect All") self.deselectAllButton.toolTip = "Deselect all quantitative features." self.QIFrame6.layout().addWidget(self.deselectAllButton) # # Calculate Button # self.calculateButton = qt.QPushButton("Calculate") self.calculateButton.toolTip = "Calculate quantitative features." self.calculateButton.enabled = False self.featuresFormLayout.addRow(self.calculateButton) # # Results Frame # self.resultsCollapsibleButton = ctk.ctkCollapsibleButton() self.resultsCollapsibleButton.text = "Results" self.layout.addWidget(self.resultsCollapsibleButton) self.resultsFormLayout = qt.QFormLayout(self.resultsCollapsibleButton) self.resultsFrame = qt.QFrame(self.resultsCollapsibleButton) self.resultsFrame.setLayout(qt.QHBoxLayout()) self.resultsFrame.layout().setSpacing(0) self.resultsFrame.layout().setMargin(0) self.resultsFormLayout.addWidget(self.resultsFrame) self.resultsFrameLabel = qt.QLabel('', self.resultsFrame) self.resultsFrame.layout().addWidget(self.resultsFrameLabel) # Add vertical spacer self.layout.addStretch(1) # connections self.calculateButton.connect('clicked(bool)', self.onCalculateButton) self.grayscaleSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onGrayscaleSelect) self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelSelect) self.parameterSetButton.connect('clicked(bool)', self.onParameterSetButton) self.changeVolumesButton.connect('clicked(bool)', self.onChangeVolumesButton) self.labelValueSelector.connect('valueChanged(int)', self.onLabelValueSelect) self.selectAllButton.connect('clicked(bool)', self.onSelectAllButton) self.deselectAllButton.connect('clicked(bool)', self.onDeselectAllButton)
def setup(self): # Instantiate and connect widgets ... # reload button # (use this during development, but remove it when delivering # your module to users) # Collapsible button dummyCollapsibleButton = ctk.ctkCollapsibleButton() dummyCollapsibleButton.text = "Parameters" self.layout.addWidget(dummyCollapsibleButton) # Layout within the dummy collapsible button dummyFormLayout = qt.QFormLayout(dummyCollapsibleButton) #LABEL VOLUME SELECTOR self.labelSelectorFrame = qt.QFrame() self.labelSelectorFrame.setLayout(qt.QHBoxLayout()) dummyFormLayout.addWidget(self.labelSelectorFrame) self.labelSelectorLabel = qt.QLabel() self.labelSelectorLabel.setText("Label Map: ") dummyFormLayout.addWidget(self.labelSelectorLabel) self.labelSelector = slicer.qMRMLNodeComboBox() self.labelSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "") self.labelSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", "1") # todo addAttribute self.labelSelector.selectNodeUponCreation = False self.labelSelector.addEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.removeEnabled = False self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = False self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Pick the label map to edit") dummyFormLayout.addWidget(self.labelSelector) self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelSelect) # the grayscale volume selector # self.grayscaleSelectorFrame = qt.QFrame(self.parent) self.grayscaleSelectorFrame.setLayout(qt.QHBoxLayout()) dummyFormLayout.addWidget(self.grayscaleSelectorFrame) self.grayscaleSelectorLabel = qt.QLabel("Grayscale Volume: ", self.grayscaleSelectorFrame) self.grayscaleSelectorLabel.setToolTip( "Select the grayscale volume (background grayscale scalar volume node) for statistics calculations" ) dummyFormLayout.addWidget(self.grayscaleSelectorLabel) self.grayscaleSelector = slicer.qMRMLNodeComboBox( self.grayscaleSelectorFrame) self.grayscaleSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.grayscaleSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.grayscaleSelector.selectNodeUponCreation = False self.grayscaleSelector.addEnabled = False self.grayscaleSelector.removeEnabled = False self.grayscaleSelector.noneEnabled = True self.grayscaleSelector.showHidden = False self.grayscaleSelector.showChildNodeTypes = False self.grayscaleSelector.setMRMLScene(slicer.mrmlScene) # TODO: need to add a QLabel # self.grayscaleSelector.SetLabelText( "Master Volume:" ) dummyFormLayout.addWidget(self.grayscaleSelector) self.grayscaleSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onGrayscaleSelect) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "diagnosis Reload" self.layout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # Calculate button self.calcButton = qt.QPushButton("Calculates") self.calcButton.toolTip = "Calculates the level of stenosis on the most patological slice" dummyFormLayout.addWidget(self.calcButton) self.calcButton.enabled = False self.calcButton.connect('clicked(bool)', self.onCalcButtonClicked) # Botton temporal para llenar tabla *************************************** self.fillTable = qt.QPushButton("Fill") self.fillTable.toolTip = "Testing" dummyFormLayout.addWidget(self.fillTable) self.fillTable.enabled = True self.fillTable.connect('clicked(bool)', self.onFillButtonClicked) # Add Vertical Spacer self.layout.addStretch(1) # Parametros tabla self.vista = qt.QTableView() self.vista.sortingEnabled = False self.vista.visible = False self.vista.verticalHeader().visible = False self.vista.horizontalHeader().visible = False self.vista.setAlternatingRowColors(True) dummyFormLayout.addWidget(self.vista) # Add vertical spacer self.layout.addStretch(1)