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.values(): self.contextComboBox.addItem(context) ## Operation self.operationLabel = qt.QLabel("Optimization") self.operationComboBox = qt.QComboBox() for operation in self.operations.values(): 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.values(): 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.values(): 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.values()): slicer.connect('valueChanged(int)', self.__onNumberOfSlicesChanged__) self.crosshairCheckbox.connect("stateChanged(int)", self.__onCrosshairCheckChanged__) self.centerButton.connect("clicked()", self.__onCenterButtonClicked__)
def create(self): super(WatershedFromMarkerEffectOptions,self).create() if not HAVE_SIMPLEITK: self.warningLabel = qt.QLabel() self.warningLabel.text = "WatershedFromMarker is not available because\nSimpleITK is not available in this build" self.widgets.append(self.warningLabel) self.frame.layout().addWidget(self.warningLabel) return labelVolume = self.editUtil.getLabelVolume() if labelVolume and labelVolume.GetImageData(): spacing = labelVolume.GetSpacing() self.minimumSigma = 0.1 * min(spacing) self.maximumSigma = 100 * self.minimumSigma else: self.minimumSigma = 0.1 self.maximumSigma = 10 self.sigmaFrame = qt.QFrame(self.frame) self.sigmaFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.sigmaFrame) self.widgets.append(self.sigmaFrame) tip = "Increasing this value smooths the segmentation and reduces leaks. This is the sigma used for edge detection." self.sigmaLabel = qt.QLabel("Object Scale: ", self.frame) self.sigmaLabel.setToolTip(tip) self.sigmaFrame.layout().addWidget(self.sigmaLabel) self.widgets.append(self.sigmaLabel) self.sigmaSlider = qt.QSlider( qt.Qt.Horizontal, self.frame ) self.sigmaFrame.layout().addWidget(self.sigmaSlider) self.sigmaFrame.setToolTip(tip) self.widgets.append(self.sigmaSlider) self.sigmaSpinBox = qt.QDoubleSpinBox(self.frame) self.sigmaSpinBox.setToolTip(tip) self.sigmaSpinBox.suffix = "mm" self.sigmaFrame.layout().addWidget(self.sigmaSpinBox) self.widgets.append(self.sigmaSpinBox) self.sigmaSpinBox.minimum = self.minimumSigma self.sigmaSlider.minimum = self.minimumSigma self.sigmaSpinBox.maximum = self.maximumSigma self.sigmaSlider.maximum = self.maximumSigma decimals = math.floor(math.log(self.minimumSigma,10)) if decimals < 0: self.sigmaSpinBox.decimals = -decimals + 2 self.apply = qt.QPushButton("Apply", self.frame) self.apply.setToolTip("Apply the extension operation") self.frame.layout().addWidget(self.apply) self.widgets.append(self.apply) helpDoc = \ """Use this effect to apply the watershed from markers segmentation from multiple initial labels. The input to this filter is current labelmap image which is expected to contain multiple labels as initial markss. The marks or labels are grown to fill the image and with edges defining the bondaries between. To segment a single object, mark the object, and then it is suggested to surround the object with a negative label on each axis. The "Object Scale" parameter is use to adjust the smoothness of the output image and prevent leakage. It is used internally for the sigma of the gradient magnitude. """ HelpButton(self.frame, helpDoc) self.sigmaSlider.connect( 'valueChanged(int)', self.sigmaSpinBox.setValue ) self.sigmaSpinBox.connect( 'valueChanged(double)', self.sigmaSlider.setValue ) # if either widget is changed both should change and this should be triggered self.connections.append( ( self.sigmaSpinBox, 'valueChanged(double)', self.onSigmaValueChanged ) ) self.connections.append( (self.apply, 'clicked()', self.onApply) ) # Add vertical spacer self.frame.layout().addStretch(1)
def setup(self): # Instantiate and connect widgets ... # Collapsible button autoCTCollapsibleButton = ctk.ctkCollapsibleButton() autoCTCollapsibleButton.text = "Collapsible button for CT auto-segmentation" self.layout.addWidget(autoCTCollapsibleButton) # Layout within the sample collapsible button autoCTFormLayout = qt.QFormLayout(autoCTCollapsibleButton) #Load CT image button loadCTButton = qt.QPushButton("Load CT image and add ROI annotation") loadCTButton.toolTip = "Click to load CT image and then annotate tumor location" autoCTFormLayout.addWidget(loadCTButton) loadCTButton.connect('clicked(bool)', self.onloadCTButtonClicked) #Number of nodule to operate # loadCTnodulelabel = qt.QInputDialog() # loadCTnodulelabel.toolTip = "The tumor number to segment" # loadCTnodulelabel.getInt(self, "Get integer","Percentage:") # autoCTFormLayout.addWidget(loadCTnodulelabel) # loadCTnodulelabel.connect('clicked(bool)', self.onloadCTnodulelabelButtonClicked) # ####Ajust sigma value for CT########## ######################################### # nodulelabel1 = qt.QLabel() # nodulelabel1.setText("Enter the nodule number to process") # autoCTFormLayout.addWidget(nodulelabel1) # noduleSlider1 = qt.QInputDialog() # noduleSlider1.toolTip = "Slide to change nodule number" # autoCTFormLayout.addWidget(noduleSlider1) ## noduleSlider1.setMinimum(0.0) ## noduleSlider1.setMaximum(20) ## noduleSlider1.setValue(1.0) ## noduleSlider.setTickPosition(qt.QSlider.TicksBelow) ## noduleSlider.setTickInterval(1) # self.noduleSlider1 = noduleSlider1 nodulelabel = qt.QLabel() nodulelabel.setText("Enter the nodule number to segment (1-10)") autoCTFormLayout.addWidget(nodulelabel) noduleSlider = qt.QSlider(qt.Qt.Horizontal) noduleSlider.toolTip = "Slide to change nodule number" noduleSlider.setMinimum(0.0) noduleSlider.setMaximum(20) noduleSlider.setValue(1.0) noduleSlider.setTickPosition(qt.QSlider.TicksBelow) noduleSlider.setTickInterval(1) self.noduleSlider = noduleSlider #label for ticks nodulevalues = qt.QGridLayout() r1 = qt.QLabel("0") r2 = qt.QLabel("2") r3 = qt.QLabel("4") r4 = qt.QLabel("6") r5 = qt.QLabel("8") nodulevalues.addWidget(noduleSlider, 0, 0, 1, 5) nodulevalues.addWidget(r1, 1, 0, 1, 1) nodulevalues.addWidget(r2, 1, 1, 1, 1) nodulevalues.addWidget(r3, 1, 2, 1, 1) nodulevalues.addWidget(r4, 1, 3, 1, 1) nodulevalues.addWidget(r5, 1, 4, 1, 1) #Apply the changes # noduleApplyButton = qt.QPushButton("Apply") # noduleApplyButton.toolTip = "Click to apply new sigma value" # nodulevalues.addWidget(noduleApplyButton, 0,5,2,1) # noduleApplyButton.connect('clicked(bool)', self.changesApplyButtonClicked) autoCTFormLayout.addRow(nodulevalues) # Add vertical spacer self.layout.addStretch(1) #########Button for CT segmentation and 3D generation########## ########################################################### CTSeg3D_tumorButton = qt.QPushButton("CTSeg3D_tumor") CTSeg3D_tumorButton.toolTip = "Click to generate auto segmentation and 3D view of tumor" autoCTFormLayout.addWidget(CTSeg3D_tumorButton) CTSeg3D_tumorButton.connect('clicked(bool)', self.onCTSeg3D_tumorButtonClicked) ####Ajust multipler value for CT (fine tuning)########## ######################################### # CTfinetuneButton = qt.QPushButton("Fine_tuning") # CTfinetuneButton.toolTip = "Fine tuning segmentation for better ROI" # autoCTFormLayout.addWidget(CTfinetuneButton) # CTfinetuneButton.connect('clicked(bool)', self.onCTfinetuneButtonClicked) ############## Button segment out lung ############ CTSeg3D_lungButton = qt.QPushButton("CTSeg3D_lung") CTSeg3D_lungButton.toolTip = "Click to generate auto segmentation and 3D view of lung" autoCTFormLayout.addWidget(CTSeg3D_lungButton) CTSeg3D_lungButton.connect('clicked(bool)', self.onCTSeg3D_lungButtonClicked) self.image_loaded = False
def create(self): super(BinaryWatershedEffectOptions, self).create() if not HAVE_SIMPLEITK: self.warningLabel = qt.QLabel() self.warningLabel.text = "BinaryWatershed is not available because\nSimpleITK is not available in this build" self.widgets.append(self.warningLabel) self.frame.layout().addWidget(self.warningLabel) return self.splitSizeFrame = qt.QFrame(self.frame) self.splitSizeFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.splitSizeFrame) self.widgets.append(self.splitSizeFrame) tip = "Sets the a minimum size for labels which will be split into multiple objects." self.splitSizeLabel = qt.QLabel("Split Size:", self.frame) self.splitSizeLabel.setToolTip(tip) self.splitSizeFrame.layout().addWidget(self.splitSizeLabel) self.widgets.append(self.splitSizeLabel) self.minimumSplitSize = 0 self.maximumSplitSize = 100 self.splitSizeSlider = qt.QSlider(qt.Qt.Horizontal, self.frame) self.splitSizeSlider.setValue(1) self.splitSizeFrame.layout().addWidget(self.splitSizeSlider) self.splitSizeFrame.setToolTip(tip) self.widgets.append(self.splitSizeSlider) self.splitSizeSpinBox = qt.QDoubleSpinBox(self.frame) self.splitSizeSpinBox.setToolTip(tip) self.splitSizeSpinBox.setValue(1) self.splitSizeSpinBox.suffix = "mm" self.splitSizeFrame.layout().addWidget(self.splitSizeSpinBox) self.widgets.append(self.splitSizeSpinBox) self.splitSizeSpinBox.minimum = self.minimumSplitSize self.splitSizeSlider.minimum = self.minimumSplitSize self.splitSizeSpinBox.maximum = self.maximumSplitSize self.splitSizeSlider.maximum = self.maximumSplitSize self.apply = qt.QPushButton("Apply", self.frame) self.apply.setToolTip("Apply the binary watershed operation") self.frame.layout().addWidget(self.apply) self.widgets.append(self.apply) helpDoc = """Split selected label into separate objects based at minimum size the objects.""" HelpButton(self.frame, helpDoc) self.apply.connect('clicked()', self.onApply) self.splitSizeSlider.connect('valueChanged(int)', self.splitSizeSpinBox.setValue) self.splitSizeSpinBox.connect('valueChanged(double)', self.splitSizeSlider.setValue) # if either widget is changed both should change and this should be triggered self.connections.append((self.splitSizeSpinBox, 'valueChanged(double)', self.onSplitSizeValueChanged)) # Add vertical spacer self.frame.layout().addStretch(1)