def __init__(self, SettingsFile): """ Init function. """ #-------------------- # Call parent init. #-------------------- qt.QFrame.__init__(self) #-------------------- # Track all widgets. #-------------------- self.collapsibles = {} self.metadataWidgets = {} self.defaultMetadataEditors = {} self.customMetadataEditors = {} self.buttons = {} self.labels = {} self.collapsibleLayouts = {} self.editCustomButtons = {} self.currItemType = '' self.Events = MokaUtils.Events(self.EVENT_TYPES) #-------------------- # The mainLayout eventually becomes # the layout of the MetadataEditorSet via # the '.setLayout' function #-------------------- self.mainLayout = qt.QVBoxLayout() #-------------------- # The Edit Button group. # # NOTE: A button group is created because # normal qt.QPushButton.connect events do not # send the button 'name' to the even method. A # button group allows you to send the actual # button to the vent method. #-------------------- self.editCustomButtonGroup = qt.QButtonGroup() self.editCustomButtonGroup.connect('buttonClicked(QAbstractButton*)', \ self.editCustomClicked) self.editButtonsVisible = True #-------------------- # Construct the manager #-------------------- self.construct() #-------------------- # Set the default states of the # collapsibles. #-------------------- for key, collapsible in self.collapsibles.items(): collapsible.suspendAnim(True) collapsible.show() collapsible.setChecked(True) collapsible.suspendAnim(False)
def createCheckbox(parent, options, exclusive=False): '''group.buttons()[0].checked -- whether first item checked ''' optionWidgets = [qt.QCheckBox(i) for i in options] group = qt.QButtonGroup(parent) group.setExclusive(exclusive) [group.addButton(i) for i in optionWidgets] [parent.layout().addWidget(i) for i in optionWidgets] return group
def create(self): super(WindowLevelEffectOptions,self).create() #self.thresholdPaint.hide() #self.paintOver.hide() #self.threshold.hide() #self.thresholdLabel.hide() # add the selection whether it should work as regular w/l control, # or as a rectangle self.normalMode = qt.QRadioButton('Normal mode') self.rectangleMode = qt.QRadioButton('Rectangle mode') self.rectangleMode.setChecked(1) label = qt.QLabel('Mode of operation:') self.frame.layout().addWidget(label) self.viewGroup = qt.QButtonGroup() self.viewGroup.addButton(self.normalMode,1) self.viewGroup.addButton(self.rectangleMode,2) self.frame.layout().addWidget(self.normalMode) self.frame.layout().addWidget(self.rectangleMode) self.viewGroup.connect('buttonClicked(int)',self.updateMRMLFromGUI) label = qt.QLabel('Layers affected:') self.bgSelector = qt.QCheckBox('Background') self.fgSelector = qt.QCheckBox('Foreground') self.bgSelector.checked = 1 self.fgSelector.checked = 1 self.frame.layout().addWidget(label) self.frame.layout().addWidget(self.bgSelector) self.frame.layout().addWidget(self.fgSelector) self.bgSelector.connect('stateChanged(int)',self.updateMRMLFromGUI) self.fgSelector.connect('stateChanged(int)',self.updateMRMLFromGUI) EditorLib.HelpButton(self.frame, "Use this tool to change window/level of background/foreground volumes based on the intensity range of the selected rectangle.\n\nNormal mode: use primary mouse button to adjust window level. Depending on the selection, Foreground, Background or both layers are affected.\n\nRectangle mode: Left Click and Drag: sweep out an outline that will draw when the button is released. The outline will define the rectangle for calculating the new window/level settings for the selected layers.\n\n") # step4Layout.addRow(self.normalMode, rectangleMode) # Add vertical spacer self.frame.layout().addStretch(1) # set effect-specific parameters if self.parameterNode.GetParameter('WindowLevelEffect,wlmode') == '': self.parameterNode.SetParameter('WindowLevelEffect,wlmode', 'Rectangle') if self.parameterNode.GetParameter('WindowLevelEffect,changeBg') == '': self.parameterNode.SetParameter('WindowLevelEffect,changeBg','1') if self.parameterNode.GetParameter('WindowLevelEffect,changeFg') == '': self.parameterNode.SetParameter('WindowLevelEffect,changeFg','1') if self.parameterNode.GetParameter('Effect,scope') == '': self.parameterNode.SetParameter('Effect,scope','')
def setupUi( self ): self.loadUi('InitialStep.ui') moduleName = 'Workflow' scriptedModulesPath = eval('slicer.modules.%s.path' % moduleName.lower()) scriptedModulesPath = os.path.dirname(scriptedModulesPath) iconsPath = os.path.join(scriptedModulesPath, 'Widgets', 'Resources', 'Icons') buttonGroup = qt.QButtonGroup(self.get('InitialCollapsibleGroupBox')) logic = slicer.modules.workflow.logic() resourceDir = qt.QDir(logic.GetModuleShareDirectory() + '/Resources') for dir in resourceDir.entryList(resourceDir.Dirs | resourceDir.NoDotAndDotDot): pushButton = qt.QPushButton(self.get('InitialCollapsibleGroupBox')) buttonGroup.addButton(pushButton) pushButton.text = dir.replace('_', ' ') pushButton.setProperty('Path', resourceDir.absolutePath() + '/' + dir) pushButton.checkable = True pushButton.connect('clicked()', self.onPresetSelected) pushButton.setIcon(qt.QIcon(os.path.join(iconsPath, dir))) pushButton.setIconSize(qt.QSize(75, 75)) self.PresetButtons.append(pushButton) self.get('InitialCollapsibleGroupBox').layout().addWidget(pushButton)
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 setupCollapsibleButtonGroup(self): """" Making sure only one collapsible button is open at a time.""" self.collapsibleButtonsGroup = qt.QButtonGroup() self.collapsibleButtonsGroup.addButton(self.valvesCollapsibleButton) self.collapsibleButtonsGroup.addButton(self.fieldsCollapsibleButton) self.collapsibleButtonsGroup.addButton(self.outputCollapsibleButton)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... self.logic = NeedleTrackingLogic(None) self.logic.setWidget(self) #-------------------------------------------------- # For debugging # # Reload and Test area reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) reloadCollapsibleButton.collapsed = True # 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 = "Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # #-------------------------------------------------- self.nCath = 1 # Number of catheters #-------------------------------------------------- # GUI components # # Connection Area # connectionCollapsibleButton = ctk.ctkCollapsibleButton() connectionCollapsibleButton.text = "Connection (OpenIGTLink)" self.layout.addWidget(connectionCollapsibleButton) # Layout within the dummy collapsible button connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton) #-------------------------------------------------- # Connector Selector #-------------------------------------------------- self.igtlConnector1 = NeedleTrackingIGTLConnector("Connector 1") self.igtlConnector1.port = 18944 self.igtlConnector1.buildGUI(connectionFormLayout) #-------------------------------------------------- # Catheter #-------------------------------------------------- catheterCollapsibleButton = ctk.ctkCollapsibleButton() catheterCollapsibleButton.text = "Tracking Node" self.layout.addWidget(catheterCollapsibleButton) catheterFormLayout = qt.QFormLayout(catheterCollapsibleButton) #-------------------------------------------------- # Tracking node selector trackingNodeGroupBox = ctk.ctkCollapsibleGroupBox() trackingNodeGroupBox.title = "Tracking Node" catheterFormLayout.addWidget(trackingNodeGroupBox) trackingNodeFormLayout = qt.QFormLayout(trackingNodeGroupBox) self.trackingDataSelector = slicer.qMRMLNodeComboBox() self.trackingDataSelector.nodeTypes = (( "vtkMRMLIGTLTrackingDataBundleNode"), "") self.trackingDataSelector.selectNodeUponCreation = True self.trackingDataSelector.addEnabled = True self.trackingDataSelector.removeEnabled = False self.trackingDataSelector.noneEnabled = False self.trackingDataSelector.showHidden = True self.trackingDataSelector.showChildNodeTypes = False self.trackingDataSelector.setMRMLScene(slicer.mrmlScene) self.trackingDataSelector.setToolTip("Incoming tracking data") trackingNodeFormLayout.addRow("TrackingData: ", self.trackingDataSelector) # # check box to trigger transform conversion # self.activeTrackingCheckBox = qt.QCheckBox() self.activeTrackingCheckBox.checked = 0 self.activeTrackingCheckBox.enabled = 1 self.activeTrackingCheckBox.setToolTip("Activate Tracking") trackingNodeFormLayout.addRow("Active: ", self.activeTrackingCheckBox) #-------------------------------------------------- # Catheter Configuration configGroupBox = ctk.ctkCollapsibleGroupBox() configGroupBox.title = "Catheter Configuration" configGroupBox.collapsed = True catheterFormLayout.addWidget(configGroupBox) configFormLayout = qt.QFormLayout(configGroupBox) self.tipLengthSliderWidget = [None] * self.nCath self.catheterDiameterSliderWidget = [None] * self.nCath self.catheterOpacitySliderWidget = [None] * self.nCath for cath in range(self.nCath): # # Tip Length (legnth between the catheter tip and the first coil) # self.tipLengthSliderWidget[cath] = ctk.ctkSliderWidget() self.tipLengthSliderWidget[cath].singleStep = 0.5 self.tipLengthSliderWidget[cath].minimum = 0.0 self.tipLengthSliderWidget[cath].maximum = 100.0 self.tipLengthSliderWidget[cath].value = 10.0 self.tipLengthSliderWidget[cath].setToolTip( "Set the length of the catheter tip.") configFormLayout.addRow("Cath %d Tip Length (mm): " % cath, self.tipLengthSliderWidget[cath]) # # Catheter #1 Catheter diameter # self.catheterDiameterSliderWidget[cath] = ctk.ctkSliderWidget() self.catheterDiameterSliderWidget[cath].singleStep = 0.1 self.catheterDiameterSliderWidget[cath].minimum = 0.1 self.catheterDiameterSliderWidget[cath].maximum = 10.0 self.catheterDiameterSliderWidget[cath].value = 1.0 self.catheterDiameterSliderWidget[cath].setToolTip( "Set the diameter of the catheter") configFormLayout.addRow("Cath %d Diameter (mm): " % cath, self.catheterDiameterSliderWidget[cath]) # # Catheter #1 Catheter opacity # self.catheterOpacitySliderWidget[cath] = ctk.ctkSliderWidget() self.catheterOpacitySliderWidget[cath].singleStep = 0.1 self.catheterOpacitySliderWidget[cath].minimum = 0.0 self.catheterOpacitySliderWidget[cath].maximum = 1.0 self.catheterOpacitySliderWidget[cath].value = 1.0 self.catheterOpacitySliderWidget[cath].setToolTip( "Set the opacity of the catheter") configFormLayout.addRow("Cath %d Opacity: " % cath, self.catheterOpacitySliderWidget[cath]) # # Check box to show/hide coil labels # self.showCoilLabelCheckBox = qt.QCheckBox() self.showCoilLabelCheckBox.checked = 0 self.showCoilLabelCheckBox.setToolTip("Show/hide coil labels") configFormLayout.addRow("Show Coil Labels: ", self.showCoilLabelCheckBox) #-------------------------------------------------- # Coordinate System # coordinateGroupBox = ctk.ctkCollapsibleGroupBox() coordinateGroupBox.title = "Coordinate System" coordinateGroupBox.collapsed = True catheterFormLayout.addWidget(coordinateGroupBox) coordinateLayout = qt.QFormLayout(coordinateGroupBox) self.coordinateRPlusRadioButton = qt.QRadioButton("+X") self.coordinateRMinusRadioButton = qt.QRadioButton("-X") self.coordinateRPlusRadioButton.checked = 1 self.coordinateRBoxLayout = qt.QHBoxLayout() self.coordinateRBoxLayout.addWidget(self.coordinateRPlusRadioButton) self.coordinateRBoxLayout.addWidget(self.coordinateRMinusRadioButton) self.coordinateRGroup = qt.QButtonGroup() self.coordinateRGroup.addButton(self.coordinateRPlusRadioButton) self.coordinateRGroup.addButton(self.coordinateRMinusRadioButton) coordinateLayout.addRow("Right:", self.coordinateRBoxLayout) self.coordinateAPlusRadioButton = qt.QRadioButton("+Y") self.coordinateAMinusRadioButton = qt.QRadioButton("-Y") self.coordinateAPlusRadioButton.checked = 1 self.coordinateABoxLayout = qt.QHBoxLayout() self.coordinateABoxLayout.addWidget(self.coordinateAPlusRadioButton) self.coordinateABoxLayout.addWidget(self.coordinateAMinusRadioButton) self.coordinateAGroup = qt.QButtonGroup() self.coordinateAGroup.addButton(self.coordinateAPlusRadioButton) self.coordinateAGroup.addButton(self.coordinateAMinusRadioButton) coordinateLayout.addRow("Anterior:", self.coordinateABoxLayout) self.coordinateSPlusRadioButton = qt.QRadioButton("+Z") self.coordinateSMinusRadioButton = qt.QRadioButton("-Z") self.coordinateSPlusRadioButton.checked = 1 self.coordinateSBoxLayout = qt.QHBoxLayout() self.coordinateSBoxLayout.addWidget(self.coordinateSPlusRadioButton) self.coordinateSBoxLayout.addWidget(self.coordinateSMinusRadioButton) self.coordinateSGroup = qt.QButtonGroup() self.coordinateSGroup.addButton(self.coordinateSPlusRadioButton) self.coordinateSGroup.addButton(self.coordinateSMinusRadioButton) coordinateLayout.addRow("Superior:", self.coordinateSBoxLayout) #-------------------------------------------------- # Reslice # resliceCollapsibleButton = ctk.ctkCollapsibleButton() resliceCollapsibleButton.text = "Image Reslice" self.layout.addWidget(resliceCollapsibleButton) #resliceLayout = qt.QFormLayout(resliceCollapsibleButton) self.reslice = NeedleTrackingReslice("Image Reslice") self.reslice.nCath = self.nCath self.reslice.buildGUI(resliceCollapsibleButton) #-------------------------------------------------- # Connections #-------------------------------------------------- self.trackingDataSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onTrackingDataSelected) self.activeTrackingCheckBox.connect('toggled(bool)', self.onActiveTracking) for cath in range(self.nCath): self.tipLengthSliderWidget[cath].connect( "valueChanged(double)", functools.partial(self.onTipLengthChanged, cath)) self.catheterDiameterSliderWidget[cath].connect( "valueChanged(double)", functools.partial(self.onCatheterDiameterChanged, cath)) self.catheterOpacitySliderWidget[cath].connect( "valueChanged(double)", functools.partial(self.onCatheterOpacityChanged, cath)) self.showCoilLabelCheckBox.connect('toggled(bool)', self.onCoilLabelChecked) self.coordinateRPlusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateRMinusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateAPlusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateAMinusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateSPlusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateSMinusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) # Add vertical spacer self.layout.addStretch(1)
def setup(self): """Init the widget """ self.modulePath = SlicerUtil.getModuleFolder("CIP_GetImage") self.resourcesPath = os.path.join(self.modulePath, "CIP_GetImage_Resources") self.StudyId = "" self.logic = CIP_GetImageLogic(self.modulePath) # Widget to load cases faster self.loadSaveDatabuttonsWidget = CIPUI.LoadSaveDataWidget( parentWidget=self.parent) self.loadSaveDatabuttonsWidget.setup(moduleName="CIP_GetImage") # # Obligatory parameters area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Image data" self.layout.addWidget(parametersCollapsibleButton) parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # Study radio buttons label = qt.QLabel() label.text = "Select the study:" parametersFormLayout.addRow(label) self.rbgStudy = qt.QButtonGroup() for key in self.studyIds: rbStudyid = qt.QRadioButton(key) self.rbgStudy.addButton(rbStudyid) parametersFormLayout.addWidget(rbStudyid) self.txtOtherStudy = qt.QLineEdit() self.txtOtherStudy.hide() parametersFormLayout.addWidget(self.txtOtherStudy) # Case id self.txtCaseId = qt.QLineEdit() parametersFormLayout.addRow("Case ID ", self.txtCaseId) # Image types label = qt.QLabel() label.text = "Select the images that you want to load:" parametersFormLayout.addRow(label) self.cbsImageTypes = [] for key in self.imageTypes: check = qt.QCheckBox() check.checked = True check.setText(key) parametersFormLayout.addWidget(check) self.cbsImageTypes.append(check) # Label maps label = qt.QLabel() label.text = "Select the label maps that you want to load:" parametersFormLayout.addRow(label) # Labelmap types checkboxes self.cbsLabelMapTypes = [] for key in self.labelMapTypes: check = qt.QCheckBox() check.setText(key) check.checked = self.labelMapTypes[key][0] parametersFormLayout.addWidget(check) self.cbsLabelMapTypes.append(check) # Load image Button self.downloadButton = qt.QPushButton("Download") self.downloadButton.toolTip = "Load the image" #self.downloadButton.enabled = False self.downloadButton.setStyleSheet( "background-color: green; font-weight:bold; color:white") parametersFormLayout.addRow(self.downloadButton) self.downloadButton.connect('clicked (bool)', self.onDownloadButton) # Information message self.lblDownloading = qt.QLabel() self.lblDownloading.text = "Downloading images. Please wait..." self.lblDownloading.hide() parametersFormLayout.addRow(self.lblDownloading) # # Optional Parameters # optionalParametersCollapsibleButton = ctk.ctkCollapsibleButton() optionalParametersCollapsibleButton.text = "Optional parameters" self.layout.addWidget(optionalParametersCollapsibleButton) optionalParametersFormLayout = qt.QFormLayout( optionalParametersCollapsibleButton) # Local storage (Slicer temporary path) self.localStoragePath = "{0}/CIP".format(slicer.app.temporaryPath) if not os.path.exists(self.localStoragePath): os.makedirs(self.localStoragePath) # Make sure that everybody has write permissions (sometimes there are problems because of umask) os.chmod(self.localStoragePath, 0o777) self.storagePathButton = ctk.ctkDirectoryButton() self.storagePathButton.directory = self.localStoragePath optionalParametersFormLayout.addRow("Local directory: ", self.storagePathButton) # Connection type (SSH, "normal") label = qt.QLabel() label.text = "Connection type:" optionalParametersFormLayout.addRow(label) self.rbgConnectionType = qt.QButtonGroup() self.rbSSH = qt.QRadioButton("SSH (secure connection)") self.rbSSH.setChecked(True) self.rbgConnectionType.addButton(self.rbSSH) optionalParametersFormLayout.addWidget(self.rbSSH) self.rbCP = qt.QRadioButton("Common") self.rbgConnectionType.addButton(self.rbCP) optionalParametersFormLayout.addWidget(self.rbCP) # SSH Server login self.txtServer = qt.QLineEdit() s = SlicerUtil.settingGetOrSetDefault( "CIP_GetImage", "server", "This is your ssh user and server. Example: [email protected]") self.txtServer.text = s # This is your ssh user and server. Example: [email protected]" optionalParametersFormLayout.addRow("Server:", self.txtServer) # Server root path self.txtServerpath = qt.QLineEdit() s = SlicerUtil.settingGetOrSetDefault( "CIP_GetImage", "serverRootPath", "This is your root path to search for files. Ex: /Cases/Processed") self.txtServerpath.text = s # This is your root path to search for files. Ex: /Cases/Processed optionalParametersFormLayout.addRow("Server root path:", self.txtServerpath) # SSH Private key self.txtPrivateKeySSH = qt.QLineEdit() s = SlicerUtil.settingGetOrSetDefault("CIP_GetImage", "sshKey", "") self.txtPrivateKeySSH.text = s # this is the full path to your ssh key if you need it. Be aware of Unix/Windows comaptibility (hint: use os.path.join) # Please notice that you won't need a SSH key if your computer already has one locally installed" optionalParametersFormLayout.addRow( "SSH private key (leave blank for computer's default): ", self.txtPrivateKeySSH) # Cache mode self.cbCacheMode = qt.QCheckBox("Cache mode activated") self.cbCacheMode.setChecked(True) # Cache mode is activated by default optionalParametersFormLayout.addRow("", self.cbCacheMode) # Clean cache Button self.cleanCacheButton = qt.QPushButton("Clean cache") self.cleanCacheButton.toolTip = "Remove all the local cached files" optionalParametersFormLayout.addRow(self.cleanCacheButton) optionalParametersCollapsibleButton.collapsed = True if SlicerUtil.IsDevelopment: # reload button self.reloadButton = qt.QPushButton("Reload (just development)") self.reloadButton.toolTip = "Reload this module (for development purposes)." self.reloadButton.name = "Reload" self.layout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # Add vertical spacer self.layout.addStretch(1) # Connections self.rbgStudy.connect("buttonClicked (QAbstractButton*)", self.onRbStudyClicked) self.txtOtherStudy.connect("textEdited (QString)", self.onTxtOtherStudyEdited) self.rbgConnectionType.connect("buttonClicked (QAbstractButton*)", self.onRbgConnectionType) self.storagePathButton.connect("directorySelected(QString)", self.onTmpDirChanged) self.cleanCacheButton.connect('clicked (bool)', self.onCleanCacheButtonClicked)
def setup(self): # Tags are used to manage event ovservers self.tagSourceNode = None self.tagDestinationNode = None #Set up area for creating curves createCurveBttn = ctk.ctkCollapsibleButton() createCurveBttn.text = "Create Curve" self.layout.addWidget(createCurveBttn) layout = qt.QFormLayout(createCurveBttn) #Selecting source points from fiducials self.SourceSelector = slicer.qMRMLNodeComboBox() self.SourceSelector.nodeTypes = (("vtkMRMLMarkupsFiducialNode"), "") self.SourceSelector.addEnabled = True self.SourceSelector.removeEnabled = True self.SourceSelector.noneEnabled = True self.SourceSelector.renameEnabled = True self.SourceSelector.setMRMLScene(slicer.mrmlScene) self.SourceSelector.setToolTip( "Select source of points or create a new list") layout.addRow("Source points: ", self.SourceSelector) #Selecting destination for new curve self.DestinationSelector = slicer.qMRMLNodeComboBox() self.DestinationSelector.nodeTypes = (("vtkMRMLModelNode"), "") self.DestinationSelector.addEnabled = True self.DestinationSelector.removeEnabled = True self.DestinationSelector.noneEnabled = True self.DestinationSelector.renameEnabled = True self.DestinationSelector.selectNodeUponCreation = True self.DestinationSelector.setMRMLScene(slicer.mrmlScene) self.DestinationSelector.setToolTip( "Select existing curve model or create a new one") layout.addRow("Curve model: ", self.DestinationSelector) #x, y, z inputs for new fiducial self.validator = qt.QDoubleValidator() self.AddFiducialLayout = qt.QHBoxLayout() self.AddX = qt.QLineEdit("X") self.AddX.setValidator(self.validator) self.AddY = qt.QLineEdit("Y") self.AddY.setValidator(self.validator) self.AddZ = qt.QLineEdit("Z") self.AddZ.setValidator(self.validator) self.AddFiducialLayout.addWidget(self.AddX) self.AddFiducialLayout.addWidget(self.AddY) self.AddFiducialLayout.addWidget(self.AddZ) layout.addRow("X, Y, Z coordinates for new fiducial: ", self.AddFiducialLayout) #Add fiducial button self.AddFiducialButton = qt.QPushButton("Add Fiducial") self.AddFiducialButton.toolTip = "Adds fiducial using given x, y, z coordinates" self.AddFiducialButton.enabled = True layout.addRow("", self.AddFiducialButton) #Current fiducials table self.FiducialTable = qt.QTableWidget(1, 4) self.FiducialTableHeaders = ["Name", "X (mm)", "Y (mm)", "Z (mm)"] self.FiducialTable.setHorizontalHeaderLabels(self.FiducialTableHeaders) layout.addWidget(self.FiducialTable) #Radius of curve self.RadiusSliderWidget = ctk.ctkSliderWidget() self.RadiusSliderWidget.singleStep = 0.5 self.RadiusSliderWidget.minimum = 0.5 self.RadiusSliderWidget.maximum = 20.0 self.RadiusSliderWidget.value = 3.0 self.RadiusSliderWidget.setToolTip( "Determines the thickness of the curve") layout.addRow("Thickness: ", self.RadiusSliderWidget) #Select the method of interpolation self.InterpolationLayout = qt.QHBoxLayout() self.InterpolationLinear = qt.QRadioButton("Linear") self.InterpolationLinear.setToolTip( "Straight lines from point to point") self.InterpolationSpline = qt.QRadioButton("Spline") self.InterpolationSpline.setToolTip( "Cardinal spline will create curvature between points") self.InterpolationLayout.addWidget(self.InterpolationLinear) self.InterpolationLayout.addWidget(self.InterpolationSpline) self.InterpolationGroup = qt.QButtonGroup() self.InterpolationGroup.addButton(self.InterpolationLinear) self.InterpolationGroup.addButton(self.InterpolationSpline) layout.addRow("Interpolation: ", self.InterpolationLayout) #Button for generating specified curve self.GenerateButton = qt.QPushButton("Generate/Update Curve") self.GenerateButton.toolTip = "Creates or updates curve specified" self.GenerateButton.enabled = True layout.addRow("", self.GenerateButton) #Linking buttons to methods self.InterpolationLinear.connect('clicked(bool)', self.onSelectInterpolationLinear) self.InterpolationSpline.connect('clicked(bool)', self.onSelectInterpolationSpline) self.SourceSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSourceSelected) self.DestinationSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onDestinationSelected) self.AddX.textChanged.connect( lambda inputSelection: self.checkInputState('x')) self.AddX.textChanged.emit(self.AddX.text) self.AddY.textChanged.connect( lambda inputSelection: self.checkInputState('y')) self.AddY.textChanged.emit(self.AddY.text) self.AddZ.textChanged.connect( lambda inputSelection: self.checkInputState('z')) self.AddZ.textChanged.emit(self.AddZ.text) self.AddFiducialButton.connect('clicked(bool)', self.addFiducial) self.RadiusSliderWidget.connect("valueChanged(double)", self.onThicknessUpdated) self.GenerateButton.connect('clicked(bool)', self.generateCurve) #Default checkboxes self.InterpolationSpline.setChecked(True) self.onSelectInterpolationSpline(True) self.layout.addStretch(1)
def setup(self): # intialize variables # Data of current loaded patient self.IDcurrPatient = {} self.imageNodes = {} # List of currently loaded image nodes self.labelNodes = {} # List of currently loaded label nodes self.ModelNodes = {} # Data of database self.mainPatientdir = self.outputDir = self.datafile = {} #--------------------------------------------------------- # 2D Slice Snapshots self.IMGSliceExtractCollapsibleButton = ctk.ctkCollapsibleButton() self.IMGSliceExtractCollapsibleButton.text = "2D Slice and Model Image Capture" self.layout.addWidget(self.IMGSliceExtractCollapsibleButton) self.IMGSliceExtractCollapsibleButton.collapsed = False self.IMGSliceExtractFormLayout = qt.QFormLayout( self.IMGSliceExtractCollapsibleButton) # Input 1: Input Directory selector self.input6Frame = qt.QFrame(self.IMGSliceExtractCollapsibleButton) self.input6Frame.setLayout(qt.QHBoxLayout()) self.IMGSliceExtractFormLayout.addWidget(self.input6Frame) self.input6Selector = qt.QLabel("Input Directory (DICOM): ", self.input6Frame) self.input6Frame.layout().addWidget(self.input6Selector) self.input6Button = qt.QPushButton("Select main directory DICOM files") self.input6Button.toolTip = "Select main directory with DICOM files (folder names are patient names)" self.input6Button.enabled = True self.input6Frame.layout().addWidget(self.input6Button) # Input 2: Output Directory selector self.input7Frame = qt.QFrame(self.IMGSliceExtractCollapsibleButton) self.input7Frame.setLayout(qt.QHBoxLayout()) self.IMGSliceExtractFormLayout.addWidget(self.input7Frame) self.input7Selector = qt.QLabel("Output Directory: ", self.input7Frame) self.input7Frame.layout().addWidget(self.input7Selector) self.input7Button = qt.QPushButton( "Select main directory output NRRD or NFITI files") self.input7Button.toolTip = "Select main directory for output NRRD or NIFTI files (folder names are patient names)" self.input7Button.enabled = True self.input7Frame.layout().addWidget(self.input7Button) # Keywords Collapsible Button self.KeywordsCollapsibleButton = ctk.ctkCollapsibleButton( self.IMGSliceExtractCollapsibleButton) self.KeywordsCollapsibleButton.text = "Keyword Matching" self.KeywordsCollapsibleButtonLayout = qt.QHBoxLayout() self.KeywordsCollapsibleButton.setLayout( self.KeywordsCollapsibleButtonLayout) self.IMGSliceExtractFormLayout.addWidget( self.KeywordsCollapsibleButton) self.KeywordsCollapsibleButton.collapsed = False self.keywordsFrame = qt.QFrame(self.KeywordsCollapsibleButton) self.keywordsFrame.setLayout(qt.QFormLayout()) self.KeywordsCollapsibleButtonLayout.addWidget(self.keywordsFrame) # Radio Buttons Frame self.radioButtonFrame = qt.QFrame(self.keywordsFrame) self.radioButtonFrame.setLayout(qt.QFormLayout()) self.fileFormatGroup = qt.QButtonGroup(self.radioButtonFrame) self.nrrdButton = qt.QRadioButton("NRRD") self.nrrdButton.checked = True self.niftiButton = qt.QRadioButton("NIFTI") self.fileFormatGroup.addButton(self.nrrdButton) self.fileFormatGroup.addButton(self.niftiButton) self.radioButtonFrame.layout().addRow(self.nrrdButton, self.niftiButton) self.keywordsHeader = qt.QLabel("Keyword Matching:", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.keywordsHeader) # Keywords Frame self.inputMaskHeader = qt.QLabel("Input Image File Type:", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputMaskHeader, self.radioButtonFrame) self.inputImageKeywords = qt.QLabel("Input Image Keywords:", self.keywordsFrame) self.inputImageKeywordsField = qt.QLineEdit("", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputImageKeywords, self.inputImageKeywordsField) self.inputImageExclusionKeywords = qt.QLabel( "Input Image Exclusion Keywords:", self.keywordsFrame) self.inputImageExclusionKeywordsField = qt.QLineEdit( "", self.keywordsFrame) self.keywordsFrame.layout().addRow( self.inputImageExclusionKeywords, self.inputImageExclusionKeywordsField) self.inputLabelKeywords = qt.QLabel("Input Label Keywords:", self.keywordsFrame) self.inputLabelKeywordsField = qt.QLineEdit("", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputLabelKeywords, self.inputLabelKeywordsField) self.inputLabelExclusionKeywords = qt.QLabel( "Input Label Exclusion Keywords:", self.keywordsFrame) self.inputLabelExclusionKeywordsField = qt.QLineEdit( "", self.keywordsFrame) self.keywordsFrame.layout().addRow( self.inputLabelExclusionKeywords, self.inputLabelExclusionKeywordsField) # IMG Slice Extract Button self.IMGSliceExtractButton = qt.QPushButton("Extract Images") self.IMGSliceExtractFormLayout.addWidget(self.IMGSliceExtractButton) #--------------------------------------------------------- # Connections self.input6Button.connect('clicked(bool)', self.onInput6Button) self.input7Button.connect('clicked(bool)', self.onInput7Button) self.IMGSliceExtractButton.connect('clicked(bool)', self.onIMGSliceExtract)
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) # # fixed image selector # self.fixedImageSelector = slicer.qMRMLNodeComboBox() self.fixedImageSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.fixedImageSelector.selectNodeUponCreation = True self.fixedImageSelector.addEnabled = False self.fixedImageSelector.removeEnabled = False self.fixedImageSelector.noneEnabled = True self.fixedImageSelector.showHidden = False self.fixedImageSelector.showChildNodeTypes = False self.fixedImageSelector.setMRMLScene(slicer.mrmlScene) self.fixedImageSelector.setToolTip("Fixed image (optional)") parametersFormLayout.addRow("Fixed Image: ", self.fixedImageSelector) # # fixed image label selector # self.fixedImageLabelSelector = slicer.qMRMLNodeComboBox() self.fixedImageLabelSelector.nodeTypes = (( "vtkMRMLLabelMapVolumeNode"), "") self.fixedImageLabelSelector.selectNodeUponCreation = True self.fixedImageLabelSelector.addEnabled = False self.fixedImageLabelSelector.removeEnabled = False self.fixedImageLabelSelector.noneEnabled = False self.fixedImageLabelSelector.showHidden = False self.fixedImageLabelSelector.showChildNodeTypes = False self.fixedImageLabelSelector.setMRMLScene(slicer.mrmlScene) self.fixedImageLabelSelector.setToolTip( "Segmentation of the fixed image") parametersFormLayout.addRow("Segmentation of the fixed Image: ", self.fixedImageLabelSelector) # # moving image selector # self.movingImageSelector = slicer.qMRMLNodeComboBox() self.movingImageSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.movingImageSelector.selectNodeUponCreation = True self.movingImageSelector.addEnabled = False self.movingImageSelector.removeEnabled = False self.movingImageSelector.noneEnabled = True self.movingImageSelector.showHidden = False self.movingImageSelector.showChildNodeTypes = False self.movingImageSelector.setMRMLScene(slicer.mrmlScene) self.movingImageSelector.setToolTip("Moving image (optional)") parametersFormLayout.addRow("Moving Image: ", self.movingImageSelector) # # moving image label selector # self.movingImageLabelSelector = slicer.qMRMLNodeComboBox() self.movingImageLabelSelector.nodeTypes = (( "vtkMRMLLabelMapVolumeNode"), "") self.movingImageLabelSelector.selectNodeUponCreation = True self.movingImageLabelSelector.addEnabled = False self.movingImageLabelSelector.removeEnabled = False self.movingImageLabelSelector.noneEnabled = False self.movingImageLabelSelector.showHidden = False self.movingImageLabelSelector.showChildNodeTypes = False self.movingImageLabelSelector.setMRMLScene(slicer.mrmlScene) self.movingImageLabelSelector.setToolTip( "Segmentation of the moving image") parametersFormLayout.addRow("Segmentation of the moving Image: ", self.movingImageLabelSelector) # # Affine output transform selector # self.affineTransformSelector = slicer.qMRMLNodeComboBox() self.affineTransformSelector.nodeTypes = (("vtkMRMLTransformNode"), "") self.affineTransformSelector.selectNodeUponCreation = True self.affineTransformSelector.addEnabled = True self.affineTransformSelector.removeEnabled = False self.affineTransformSelector.noneEnabled = False self.affineTransformSelector.showHidden = False self.affineTransformSelector.showChildNodeTypes = False self.affineTransformSelector.baseName = 'Affine Transform' self.affineTransformSelector.setMRMLScene(slicer.mrmlScene) self.affineTransformSelector.setToolTip( "Registration affine transform") parametersFormLayout.addRow("Registration affine transform: ", self.affineTransformSelector) # # B-spline output transform selector # self.bsplineTransformSelector = slicer.qMRMLNodeComboBox() self.bsplineTransformSelector.nodeTypes = (("vtkMRMLTransformNode"), "") self.bsplineTransformSelector.selectNodeUponCreation = True self.bsplineTransformSelector.addEnabled = True self.bsplineTransformSelector.removeEnabled = False self.bsplineTransformSelector.noneEnabled = False self.bsplineTransformSelector.showHidden = False self.bsplineTransformSelector.showChildNodeTypes = False self.bsplineTransformSelector.baseName = 'Deformable Transform' self.bsplineTransformSelector.setMRMLScene(slicer.mrmlScene) self.bsplineTransformSelector.setToolTip( "Registration b-spline transform") parametersFormLayout.addRow("Registration B-spline Transform: ", self.bsplineTransformSelector) # # registered volume selector # ''' self.outputImageSelector = slicer.qMRMLNodeComboBox() self.outputImageSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.outputImageSelector.nodeTypes = ( ("vtkMRMLLabelMapVolumeNode"), "" ) self.outputImageSelector.selectNodeUponCreation = True self.outputImageSelector.addEnabled = True self.outputImageSelector.removeEnabled = True self.outputImageSelector.noneEnabled = True self.outputImageSelector.showHidden = False self.outputImageSelector.showChildNodeTypes = False self.outputImageSelector.baseName = 'Registered Volume' self.outputImageSelector.setMRMLScene( slicer.mrmlScene ) self.outputImageSelector.setToolTip( "Registered volume (will be generated only if the moving image was provided)" ) parametersFormLayout.addRow("Registered Volume: ", self.outputImageSelector) ''' # # To be added later: advanced parameters # registration modes (rigid/affine/bspline), save rigid/affine transforms, # crop box margin, number of samples, ... # # Add parameter node to facilitate registration from other modules and # command line # self.registrationModeGroup = qt.QButtonGroup() self.noRegistrationRadio = qt.QRadioButton('Before registration') self.linearRegistrationRadio = qt.QRadioButton( 'After linear registration') self.deformableRegistrationRadio = qt.QRadioButton( 'After deformable registration') self.noRegistrationRadio.setChecked(1) self.registrationModeGroup.addButton(self.noRegistrationRadio, 1) self.registrationModeGroup.addButton(self.linearRegistrationRadio, 2) self.registrationModeGroup.addButton(self.deformableRegistrationRadio, 3) parametersFormLayout.addRow(qt.QLabel("Visualization")) parametersFormLayout.addRow("", self.noRegistrationRadio) parametersFormLayout.addRow("", self.linearRegistrationRadio) parametersFormLayout.addRow("", self.deformableRegistrationRadio) self.registrationModeGroup.connect('buttonClicked(int)', self.onVisualizationModeClicked) # # 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) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state #self.onSelect() self.parameterNode = slicer.vtkMRMLScriptedModuleNode() '''
def __init__(self, parent, *args, **kwargs): """ Init function. """ super(FingerTabWidget, self).__init__(parent) #-------------------- # Define sizing parameters. #-------------------- self.marginVal = 5 self.currentIndex = 0 self.tabWidth = 120 #-------------------- # Make and style 'tabColumn', which is a qFrame. #-------------------- self.tabColumn = qt.QFrame(self) self.tabColumn.setFixedWidth(self.tabWidth) self.tabColumn.setObjectName('tabColumn') self.tabColumn.setStyleSheet('#tabColumn {background:#E8E8E8 ; height: 4000px;' + 'border-right-width: 1px; border-right-color: gray;' + 'border-right-style: solid; margin-top: 5px;' + 'margin-left: 5px; margin-bottom: 5px}') #-------------------- # Define the layout of the 'tabColumn' qFrame, # set the layout to the 'tabColumn' qFrame. #-------------------- self.tabColumnLayout = qt.QVBoxLayout() self.tabColumnLayout.setContentsMargins(0,0,0,0) self.tabColumnLayout.setSpacing(0) self.tabColumnLayout.addStretch() self.tabColumn.setLayout(self.tabColumnLayout) #-------------------- # Define the 'innerWindowLayout'. #-------------------- self.innerWindowLayout = qt.QStackedLayout() self.innerWindowLayout.setStackingMode(1) self.innerWindowLayout.setSpacing(0) self.innerWindowLayout.setContentsMargins(0,0,0,0) #-------------------- # Define the 'widgetStack' object, which takes # the whole span of the window. #-------------------- self.widgetStack = qt.QWidget(self) self.widgetStack.setObjectName("widgetStack") self.widgetStack.setStyleSheet("#widgetStack{ border: none; background: transparent}") #-------------------- # The layout for the 'widgetStack' is # 'widgetStackLayout', which is an HBoxLayout. We set # a left spacing the length of the tabs-1 to accomodate for the border # and tabs of the widget. #-------------------- self.widgetStackLayout = qt.QHBoxLayout() self.widgetStackLayout.setContentsMargins(0,self.marginVal,self.marginVal,self.marginVal) self.widgetStackLayout.addSpacing(self.tabWidth - 1) self.widgetStack.setLayout(self.widgetStackLayout) #-------------------- # Define the 'tabPageStack', add to the widgetStackLayout. # # NOTE: The 'tabPageStack' is the stacked layout were all # of the tab pages reside. #-------------------- self.tabPageStack = qt.QStackedLayout() self.widgetStackLayout.addLayout(self.tabPageStack) #-------------------- # Define the tabButtons as part of a # button group, for easier event listening. # # Set their styles as well. #-------------------- self.buttonGroup = qt.QButtonGroup(self) self.buttonGroup.connect('buttonClicked(QAbstractButton*)', self.onTabClicked) self.tabButtons = [] self.tabWidgets = [] self.tabObjectName = 'fingerTab' self.tabToggledStyle = '#fingerTab {border: 1px solid gray; border-right-width: 1px; border-right-color: white; background-color: white;}' self.tabUntoggledStyle ='#fingerTab {border: 1px solid #D0D0D0; border-right-width: 1px; border-right-color: gray; background-color: #C0C0C0;}' self.tabToggledFont = qt.QFont('Arial', 12, 100, False) self.tabUntoggledFont = qt.QFont('Arial', 12, 25, False) #-------------------- # Add 'tabColumn' and 'widgetStack' to 'innerWindowLayout'. Set the current # index of the widgetStack (this will allow for the black # borders between the tabs and the windows to connect). #-------------------- self.innerWindowLayout.addWidget(self.tabColumn) self.innerWindowLayout.addWidget(self.widgetStack) self.innerWindowLayout.setCurrentIndex(1) #-------------------- # Set 'mainWidgetLayout' to hold the 'innerWindowLayout'. # The 'mainWidgetLayout' exists because subclasses of # 'FingerTabWidget' and others that use it can add # further rows to the window (such as 'Done' and 'Cancel' # buttons). #-------------------- self.mainWidgetLayout = qt.QVBoxLayout() self.mainWidgetLayout.setContentsMargins(5,5,5,5) self.mainWidgetLayout.addLayout(self.innerWindowLayout) #-------------------- # Set the primary layout to the 'mainWidgetLayout' #-------------------- self.setLayout(self.mainWidgetLayout)
def setup(self): # # 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 = "Radiomics 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) reloadCollapsibleButton.collapsed = True #--------------------------------------------------------- # # Compute Radiomics area # self.computeRadiomicsCollapsibleButton = ctk.ctkCollapsibleButton() self.computeRadiomicsCollapsibleButton.text = "Slicer Radiomics Platform" self.layout.addWidget(self.computeRadiomicsCollapsibleButton) self.computeRadiomicsFormLayout = qt.QFormLayout( self.computeRadiomicsCollapsibleButton) # # Universal Advanced Settings Collapsible Button # self.AdvancedSettingsCollapsibleButton = ctk.ctkCollapsibleButton() self.AdvancedSettingsCollapsibleButton.text = "Advanced Settings" self.AdvancedSettingsCollapsibleButtonLayout = qt.QHBoxLayout() self.AdvancedSettingsCollapsibleButton.setLayout(qt.QHBoxLayout()) self.computeRadiomicsFormLayout.addWidget( self.AdvancedSettingsCollapsibleButton) self.AdvancedSettingsCollapsibleButton.collapsed = True self.AdvancedSettingsFrame = qt.QFrame( self.AdvancedSettingsCollapsibleButton) self.AdvancedSettingsFrameLayout = qt.QFormLayout() self.AdvancedSettingsFrame.setLayout(self.AdvancedSettingsFrameLayout) self.AdvancedSettingsCollapsibleButton.layout().addWidget( self.AdvancedSettingsFrame) # Label Values self.inputLabelValues = qt.QLabel("Label Values:", self.AdvancedSettingsFrame) self.inputLabelValuesField = qt.QLineEdit("1", self.AdvancedSettingsFrame) self.AdvancedSettingsFrameLayout.addRow(self.inputLabelValues, self.inputLabelValuesField) # Interpolation Settings self.settingsRadioButtonFrame = qt.QFrame(self.AdvancedSettingsFrame) self.settingsRadioButtonFrame.setLayout(qt.QHBoxLayout()) self.interpolationsGroup = qt.QButtonGroup( self.settingsRadioButtonFrame) self.ipRawButton = qt.QRadioButton("Raw") self.ip1x1x1Button = qt.QRadioButton("(1,1,1)") self.ip2x2x2Button = qt.QRadioButton("(2,2,2)") self.ip3x3x3Button = qt.QRadioButton("(3,3,3)") self.ipRawButton.checked = True self.interpolationsGroup.addButton(self.ipRawButton) self.interpolationsGroup.addButton(self.ip1x1x1Button) self.interpolationsGroup.addButton(self.ip2x2x2Button) self.interpolationsGroup.addButton(self.ip3x3x3Button) self.settingsRadioButtonFrame.layout().addWidget(self.ipRawButton) self.settingsRadioButtonFrame.layout().addWidget(self.ip1x1x1Button) self.settingsRadioButtonFrame.layout().addWidget(self.ip2x2x2Button) self.settingsRadioButtonFrame.layout().addWidget(self.ip3x3x3Button) self.interpHeader = qt.QLabel("Interpolation:") self.AdvancedSettingsFrameLayout.addRow(self.interpHeader, self.settingsRadioButtonFrame) # Bin Width self.inputBinWidth = qt.QLabel("Bin Width:", self.AdvancedSettingsFrame) self.inputBinWidthField = qt.QLineEdit("25", self.AdvancedSettingsFrame) self.AdvancedSettingsFrameLayout.addRow(self.inputBinWidth, self.inputBinWidthField) # Modality Radio Buttons Frame self.ModalityRadioButtonFrame = qt.QFrame(self.AdvancedSettingsFrame) self.ModalityRadioButtonFrame.setLayout(qt.QHBoxLayout()) self.ModalityFileFormatGroup = qt.QButtonGroup( self.ModalityRadioButtonFrame) self.CTButton = qt.QRadioButton("CT") self.CTButton.checked = True self.MRIButton = qt.QRadioButton("MRI") self.PETButton = qt.QRadioButton("PET") self.ModalityFileFormatGroup.addButton(self.CTButton) self.ModalityFileFormatGroup.addButton(self.MRIButton) self.ModalityFileFormatGroup.addButton(self.PETButton) self.ModalityRadioButtonFrame.layout().addWidget(self.CTButton) self.ModalityRadioButtonFrame.layout().addWidget(self.MRIButton) self.ModalityRadioButtonFrame.layout().addWidget(self.PETButton) self.ModalityInputLabel = qt.QLabel("Image Modality:", self.AdvancedSettingsFrame) self.AdvancedSettingsFrameLayout.addRow(self.ModalityInputLabel, self.ModalityRadioButtonFrame) # # End Universal Advanced Settings Collapsible Button # # Parent Tab Widget self.computeRadiomicsTabWidget = qt.QTabWidget() self.computeRadiomicsFormLayout.addWidget( self.computeRadiomicsTabWidget) # Radiomics Current Mode self.tabComputeRadiomicsCurr = qt.QWidget() self.singleCaseInputFormLayout = qt.QFormLayout() self.tabComputeRadiomicsCurr.setLayout(self.singleCaseInputFormLayout) self.tabComputeRadiomicsCurrName = "Single Case Mode" self.computeRadiomicsTabWidget.addTab(self.tabComputeRadiomicsCurr, self.tabComputeRadiomicsCurrName) # Input 1: Input Image self.input1Frame = qt.QFrame(self.tabComputeRadiomicsCurr) self.input1Frame.setLayout(qt.QHBoxLayout()) self.singleCaseInputFormLayout.addWidget(self.input1Frame) self.input1Selector = qt.QLabel("Input Image: ", self.input1Frame) self.input1Frame.layout().addWidget(self.input1Selector) self.input1Selector = slicer.qMRMLNodeComboBox(self.input1Frame) self.input1Selector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.input1Selector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.input1Selector.addEnabled = False self.input1Selector.removeEnabled = False self.input1Selector.setMRMLScene(slicer.mrmlScene) self.input1Frame.layout().addWidget(self.input1Selector) # Input 2: Input Segmentation self.input2Frame = qt.QFrame(self.tabComputeRadiomicsCurr) self.input2Frame.setLayout(qt.QHBoxLayout()) self.singleCaseInputFormLayout.addWidget(self.input2Frame) self.input2Selector = qt.QLabel("Input Label: ", self.input2Frame) self.input2Frame.layout().addWidget(self.input2Selector) self.input2Selector = slicer.qMRMLNodeComboBox(self.input2Frame) self.input2Selector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.input2Selector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 1) self.input2Selector.addEnabled = False self.input2Selector.removeEnabled = False self.input2Selector.setMRMLScene(slicer.mrmlScene) self.input2Frame.layout().addWidget(self.input2Selector) # Settings Collapsible Button self.SettingsCollapsibleButtonCurr = ctk.ctkCollapsibleButton() self.SettingsCollapsibleButtonCurr.text = "Settings" self.SettingsCollapsibleButtonCurrLayout = qt.QHBoxLayout() self.SettingsCollapsibleButtonCurr.setLayout( self.SettingsCollapsibleButtonCurrLayout) self.singleCaseInputFormLayout.addWidget( self.SettingsCollapsibleButtonCurr) self.SettingsCollapsibleButtonCurr.collapsed = False self.SettingsFrameCurr = qt.QFrame(self.SettingsCollapsibleButtonCurr) self.SettingsFrameCurr.setLayout(qt.QFormLayout()) self.SettingsCollapsibleButtonCurrLayout.addWidget( self.SettingsFrameCurr) # Settings self.para2curr = qt.QCheckBox("Use MatlabBridge", self.tabComputeRadiomicsCurr) self.para2curr.toolTip = "When checked: Matlab features extracted" self.para2curr.checked = False self.SettingsFrameCurr.layout().addRow(self.para2curr) # Apply Radiomics button self.RadiomicCurrButtonsFrame = qt.QFrame(self.tabComputeRadiomicsCurr) self.RadiomicCurrButtonsFrame.setLayout(qt.QHBoxLayout()) self.singleCaseInputFormLayout.addWidget(self.RadiomicCurrButtonsFrame) self.radiomicsCurrButton = qt.QPushButton( "Compute Radiomics Features (Single Case)", self.RadiomicCurrButtonsFrame) self.radiomicsCurrButton.enabled = True self.radiomicsCurrButton.toolTip = "Run the feature extraction for a single case." self.RadiomicCurrButtonsFrame.layout().addWidget( self.radiomicsCurrButton) # Chart self.RadiomicsTableFrame = qt.QFrame(self.tabComputeRadiomicsCurr) self.RadiomicsTableFrameLayout = qt.QHBoxLayout() self.RadiomicsTableFrame.setLayout(self.RadiomicsTableFrameLayout) self.singleCaseInputFormLayout.addWidget(self.RadiomicsTableFrame) self.RadiomicsTableView = qt.QTableView(self.RadiomicsTableFrame) self.RadiomicsTableView.sortingEnabled = True self.RadiomicsTableView.minimumHeight = 175 self.RadiomicsTableView.verticalHeader().visible = False self.RadiomicsTableView.setColumnWidth(0, 30) self.RadiomicsTableFrameLayout.addWidget(self.RadiomicsTableView) self.RadiomicsTableModel = qt.QStandardItemModel() # Save Table Button self.saveButton = qt.QPushButton("Save Table to CSV File", self.RadiomicCurrButtonsFrame) self.saveButton.toolTip = "Save Radiomics Feature from table to CSV file" self.saveButton.enabled = False self.singleCaseInputFormLayout.layout().addWidget(self.saveButton) """ # # The interface we use for batch mode (not part of this module) # #--------------------------------------------------------- # Radiomics Batch self.tabComputeRadiomicsBatch = qt.QWidget() self.RadiomicsFormLayout = qt.QFormLayout() self.tabComputeRadiomicsBatch.setLayout(self.RadiomicsFormLayout) self.tabComputeRadiomicsBatchName = "Batch Mode" self.computeRadiomicsTabWidget.addTab(self.tabComputeRadiomicsBatch, self.tabComputeRadiomicsBatchName) # Input 3: Database selection self.input3Frame = qt.QFrame(self.tabComputeRadiomicsBatch) self.input3Frame.setLayout(qt.QHBoxLayout()) self.RadiomicsFormLayout.addWidget(self.input3Frame) self.DatabaseButton = qt.QPushButton("Set Root Patient Directory") self.DatabaseButton.toolTip = "Set the main Patient Data location" self.DatabaseButton.enabled = True self.input3Frame.layout().addWidget(self.DatabaseButton) self.PatientSelector = qt.QComboBox() self.PatientSelector.enabled = False self.input3Frame.layout().addWidget(self.PatientSelector) # Settings Collapsible Button self.SettingsCollapsibleButton = ctk.ctkCollapsibleButton() self.SettingsCollapsibleButton.text = "Settings" self.SettingsCollapsibleButtonLayout = qt.QHBoxLayout() self.SettingsCollapsibleButton.setLayout(self.SettingsCollapsibleButtonLayout) self.RadiomicsFormLayout.addWidget(self.SettingsCollapsibleButton) self.SettingsCollapsibleButton.collapsed = False self.SettingsFrame = qt.QFrame(self.SettingsCollapsibleButton) self.SettingsFrame.setLayout(qt.QFormLayout()) self.SettingsCollapsibleButtonLayout.addWidget(self.SettingsFrame) # Settings self.para2 = qt.QCheckBox("Use MatlabBridge", self.SettingsFrame) self.para2.toolTip = "When checked: Matlab features extracted" self.para2.checked = True self.SettingsFrame.layout().addRow(self.para2) self.para3 = qt.QCheckBox("Clear Database", self.SettingsFrame) self.para3.toolTip = "When checked: old database is cleared" self.para3.checked = True self.SettingsFrame.layout().addRow(self.para3) # Keywords Collapsible Button self.KeywordsCollapsibleButton = ctk.ctkCollapsibleButton() self.KeywordsCollapsibleButton.text = "Keyword Matching" self.KeywordsCollapsibleButtonLayout = qt.QHBoxLayout() self.KeywordsCollapsibleButton.setLayout(self.KeywordsCollapsibleButtonLayout) self.SettingsFrame.layout().addRow(self.KeywordsCollapsibleButton) self.KeywordsCollapsibleButton.collapsed = True self.keywordsFrame = qt.QFrame(self.KeywordsCollapsibleButton) self.keywordsFrame.setLayout(qt.QFormLayout()) self.KeywordsCollapsibleButtonLayout.addWidget(self.keywordsFrame) self.keywordsHeader = qt.QLabel("Keyword Matching:", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.keywordsHeader) # File Type Radio Buttons Frame self.radioButtonFrame = qt.QFrame(self.keywordsFrame) self.radioButtonFrame.setLayout(qt.QFormLayout()) self.fileFormatGroup = qt.QButtonGroup(self.radioButtonFrame) self.nrrdButton = qt.QRadioButton("NRRD") self.nrrdButton.checked = True self.niftiButton = qt.QRadioButton("NIFTI") self.fileFormatGroup.addButton(self.nrrdButton) self.fileFormatGroup.addButton(self.niftiButton) self.radioButtonFrame.layout().addRow(self.nrrdButton, self.niftiButton) self.inputMaskHeader = qt.QLabel("Input Image File Type:", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputMaskHeader, self.radioButtonFrame) # Keywords Frame self.inputImageKeywords = qt.QLabel("Input Image Keywords:", self.keywordsFrame) self.inputImageKeywordsField = qt.QLineEdit("",self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputImageKeywords, self.inputImageKeywordsField ) self.inputImageExclusionKeywords = qt.QLabel("Input Image Exclusion Keywords:", self.keywordsFrame) self.inputImageExclusionKeywordsField = qt.QLineEdit("",self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputImageExclusionKeywords, self.inputImageExclusionKeywordsField ) self.inputLabelKeywords = qt.QLabel("Input Label Keywords:", self.keywordsFrame) self.inputLabelKeywordsField = qt.QLineEdit("",self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputLabelKeywords, self.inputLabelKeywordsField ) self.inputLabelExclusionKeywords = qt.QLabel("Input Label Exclusion Keywords:", self.keywordsFrame) self.inputLabelExclusionKeywordsField = qt.QLineEdit("",self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputLabelExclusionKeywords, self.inputLabelExclusionKeywordsField ) # Radiomic Mode Buttons self.RadiomicButtonsFrame = qt.QFrame(self.tabComputeRadiomicsBatch) self.RadiomicButtonsFrame.setLayout(qt.QHBoxLayout()) self.RadiomicsFormLayout.addWidget(self.RadiomicButtonsFrame) self.radiomicsBatchButton = qt.QPushButton("Compute Radiomics Features (Batch Mode)") self.radiomicsBatchButton.toolTip = "Run the feature extraction for database batch." self.radiomicsBatchButton.enabled = True self.RadiomicButtonsFrame.layout().addWidget(self.radiomicsBatchButton) self.RadiomicButtonsFrame.enabled = True """ #--------------------------------------------------------- # Connections #self.DatabaseButton.connect('clicked(bool)', self.onDatabaseButton) self.radiomicsCurrButton.connect('clicked(bool)', self.onRadiomicsCurr) #self.radiomicsBatchButton.connect('clicked(bool)', self.onRadiomicsBatch) self.saveButton.connect('clicked()', self.onSave) self.layout.addStretch(1) # Add vertical spacer
def setup(self): #--------------------------------------------------------- # Batch Covert DICOM to NRRD self.BatchConvertCollapsibleButton = ctk.ctkCollapsibleButton() self.BatchConvertCollapsibleButton.text = "Batch convert DICOM to NRRD or NIFTI" self.layout.addWidget(self.BatchConvertCollapsibleButton) self.BatchConvertCollapsibleButton.collapsed = False self.BatchConvertFormLayout = qt.QFormLayout( self.BatchConvertCollapsibleButton) # Input 1: Input Directory selector self.input1Selector = qt.QLabel("Input Directory (DICOM): ", self.BatchConvertCollapsibleButton) self.input1Button = qt.QPushButton( "Select Main Input Directory of DICOM files") self.input1Button.toolTip = "Select main directory with DICOM files (folder names are patient names)" self.input1Button.enabled = True self.BatchConvertFormLayout.addRow(self.input1Selector, self.input1Button) # Input 2: Output Directory selector self.input2Selector = qt.QLabel("Output Directory: ", self.BatchConvertCollapsibleButton) self.input2Button = qt.QPushButton("Select Main Output Directory") self.input2Button.toolTip = "Select main directory for output NRRD or NIFTI files (folder names are patient names)" self.input2Button.enabled = True self.BatchConvertFormLayout.addRow(self.input2Selector, self.input2Button) # RTStruct Conversion self.contourConvertLabel = qt.QLabel( "Convert DICOM-RT Contours: ", self.BatchConvertCollapsibleButton) self.contourConvertSelectFrame = qt.QFrame( self.BatchConvertCollapsibleButton) self.contourConvertSelectFrame.setLayout(qt.QHBoxLayout()) self.contourConvertGroup = qt.QButtonGroup( self.contourConvertSelectFrame) self.noConvertButton = qt.QRadioButton("None") self.noConvertButton.checked = True self.allConvertButton = qt.QRadioButton("All") self.selectConvertButton = qt.QRadioButton("Select") self.contourConvertGroup.addButton(self.noConvertButton) self.contourConvertGroup.addButton(self.allConvertButton) self.contourConvertGroup.addButton(self.selectConvertButton) self.contourConvertSelectFrame.layout().addWidget(self.noConvertButton) self.contourConvertSelectFrame.layout().addWidget( self.allConvertButton) self.contourConvertSelectFrame.layout().addWidget( self.selectConvertButton) self.BatchConvertFormLayout.layout().addRow( self.contourConvertLabel, self.contourConvertSelectFrame) self.contourConvertCollapsibleButton = ctk.ctkCollapsibleButton( self.BatchConvertCollapsibleButton) self.contourConvertCollapsibleButton.text = "Select Contours to Convert" self.BatchConvertFormLayout.addRow( self.contourConvertCollapsibleButton) self.contourConvertCollapsibleButton.enabled = False self.contourConvertCollapsibleButton.collapsed = True self.contourConvertFormLayout = qt.QFormLayout( self.contourConvertCollapsibleButton) # Keywords to catch RTStruct Structures self.contoursFrame = qt.QFrame(self.contourConvertCollapsibleButton) self.contoursFrame.setLayout(qt.QVBoxLayout()) self.contoursFrame.setFrameStyle(2) self.contourConvertFormLayout.addWidget(self.contoursFrame) self.addContourButton = qt.QPushButton( "Add Contour to convert from RTStruct (separate keywords by comma)", self.contoursFrame) self.keywordsScrollWidget = qt.QWidget() self.keywordsScrollWidget.setLayout(qt.QFormLayout()) self.keywordsScroll = qt.QScrollArea() self.keywordsScroll.setWidgetResizable(True) self.keywordsScroll.setWidget(self.keywordsScrollWidget) self.contoursFrame.layout().addWidget(self.keywordsScroll) self.contoursFrame.layout().addWidget(self.addContourButton) # Settings Collapsible Button self.settingsCollapsibleButton = ctk.ctkCollapsibleButton() self.settingsCollapsibleButton.text = "Settings" self.settingsCollapsibleButton.setLayout(qt.QFormLayout()) self.layout.addWidget(self.settingsCollapsibleButton) # NRRD or NIFTI Radio Buttons self.fileFormatLabel = qt.QLabel("Output File Format: ", self.settingsCollapsibleButton) self.fileFormatSelectFrame = qt.QFrame(self.settingsCollapsibleButton) self.fileFormatSelectFrame.setLayout(qt.QFormLayout()) self.fileFormatGroup = qt.QButtonGroup(self.fileFormatSelectFrame) self.nrrdButton = qt.QRadioButton("NRRD") self.nrrdButton.checked = True self.niftiButton = qt.QRadioButton("NIFTI") self.fileFormatGroup.addButton(self.nrrdButton) self.fileFormatGroup.addButton(self.niftiButton) self.fileFormatSelectFrame.layout().addRow(self.nrrdButton, self.niftiButton) self.settingsCollapsibleButton.layout().addRow( self.fileFormatLabel, self.fileFormatSelectFrame) # Use input DICOM Patient Directory names as PatientID or infer from DICOM Metadata self.patientIDLabel = qt.QLabel("Infer Patient IDs from: ", self.settingsCollapsibleButton) self.patientIDLabel.toolTip = "Use input DICOM Patient Directory names as PatientID or infer from DICOM Metadata" self.patientIDSelectFrame = qt.QFrame(self.settingsCollapsibleButton) self.patientIDSelectFrame.setLayout(qt.QFormLayout()) self.patientIDGroup = qt.QButtonGroup(self.patientIDSelectFrame) self.metadataButton = qt.QRadioButton("Series DICOM Metadata") self.metadataButton.checked = True self.inputDirButton = qt.QRadioButton("Input Patient Subdirectories") self.patientIDGroup.addButton(self.metadataButton) self.patientIDGroup.addButton(self.inputDirButton) self.patientIDSelectFrame.layout().addRow(self.metadataButton, self.inputDirButton) self.settingsCollapsibleButton.layout().addRow( self.patientIDLabel, self.patientIDSelectFrame) # Center Images option self.centerImagesLabel = qt.QLabel("Center Images: ", self.settingsCollapsibleButton) self.centerImagesSelectFrame = qt.QFrame( self.settingsCollapsibleButton) self.centerImagesSelectFrame.setLayout(qt.QFormLayout()) self.centerImagesGroup = qt.QButtonGroup(self.centerImagesSelectFrame) self.centerImagesButton = qt.QRadioButton("Yes") self.noCenterImagesButton = qt.QRadioButton("No") self.noCenterImagesButton.checked = True self.centerImagesGroup.addButton(self.centerImagesButton) self.centerImagesGroup.addButton(self.noCenterImagesButton) self.centerImagesSelectFrame.layout().addRow(self.centerImagesButton, self.noCenterImagesButton) self.settingsCollapsibleButton.layout().addRow( self.centerImagesLabel, self.centerImagesSelectFrame) # Center Labels option self.centerLabelsLabel = qt.QLabel("Center Labels: ", self.settingsCollapsibleButton) self.centerLabelsSelectFrame = qt.QFrame( self.settingsCollapsibleButton) self.centerLabelsSelectFrame.setLayout(qt.QFormLayout()) self.centerLabelsGroup = qt.QButtonGroup(self.centerLabelsSelectFrame) self.centerLabelsButton = qt.QRadioButton("Yes") self.noCenterLabelsButton = qt.QRadioButton("No") self.noCenterLabelsButton.checked = True self.centerLabelsGroup.addButton(self.centerLabelsButton) self.centerLabelsGroup.addButton(self.noCenterLabelsButton) self.centerLabelsSelectFrame.layout().addRow(self.centerLabelsButton, self.noCenterLabelsButton) self.settingsCollapsibleButton.layout().addRow( self.centerLabelsLabel, self.centerLabelsSelectFrame) # Parse and Save DICOM Metadata to CSV self.metadataExtractLabel = qt.QLabel("DICOM Metadata Extraction", self.settingsCollapsibleButton) self.metadataExtractLabel.toolTip = "Extract and Save all DICOM Metadata to a CSV file" self.metadataExtractSelectFrame = qt.QFrame( self.settingsCollapsibleButton) self.metadataExtractSelectFrame.setLayout(qt.QFormLayout()) self.metadataExtractGroup = qt.QButtonGroup( self.metadataExtractSelectFrame) self.extractCSVButton = qt.QRadioButton("CSV") self.extractCSVButton.checked = True #self.extractJSONButton = qt.QRadioButton("JSON") self.doNotExtractButton = qt.QRadioButton("None") self.metadataExtractGroup.addButton(self.extractCSVButton) self.metadataExtractGroup.addButton(self.doNotExtractButton) self.metadataExtractSelectFrame.layout().addRow( self.extractCSVButton, self.doNotExtractButton) self.settingsCollapsibleButton.layout().addRow( self.metadataExtractLabel, self.metadataExtractSelectFrame) # Apply Batch Convert button self.applyBatchButton = qt.QPushButton("Apply Batch Convert") self.applyBatchButton.toolTip = "Batch convert DICOM to NRRD or NIFTI files" self.layout.addWidget(self.applyBatchButton) self.applyBatchButton.enabled = False #--------------------------------------------------------- # Connections self.input1Button.connect('clicked(bool)', self.onInput1Button) self.input2Button.connect('clicked(bool)', self.onInput2Button) self.selectConvertButton.toggled.connect(self.selectConvert) self.addContourButton.connect('clicked(bool)', self.addContourFilterWidget) self.applyBatchButton.connect('clicked(bool)', self.onBatchApply)
def setup(self): # Instantiate and connect widgets ... self.RingOff = None self.RingOn = None # Tags to manage event observers self.tagSourceNode = None self.tagDestinationNode = None ##################### ## For debugging ## ## 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 = "CurveMaker Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) ## ##################### # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Source points (vtkMRMLMarkupsFiducialNode) # self.SourceSelector = slicer.qMRMLNodeComboBox() self.SourceSelector.nodeTypes = (("vtkMRMLMarkupsFiducialNode"), "") self.SourceSelector.addEnabled = True self.SourceSelector.removeEnabled = False self.SourceSelector.noneEnabled = True self.SourceSelector.showHidden = False self.SourceSelector.renameEnabled = True self.SourceSelector.showChildNodeTypes = False self.SourceSelector.setMRMLScene(slicer.mrmlScene) self.SourceSelector.setToolTip( "Pick up a Markups node listing fiducials.") parametersFormLayout.addRow("Source points: ", self.SourceSelector) # # Target point (vtkMRMLMarkupsFiducialNode) # self.DestinationSelector = slicer.qMRMLNodeComboBox() self.DestinationSelector.nodeTypes = (("vtkMRMLModelNode"), "") self.DestinationSelector.addEnabled = True self.DestinationSelector.removeEnabled = False self.DestinationSelector.noneEnabled = True self.DestinationSelector.showHidden = False self.DestinationSelector.renameEnabled = True self.DestinationSelector.selectNodeUponCreation = True self.DestinationSelector.showChildNodeTypes = False self.DestinationSelector.setMRMLScene(slicer.mrmlScene) self.DestinationSelector.setToolTip("Pick up or create a Model node.") parametersFormLayout.addRow("Curve model: ", self.DestinationSelector) # # Radius for the tube # self.RadiusSliderWidget = ctk.ctkSliderWidget() self.RadiusSliderWidget.singleStep = 1.0 self.RadiusSliderWidget.minimum = 1.0 self.RadiusSliderWidget.maximum = 50.0 self.RadiusSliderWidget.value = 5.0 self.RadiusSliderWidget.setToolTip("Set the raidus of the tube.") parametersFormLayout.addRow("Radius (mm): ", self.RadiusSliderWidget) # # Radio button to select interpolation method # self.InterpolationLayout = qt.QHBoxLayout() self.InterpolationNone = qt.QRadioButton("None") self.InterpolationCardinalSpline = qt.QRadioButton("Cardinal Spline") self.InterpolationHermiteSpline = qt.QRadioButton( "Hermite Spline (for Endoscopy)") self.InterpolationLayout.addWidget(self.InterpolationNone) self.InterpolationLayout.addWidget(self.InterpolationCardinalSpline) self.InterpolationLayout.addWidget(self.InterpolationHermiteSpline) self.InterpolationGroup = qt.QButtonGroup() self.InterpolationGroup.addButton(self.InterpolationNone) self.InterpolationGroup.addButton(self.InterpolationCardinalSpline) self.InterpolationGroup.addButton(self.InterpolationHermiteSpline) parametersFormLayout.addRow("Interpolation: ", self.InterpolationLayout) # # Interpolation Resolution # self.InterpResolutionSliderWidget = ctk.ctkSliderWidget() self.InterpResolutionSliderWidget.singleStep = 1.0 self.InterpResolutionSliderWidget.minimum = 3.0 self.InterpResolutionSliderWidget.maximum = 50.0 self.InterpResolutionSliderWidget.value = 25.0 self.InterpResolutionSliderWidget.setToolTip( "Number of interpolation points between control points. Default is 25." ) parametersFormLayout.addRow("Resolution: ", self.InterpResolutionSliderWidget) # # Radio button for ring mode # self.RingLayout = qt.QHBoxLayout() self.RingOff = qt.QRadioButton("Off") self.RingOn = qt.QRadioButton("On") self.RingLayout.addWidget(self.RingOff) self.RingLayout.addWidget(self.RingOn) self.RingGroup = qt.QButtonGroup() self.RingGroup.addButton(self.RingOff) self.RingGroup.addButton(self.RingOn) parametersFormLayout.addRow("Ring mode: ", self.RingLayout) # # Check box to start curve visualization # self.EnableAutoUpdateCheckBox = qt.QCheckBox() self.EnableAutoUpdateCheckBox.checked = 0 self.EnableAutoUpdateCheckBox.setToolTip( "If checked, the CurveMaker module keeps updating the model as the points are updated." ) parametersFormLayout.addRow("Auto update:", self.EnableAutoUpdateCheckBox) # # Button to generate a curve # self.GenerateButton = qt.QPushButton("Generate Curve") self.GenerateButton.toolTip = "Generate Curve" self.GenerateButton.enabled = True parametersFormLayout.addRow("", self.GenerateButton) # Connections self.InterpolationNone.connect('clicked(bool)', self.onSelectInterpolationNone) self.InterpolationCardinalSpline.connect( 'clicked(bool)', self.onSelectInterpolationCardinalSpline) self.InterpolationHermiteSpline.connect( 'clicked(bool)', self.onSelectInterpolationHermiteSpline) self.RingOff.connect('clicked(bool)', self.onRingOff) self.RingOn.connect('clicked(bool)', self.onRingOn) self.EnableAutoUpdateCheckBox.connect('toggled(bool)', self.onEnableAutoUpdate) self.SourceSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSourceSelected) self.DestinationSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onDestinationSelected) self.RadiusSliderWidget.connect("valueChanged(double)", self.onTubeUpdated) self.InterpResolutionSliderWidget.connect( "valueChanged(double)", self.onInterpResolutionUpdated) self.GenerateButton.connect('clicked(bool)', self.onGenerateCurve) # Set default ## default interpolation method self.InterpolationCardinalSpline.setChecked(True) self.onSelectInterpolationCardinalSpline(True) ## default ring mode self.RingOff.setChecked(True) self.onRingOff(True) # # Curve Length area # lengthCollapsibleButton = ctk.ctkCollapsibleButton() lengthCollapsibleButton.text = "Length" self.layout.addWidget(lengthCollapsibleButton) lengthFormLayout = qt.QFormLayout(lengthCollapsibleButton) lengthCollapsibleButton.collapsed = True #-- Curve length self.lengthLineEdit = qt.QLineEdit() self.lengthLineEdit.text = '--' self.lengthLineEdit.readOnly = True self.lengthLineEdit.frame = True self.lengthLineEdit.styleSheet = "QLineEdit { background:transparent; }" self.lengthLineEdit.cursor = qt.QCursor(qt.Qt.IBeamCursor) lengthFormLayout.addRow("Curve Length (mm):", self.lengthLineEdit) # # Distance Area # distanceCollapsibleButton = ctk.ctkCollapsibleButton() distanceCollapsibleButton.text = "Distance" distanceCollapsibleButton.collapsed = True self.layout.addWidget(distanceCollapsibleButton) distanceFormLayout = qt.QFormLayout(distanceCollapsibleButton) #-- Point-to-curve distance # - Markups selector for input points distanceLayout = qt.QVBoxLayout() self.targetFiducialsSelector = slicer.qMRMLNodeComboBox() self.targetFiducialsSelector.nodeTypes = (( "vtkMRMLMarkupsFiducialNode"), "") self.targetFiducialsSelector.selectNodeUponCreation = True self.targetFiducialsSelector.addEnabled = True self.targetFiducialsSelector.removeEnabled = True self.targetFiducialsSelector.noneEnabled = True self.targetFiducialsSelector.showHidden = False self.targetFiducialsSelector.showChildNodeTypes = False self.targetFiducialsSelector.setMRMLScene(slicer.mrmlScene) self.targetFiducialsSelector.setToolTip("Select Markups for targets") distanceLayout.addWidget(self.targetFiducialsSelector) self.targetFiducialsNode = None self.tagDestinationDispNode = None self.targetFiducialsSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.onTargetFiducialsSelected) self.fiducialsTable = qt.QTableWidget(1, 3) self.fiducialsTable.setSelectionBehavior( qt.QAbstractItemView.SelectRows) self.fiducialsTable.setSelectionMode( qt.QAbstractItemView.SingleSelection) self.fiducialsTableHeaders = ["Name", "Position (mm)", "Distance (mm)"] self.fiducialsTable.setHorizontalHeaderLabels( self.fiducialsTableHeaders) self.fiducialsTable.horizontalHeader().setStretchLastSection(True) distanceLayout.addWidget(self.fiducialsTable) self.extrapolateCheckBox = qt.QCheckBox() self.extrapolateCheckBox.checked = 0 self.extrapolateCheckBox.setToolTip( "Extrapolate the first and last segment to calculate the distance") self.extrapolateCheckBox.connect('toggled(bool)', self.updateTargetFiducialsTable) self.extrapolateCheckBox.text = 'Extrapolate curves to measure the distances' self.showErrorVectorCheckBox = qt.QCheckBox() self.showErrorVectorCheckBox.checked = 0 self.showErrorVectorCheckBox.setToolTip( "Show error vectors, which is defined by the target point and the closest point on the curve. The vector is perpendicular to the curve, unless the closest point is one end of the curve." ) self.showErrorVectorCheckBox.connect('toggled(bool)', self.updateTargetFiducialsTable) self.showErrorVectorCheckBox.text = 'Show error vectors' distanceLayout.addWidget(self.extrapolateCheckBox) distanceLayout.addWidget(self.showErrorVectorCheckBox) distanceFormLayout.addRow("Distance from:", distanceLayout) # # Curvature Area # curvatureCollapsibleButton = ctk.ctkCollapsibleButton() curvatureCollapsibleButton.text = "Curvature" curvatureCollapsibleButton.collapsed = True self.layout.addWidget(curvatureCollapsibleButton) curvatureFormLayout = qt.QFormLayout(curvatureCollapsibleButton) #-- Curvature self.curvatureLayout = qt.QHBoxLayout() self.curvatureOff = qt.QRadioButton("Off") self.curvatureOff.connect('clicked(bool)', self.onCurvatureOff) self.curvatureOn = qt.QRadioButton("On") self.curvatureOn.connect('clicked(bool)', self.onCurvatureOn) self.curvatureLayout.addWidget(self.curvatureOff) self.curvatureLayout.addWidget(self.curvatureOn) self.curvatureGroup = qt.QButtonGroup() self.curvatureGroup.addButton(self.curvatureOff) self.curvatureGroup.addButton(self.curvatureOn) curvatureFormLayout.addRow("Curvature mode:", self.curvatureLayout) autoCurvatureRangeFormLayout = qt.QFormLayout( curvatureCollapsibleButton) self.autoCurvatureRangeLayout = qt.QHBoxLayout() self.autoCurvatureRangeOff = qt.QRadioButton("Manual") self.autoCurvatureRangeOff.connect('clicked(bool)', self.onAutoCurvatureRangeOff) self.autoCurvatureRangeOn = qt.QRadioButton("Auto") self.autoCurvatureRangeOn.connect('clicked(bool)', self.onAutoCurvatureRangeOn) self.autoCurvatureRangeLayout.addWidget(self.autoCurvatureRangeOff) self.autoCurvatureRangeLayout.addWidget(self.autoCurvatureRangeOn) self.autoCurvatureRangeGroup = qt.QButtonGroup() self.autoCurvatureRangeGroup.addButton(self.autoCurvatureRangeOff) self.autoCurvatureRangeGroup.addButton(self.autoCurvatureRangeOn) curvatureFormLayout.addRow("Color range:", self.autoCurvatureRangeLayout) #-- Color range self.curvatureColorRangeWidget = ctk.ctkRangeWidget() self.curvatureColorRangeWidget.setToolTip("Set color range") self.curvatureColorRangeWidget.setDecimals(3) self.curvatureColorRangeWidget.singleStep = 0.001 self.curvatureColorRangeWidget.minimumValue = 0.0 self.curvatureColorRangeWidget.maximumValue = 0.5 self.curvatureColorRangeWidget.minimum = 0.0 self.curvatureColorRangeWidget.maximum = 1.0 curvatureFormLayout.addRow("Color range: ", self.curvatureColorRangeWidget) self.curvatureColorRangeWidget.connect( 'valuesChanged(double, double)', self.onUpdateCurvatureColorRange) #-- Curvature data self.meanCurvatureLineEdit = qt.QLineEdit() self.meanCurvatureLineEdit.text = '--' self.meanCurvatureLineEdit.readOnly = True self.meanCurvatureLineEdit.frame = True self.meanCurvatureLineEdit.styleSheet = "QLineEdit { background:transparent; }" self.meanCurvatureLineEdit.cursor = qt.QCursor(qt.Qt.IBeamCursor) self.meanCurvatureLineEdit.enabled = False curvatureFormLayout.addRow("Mean (mm^-1):", self.meanCurvatureLineEdit) self.minCurvatureLineEdit = qt.QLineEdit() self.minCurvatureLineEdit.text = '--' self.minCurvatureLineEdit.readOnly = True self.minCurvatureLineEdit.frame = True self.minCurvatureLineEdit.styleSheet = "QLineEdit { background:transparent; }" self.minCurvatureLineEdit.cursor = qt.QCursor(qt.Qt.IBeamCursor) self.minCurvatureLineEdit.enabled = False curvatureFormLayout.addRow("Minimum (mm^-1):", self.minCurvatureLineEdit) self.maxCurvatureLineEdit = qt.QLineEdit() self.maxCurvatureLineEdit.text = '--' self.maxCurvatureLineEdit.readOnly = True self.maxCurvatureLineEdit.frame = True self.maxCurvatureLineEdit.styleSheet = "QLineEdit { background:transparent; }" self.maxCurvatureLineEdit.cursor = qt.QCursor(qt.Qt.IBeamCursor) self.maxCurvatureLineEdit.enabled = False curvatureFormLayout.addRow("Maximum (mm^-1):", self.maxCurvatureLineEdit) ## Create a scale for curvature self.scalarBarWidget = vtk.vtkScalarBarWidget() actor = self.scalarBarWidget.GetScalarBarActor() actor.SetOrientationToVertical() actor.SetNumberOfLabels(11) actor.SetTitle("Curvature (mm^-1)") actor.SetLabelFormat(" %#8.3f") actor.SetPosition(0.1, 0.1) actor.SetWidth(0.1) actor.SetHeight(0.8) self.scalarBarWidget.SetEnabled(0) layout = slicer.app.layoutManager() view = layout.threeDWidget(0).threeDView() renderer = layout.activeThreeDRenderer() self.scalarBarWidget.SetInteractor( renderer.GetRenderWindow().GetInteractor()) self.lookupTable = vtk.vtkLookupTable() self.lookupTable.SetRange(0.0, 100.0) self.scalarBarWidget.GetScalarBarActor().SetLookupTable( self.lookupTable) ## default curvature mode: off self.curvatureOff.setChecked(True) self.onCurvatureOff(True) self.autoCurvatureRangeOff.setChecked(True) self.onAutoCurvatureRangeOff(True) # Add vertical spacer self.layout.addStretch(1)
def setup(self): self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged) w = qt.QWidget() layout = qt.QGridLayout() w.setLayout(layout) self.layout.addWidget(w) w.show() self.layout = layout # create frames self.inputFrame = ctk.ctkCollapsibleButton() self.inputFrame.text = "Input" self.inputFrame.collapsed = 0 inputFrameLayout = qt.QFormLayout(self.inputFrame) self.layout.addWidget(self.inputFrame) self.ctrlFrame = ctk.ctkCollapsibleButton() self.ctrlFrame.text = "Frame control" self.ctrlFrame.collapsed = 0 ctrlFrameLayout = qt.QGridLayout(self.ctrlFrame) self.layout.addWidget(self.ctrlFrame) self.plotFrame = ctk.ctkCollapsibleButton() self.plotFrame.text = "Plotting" self.plotFrame.collapsed = 0 plotFrameLayout = qt.QGridLayout(self.plotFrame) self.layout.addWidget(self.plotFrame) self.plotSettingsFrame = ctk.ctkCollapsibleButton() self.plotSettingsFrame.text = "Settings" self.plotSettingsFrame.collapsed = 1 plotSettingsFrameLayout = qt.QGridLayout(self.plotSettingsFrame) plotFrameLayout.addWidget(self.plotSettingsFrame, 0, 1) label = qt.QLabel('Input multivolume') self.__mvSelector = slicer.qMRMLNodeComboBox() self.__mvSelector.nodeTypes = ['vtkMRMLMultiVolumeNode'] self.__mvSelector.setMRMLScene(slicer.mrmlScene) self.__mvSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged) self.__mvSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onInputChanged) self.__mvSelector.addEnabled = 0 inputFrameLayout.addRow(label, self.__mvSelector) label = qt.QLabel('Input secondary multivolume') self.fgSelector = slicer.qMRMLNodeComboBox() self.fgSelector.nodeTypes = ['vtkMRMLMultiVolumeNode'] self.fgSelector.setMRMLScene(slicer.mrmlScene) self.fgSelector.addEnabled = 0 self.fgSelector.noneEnabled = 1 self.fgSelector.toolTip = "Secondary multivolume will be used for the secondary \ plot in interactive charting. As an example, this can be used to overlay the \ curve obtained by fitting a model to the data" inputFrameLayout.addRow(label, self.fgSelector) # TODO: initialize the slider based on the contents of the labels array # slider to scroll over metadata stored in the vector container being explored self.__mdSlider = ctk.ctkSliderWidget() label = qt.QLabel('Current frame number') # "play" control self.playButton = qt.QPushButton('Play') self.playButton.toolTip = 'Iterate over multivolume frames' self.playButton.checkable = True ctrlFrameLayout.addWidget(label, 0, 0) ctrlFrameLayout.addWidget(self.__mdSlider, 0, 1) ctrlFrameLayout.addWidget(self.playButton, 0, 2) self.playButton.connect('toggled(bool)', self.onPlayButtonToggled) self.__mdSlider.connect('valueChanged(double)', self.onSliderChanged) label = qt.QLabel('Current frame copy') self.__vfSelector = slicer.qMRMLNodeComboBox() self.__vfSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__vfSelector.setMRMLScene(slicer.mrmlScene) self.__vfSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVFMRMLSceneChanged) self.__vfSelector.addEnabled = 1 self.__vfSelector.enabled = 0 # do not show "children" of vtkMRMLScalarVolumeNode self.__vfSelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode", \ "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"] self.extractFrame = False self.extractButton = qt.QPushButton('Enable current frame copying') self.extractButton.checkable = True self.extractButton.connect('toggled(bool)', self.onExtractFrameToggled) ctrlFrameLayout.addWidget(label, 1, 0) ctrlFrameLayout.addWidget(self.__vfSelector, 1, 1, 1, 2) ctrlFrameLayout.addWidget(self.extractButton, 2, 0, 1, 3) # initialize slice observers (from DataProbe.py) # keep list of pairs: [observee,tag] so they can be removed easily self.styleObserverTags = [] # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic self.sliceWidgetsPerStyle = {} self.refreshObservers() # label map for probing label = qt.QLabel('Probed label volume') self.__fSelector = slicer.qMRMLNodeComboBox() self.__fSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__fSelector.addAttribute('vtkMRMLScalarVolumeNode', 'LabelMap', '1') self.__fSelector.toolTip = 'Label map to be probed' self.__fSelector.setMRMLScene(slicer.mrmlScene) self.__fSelector.addEnabled = 0 self.chartButton = qt.QPushButton('Chart') self.chartButton.checkable = False self.chartButton.connect('clicked()', self.onChartRequested) plotSettingsFrameLayout.addWidget(label, 0, 0) plotSettingsFrameLayout.addWidget(self.__fSelector, 0, 1) plotSettingsFrameLayout.addWidget(self.chartButton, 0, 2) self.iCharting = qt.QPushButton() self.iCharting.text = 'Enable interactive charting' self.iCharting.checkable = True plotSettingsFrameLayout.addWidget(self.iCharting, 1, 0, 1, 3) self.iCharting.setChecked(True) self.iCharting.connect('toggled(bool)', self.onInteractiveChartingChanged) groupLabel = qt.QLabel('Interactive plotting mode:') self.iChartingMode = qt.QButtonGroup() self.iChartingIntensity = qt.QRadioButton('Signal intensity') #self.iChartingIntensity.tooltip = 'Plot range adjusted dynamically to the range over the time course for the selected pixel' self.iChartingIntensityFixedAxes = qt.QRadioButton( 'Fixed range intensity') #self.iChartingIntensityFixedAxes.tooltip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume" self.iChartingPercent = qt.QRadioButton('Percent change') #self.iChartingPercent.tooltip = 'Percent change relative to the average of the first N frames (parameter set below)' self.iChartingIntensity.setChecked(1) self.groupWidget = qt.QWidget() self.groupLayout = qt.QFormLayout(self.groupWidget) self.groupLayout.addRow(groupLabel) self.groupLayout.addRow(self.iChartingIntensity) self.groupLayout.addRow(self.iChartingIntensityFixedAxes) self.groupLayout.addRow(self.iChartingPercent) self.baselineFrames = qt.QSpinBox() self.baselineFrames.minimum = 1 label = qt.QLabel('Number of frames for baseline calculation') self.groupLayout.addRow(label, self.baselineFrames) self.xLogScaleCheckBox = qt.QCheckBox() self.xLogScaleCheckBox.setChecked(0) label = qt.QLabel('Use log scale for X axis') self.groupLayout.addRow(self.xLogScaleCheckBox, label) self.xLogScaleCheckBox.connect('stateChanged(int)', self.onXLogScaleRequested) self.yLogScaleCheckBox = qt.QCheckBox() self.yLogScaleCheckBox.setChecked(0) label = qt.QLabel('Use log scale for Y axis') self.groupLayout.addRow(self.yLogScaleCheckBox, label) self.yLogScaleCheckBox.connect('stateChanged(int)', self.onYLogScaleRequested) plotSettingsFrameLayout.addWidget(self.groupWidget, 2, 0) # add chart container widget self.__chartView = ctk.ctkVTKChartView(w) plotFrameLayout.addWidget(self.__chartView, 3, 0, 1, 3) self.__chart = self.__chartView.chart() self.__chartTable = vtk.vtkTable() self.__xArray = vtk.vtkFloatArray() self.__yArray = vtk.vtkFloatArray() # will crash if there is no name self.__xArray.SetName('') self.__yArray.SetName('signal intensity') self.__chartTable.AddColumn(self.__xArray) self.__chartTable.AddColumn(self.__yArray)
def setupFeaturePanelList(self): featurePanelList = self.createFeaturePanels() self.collapsibleButtonGroup = qt.QButtonGroup() for panel in featurePanelList: self.collapsibleButtonGroup.addButton(panel)
def setup(self): """This is called one time when the module GUI is initialized """ ScriptedLoadableModuleWidget.setup(self) # Create objects that can be used anywhere in the module. Example: in most cases there should be just one # object of the logic class self.logic = CIP_PAARatioLogic() # # Create all the widgets. Example Area mainAreaCollapsibleButton = ctk.ctkCollapsibleButton() mainAreaCollapsibleButton.text = "Main parameters" self.layout.addWidget(mainAreaCollapsibleButton) self.mainAreaLayout = qt.QGridLayout(mainAreaCollapsibleButton) self.label = qt.QLabel("Select the volume") self.label.setStyleSheet("margin:10px 0 20px 7px") self.mainAreaLayout.addWidget(self.label, 0, 0) self.volumeSelector = slicer.qMRMLNodeComboBox() self.volumeSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "") # DEPRECATED. Now there is a new vtkMRMLLabelMapNode #self.volumeSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", "0" ) # No labelmaps self.volumeSelector.selectNodeUponCreation = True self.volumeSelector.autoFillBackground = True self.volumeSelector.addEnabled = True self.volumeSelector.noneEnabled = False self.volumeSelector.removeEnabled = False self.volumeSelector.showHidden = False self.volumeSelector.showChildNodeTypes = False self.volumeSelector.setMRMLScene(slicer.mrmlScene) self.volumeSelector.setStyleSheet( "margin:0px 0 0px 0; padding:2px 0 2px 5px") self.mainAreaLayout.addWidget(self.volumeSelector, 0, 1) # self.label2 = qt.QLabel("Select the slice") # self.label2.setStyleSheet("margin:0px 0 20px 7px; padding-top:20px") # self.mainAreaLayout.addWidget(self.label2, 1, 0) self.placeDefaultRulersButton = ctk.ctkPushButton() self.placeDefaultRulersButton.text = "Place default rulers" # self.placeDefaultRulersSliceButton.toolTip = "Navigate to the best estimated slice to place the rulers" self.placeDefaultRulersButton.setIcon( qt.QIcon("{0}/next.png".format(SlicerUtil.CIP_ICON_DIR))) self.placeDefaultRulersButton.setIconSize(qt.QSize(20, 20)) self.placeDefaultRulersButton.setStyleSheet("font-weight: bold;") # self.placeDefaultRulersButton.setFixedWidth(140) self.mainAreaLayout.addWidget(self.placeDefaultRulersButton, 1, 1) ### Structure Selector self.structuresGroupbox = qt.QGroupBox("Select the structure") self.groupboxLayout = qt.QVBoxLayout() self.structuresGroupbox.setLayout(self.groupboxLayout) self.mainAreaLayout.addWidget(self.structuresGroupbox, 2, 0) self.structuresButtonGroup = qt.QButtonGroup() # btn = qt.QRadioButton("None") # btn.visible = False # self.structuresButtonGroup.addButton(btn) # self.groupboxLayout.addWidget(btn) btn = qt.QRadioButton("Both") btn.checked = True self.structuresButtonGroup.addButton(btn, 0) self.groupboxLayout.addWidget(btn) btn = qt.QRadioButton("Pulmonary Arterial") self.structuresButtonGroup.addButton(btn, 1) self.groupboxLayout.addWidget(btn) btn = qt.QRadioButton("Aorta") self.structuresButtonGroup.addButton(btn, 2) self.groupboxLayout.addWidget(btn) ### Buttons toolbox self.buttonsToolboxFrame = qt.QFrame() self.buttonsToolboxLayout = qt.QGridLayout() self.buttonsToolboxFrame.setLayout(self.buttonsToolboxLayout) self.mainAreaLayout.addWidget(self.buttonsToolboxFrame, 2, 1) self.placeRulersButton = ctk.ctkPushButton() self.placeRulersButton.text = "Place ruler/s" self.placeRulersButton.toolTip = "Place the ruler/s for the selected structure/s in the current slice" self.placeRulersButton.setIcon( qt.QIcon("{0}/ruler.png".format(SlicerUtil.CIP_ICON_DIR))) self.placeRulersButton.setIconSize(qt.QSize(20, 20)) self.placeRulersButton.setFixedWidth(105) self.placeRulersButton.setStyleSheet("font-weight:bold") self.buttonsToolboxLayout.addWidget(self.placeRulersButton, 0, 0) self.moveUpButton = ctk.ctkPushButton() self.moveUpButton.text = "Move up" self.moveUpButton.toolTip = "Move the selected ruler/s one slice up" self.moveUpButton.setIcon( qt.QIcon("{0}/move_up.png".format(SlicerUtil.CIP_ICON_DIR))) self.moveUpButton.setIconSize(qt.QSize(20, 20)) self.moveUpButton.setFixedWidth(95) self.buttonsToolboxLayout.addWidget(self.moveUpButton, 0, 1) self.moveDownButton = ctk.ctkPushButton() self.moveDownButton.text = "Move down" self.moveDownButton.toolTip = "Move the selected ruler/s one slice down" self.moveDownButton.setIcon( qt.QIcon("{0}/move_down.png".format(SlicerUtil.CIP_ICON_DIR))) self.moveDownButton.setIconSize(qt.QSize(20, 20)) self.moveDownButton.setFixedWidth(95) self.buttonsToolboxLayout.addWidget(self.moveDownButton, 0, 2) self.removeButton = ctk.ctkPushButton() self.removeButton.text = "Remove ALL rulers" self.removeButton.toolTip = "Remove all the rulers for this volume" self.removeButton.setIcon( qt.QIcon("{0}/delete.png".format(SlicerUtil.CIP_ICON_DIR))) self.removeButton.setIconSize(qt.QSize(20, 20)) self.buttonsToolboxLayout.addWidget(self.removeButton, 1, 1, 1, 2, 2) ### Textboxes self.textboxesFrame = qt.QFrame() self.textboxesLayout = qt.QFormLayout() self.textboxesFrame.setLayout(self.textboxesLayout) self.textboxesFrame.setFixedWidth(190) self.mainAreaLayout.addWidget(self.textboxesFrame, 3, 0) self.paTextBox = qt.QLineEdit() self.paTextBox.setReadOnly(True) self.textboxesLayout.addRow("PA (mm): ", self.paTextBox) self.aortaTextBox = qt.QLineEdit() self.aortaTextBox.setReadOnly(True) self.textboxesLayout.addRow("Aorta (mm): ", self.aortaTextBox) self.ratioTextBox = qt.QLineEdit() self.ratioTextBox.setReadOnly(True) self.textboxesLayout.addRow("Ratio PA/A: ", self.ratioTextBox) # Save case data self.reportsCollapsibleButton = ctk.ctkCollapsibleButton() self.reportsCollapsibleButton.text = "Reporting" self.layout.addWidget(self.reportsCollapsibleButton) self.reportsLayout = qt.QHBoxLayout(self.reportsCollapsibleButton) self.storedColumnNames = [ "caseId", "paDiameter_mm", "aortaDiameter_mm", "pa1r", "pa1a", "pa1s", "pa2r", "pa2a", "pa2s", "a1r", "a1a", "a1s", "a2r", "a2a", "a2s" ] self.reportsWidget = CaseReportsWidget( "CIP_PAARatio", columnNames=self.storedColumnNames, parentWidget=self.reportsCollapsibleButton) self.reportsWidget.setup() self.switchToRedView() ##### # Case navigator if SlicerUtil.isSlicerACILLoaded(): caseNavigatorAreaCollapsibleButton = ctk.ctkCollapsibleButton() caseNavigatorAreaCollapsibleButton.text = "Case navigator" self.layout.addWidget(caseNavigatorAreaCollapsibleButton, 0x0020) # caseNavigatorLayout = qt.QVBoxLayout(caseNavigatorAreaCollapsibleButton) # Add a case list navigator from ACIL.ui import CaseNavigatorWidget self.caseNavigatorWidget = CaseNavigatorWidget( self.moduleName, caseNavigatorAreaCollapsibleButton) self.caseNavigatorWidget.setup() self.layout.addStretch() # Connections self.observers = [] self.__addSceneObservables__() self.volumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onVolumeSelectorChanged) self.placeDefaultRulersButton.connect('clicked()', self.oPlaceDefaultRulersClicked) self.placeRulersButton.connect('clicked()', self.onPlaceRulersClicked) self.moveUpButton.connect('clicked()', self.onMoveUpRulerClicked) self.moveDownButton.connect('clicked()', self.onMoveDownRulerClicked) self.removeButton.connect('clicked()', self.onRemoveRulerClicked) self.reportsWidget.addObservable( self.reportsWidget.EVENT_SAVE_BUTTON_CLICKED, self.onSaveReport)