def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = True self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Volume: ", self.inputSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLModelNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip("Pick the model to the algorithm.") parametersFormLayout.addRow("Output Model: ", self.outputSelector) # # threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 0.1 self.imageThresholdSliderWidget.minimum = -100 self.imageThresholdSliderWidget.maximum = 100 self.imageThresholdSliderWidget.value = 0.5 self.imageThresholdSliderWidget.setToolTip( "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero." ) parametersFormLayout.addRow("Image threshold", self.imageThresholdSliderWidget) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("Enable auto-update") parametersFormLayout.addRow("Auto-update", self.enableScreenshotsFlagCheckBox) self.observedMarkupNode = None self.markupsObserverTag = None self.enableScreenshotsFlagCheckBox.connect("toggled(bool)", self.onEnableAutoUpdate) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) self.centreOfMassValueLabel = qt.QLabel() parametersFormLayout.addRow("Center of mass", self.centreOfMassValueLabel) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # This module is often used in developer mode, therefore # collapse reload & test section by default. if hasattr(self, "reloadCollapsibleButton"): self.reloadCollapsibleButton.collapsed = True self.dragAndDropEventFilter = DICOMLoadingByDragAndDropEventFilter() globals()['d'] = self self.testingServer = None self.browserWidget = None self.directoryButton = None # Load widget from .ui file (created by Qt Designer) uiWidget = slicer.util.loadUI(self.resourcePath('UI/DICOM.ui')) self.layout.addWidget(uiWidget) self.ui = slicer.util.childWidgetVariables(uiWidget) self.browserWidget = DICOMLib.SlicerDICOMBrowser() self.browserWidget.objectName = 'SlicerDICOMBrowser' slicer.modules.DICOMInstance.setBrowserWidgetInDICOMLayout( self.browserWidget) layoutManager = slicer.app.layoutManager() if layoutManager is not None: layoutManager.layoutChanged.connect(self.onLayoutChanged) viewArrangement = slicer.app.layoutManager().layoutLogic( ).GetLayoutNode().GetViewArrangement() self.ui.showBrowserButton.checked = ( viewArrangement == slicer.vtkMRMLLayoutNode.SlicerLayoutDicomBrowserView) # connect to the 'Show DICOM Browser' button self.ui.showBrowserButton.connect('clicked()', self.toggleBrowserWidget) self.ui.importButton.connect('clicked()', self.importFolder) self.ui.subjectHierarchyTree.setMRMLScene(slicer.mrmlScene) self.ui.subjectHierarchyTree.currentItemChanged.connect( self.onCurrentItemChanged) self.ui.subjectHierarchyTree.currentItemModified.connect( self.onCurrentItemModified) self.subjectHierarchyCurrentVisibility = False self.ui.subjectHierarchyTree.setColumnHidden( self.ui.subjectHierarchyTree.model().idColumn, True) # # DICOM networking # self.ui.networkingFrame.collapsed = True self.ui.queryServerButton.connect('clicked()', self.browserWidget.dicomBrowser, "openQueryDialog()") self.ui.toggleListener.connect('toggled(bool)', self.onToggleListener) settings = qt.QSettings() self.ui.runListenerAtStart.checked = settingsValue( 'DICOM/RunListenerAtStart', False, converter=toBool) self.ui.runListenerAtStart.connect('toggled(bool)', self.onRunListenerAtStart) # Testing server - not exposed (used for development) self.toggleServer = qt.QPushButton("Start Testing Server") self.ui.networkingFrame.layout().addWidget(self.toggleServer) self.toggleServer.connect('clicked()', self.onToggleServer) self.verboseServer = qt.QCheckBox("Verbose") self.ui.networkingFrame.layout().addWidget(self.verboseServer) # advanced options - not exposed to end users # developers can uncomment these lines to access testing server self.toggleServer.hide() self.verboseServer.hide() # # Browser settings # self.ui.browserSettingsFrame.collapsed = True self.updateDatabaseDirectoryFromBrowser( self.browserWidget.dicomBrowser.databaseDirectory) # Synchronize database selection between browser and this widget self.ui.directoryButton.directoryChanged.connect( self.updateDatabaseDirectoryFromWidget) self.browserWidget.dicomBrowser.databaseDirectoryChanged.connect( self.updateDatabaseDirectoryFromBrowser) self.ui.browserAutoHideCheckBox.checked = not settingsValue( 'DICOM/BrowserPersistent', False, converter=toBool) self.ui.browserAutoHideCheckBox.stateChanged.connect( self.onBrowserAutoHideStateChanged) self.ui.repairDatabaseButton.connect('clicked()', self.browserWidget.dicomBrowser, "onRepairAction()") self.ui.clearDatabaseButton.connect('clicked()', self.onClearDatabase) # connect to the main window's dicom button mw = slicer.util.mainWindow() if mw: try: action = slicer.util.findChildren(mw, name='LoadDICOMAction')[0] action.connect('triggered()', self.onOpenBrowserWidget) except IndexError: logging.error( 'Could not connect to the main window DICOM button') self.databaseRefreshRequestTimer = qt.QTimer() self.databaseRefreshRequestTimer.setSingleShot(True) # If not receiving new file for 2 seconds then a database update is triggered. self.databaseRefreshRequestTimer.setInterval(2000) self.databaseRefreshRequestTimer.connect('timeout()', self.requestDatabaseRefresh)
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) self.inputDirectory = ctk.ctkPathLineEdit() self.inputDirectory.filters = ctk.ctkPathLineEdit.Dirs self.inputDirectory.setToolTip("Select directory containing volumes") parametersFormLayout.addRow("Input directory: ", self.inputDirectory) # Select output directory self.outputDirectory = ctk.ctkPathLineEdit() self.outputDirectory.filters = ctk.ctkPathLineEdit.Dirs self.outputDirectory.setToolTip("Select directory for output models: ") parametersFormLayout.addRow("Output directory: ", self.outputDirectory) # # Select the extension type # self.extensionOptionGZ = qt.QRadioButton(".nii.gz") self.extensionOptionGZ.setChecked(True) parametersFormLayout.addRow("Select extension type: ", self.extensionOptionGZ) # # set threshold value # self.threshold = ctk.ctkDoubleSpinBox() self.threshold.singleStep = 1 self.threshold.minimum = 0 self.threshold.maximum = 100000 self.threshold.setDecimals(0) self.threshold.value = 500 self.threshold.setToolTip( "Select threshold for segmentation of volume") parametersFormLayout.addRow("Threshold for segmentation:", self.threshold) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Generate VolumeToModels." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # connections self.inputDirectory.connect('validInputChanged(bool)', self.onSelectInput) self.outputDirectory.connect('validInputChanged(bool)', self.onSelectOutput) self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
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) # Generate Scene Button self.generateSceneButton = qt.QPushButton('Generate Scene') self.generateSceneButton.connect('clicked(bool)', self.onGenerateSceneButtonClicked) #self.generateSceneButton.setDisabled(True) parametersFormLayout.addRow(self.generateSceneButton) # Toggle DRR Button self.toggleDRRButton = qt.QCheckBox() self.toggleDRRButton.connect('toggled(bool)', self.onToggleDRRButtonClicked) parametersFormLayout.addRow("Toggle DRR", self.toggleDRRButton) # Toggle VR Button - TO DO self.toggleVRButton = qt.QCheckBox() self.toggleVRButton.connect('toggled(bool)', self.onToggleVRButtonClicked) parametersFormLayout.addRow("Toggle VR", self.toggleVRButton) # Transfer Function Presets self.fluoroButton = qt.QRadioButton() # parametersFormLayout.addRow("Fluoro", self.fluoroButton) # Field of View Slider self.fieldOfViewSlider = ctk.ctkSliderWidget() self.fieldOfViewSlider.singleStep = 0.1 self.fieldOfViewSlider.minimum = 0 self.fieldOfViewSlider.maximum = 60 self.fieldOfViewSlider.setToolTip("Increase/Decrease Field of View.") self.fieldOfViewSlider.connect('valueChanged(double)', self.onFieldOfViewValueChanged) parametersFormLayout.addRow("Field Of View", self.fieldOfViewSlider) # Zoom Slider self.zoomSlider = ctk.ctkSliderWidget() self.zoomSlider.singleStep = 0.1 self.zoomSlider.minimum = 0 self.zoomSlider.maximum = 50 self.zoomSlider.value = 0 self.zoomSlider.setToolTip("Zoom Factor") self.zoomSlider.connect('valueChanged(double)', self.onZoomValueChanged) parametersFormLayout.addRow("Zoom", self.zoomSlider) # C Rotation self.xRotationSliderWidget = ctk.ctkSliderWidget() self.xRotationSliderWidget.singleStep = 0.01 self.xRotationSliderWidget.minimum = -15 self.xRotationSliderWidget.maximum = 115 self.xRotationSliderWidget.value = 0.0 self.xRotationSliderWidget.setToolTip("C Rotation about the Z axis.") self.xRotationSliderWidget.connect('valueChanged(double)', self.onCRotationValuesChanged) parametersFormLayout.addRow("C Rotation", self.xRotationSliderWidget) # Gantry Rotation self.zRotationSliderWidget = ctk.ctkSliderWidget() self.zRotationSliderWidget.singleStep = 0.01 self.zRotationSliderWidget.minimum = -55 self.zRotationSliderWidget.maximum = 55 self.zRotationSliderWidget.value = 0.0 self.zRotationSliderWidget.setToolTip( "Gantry Rotation about the X axis.") self.zRotationSliderWidget.connect('valueChanged(double)', self.onGantryRotationValuesChanged) parametersFormLayout.addRow("Gantry Rotation", self.zRotationSliderWidget) # Wag Rotation self.wagRotationSliderWidget = ctk.ctkSliderWidget() self.wagRotationSliderWidget.singleStep = 0.005 self.wagRotationSliderWidget.minimum = -40 self.wagRotationSliderWidget.maximum = 40 self.wagRotationSliderWidget.value = 0.0 self.wagRotationSliderWidget.setToolTip( "Wag Rotation about the Y axis.") self.wagRotationSliderWidget.connect('valueChanged(double)', self.onWagRotationValuesChanged) parametersFormLayout.addRow("Wag Rotation", self.wagRotationSliderWidget) self.tableSliderWidget = ctk.ctkSliderWidget() self.tableSliderWidget.singleStep = 0.05 self.tableSliderWidget.minimum = -155 self.tableSliderWidget.maximum = 155 self.tableSliderWidget.value = 0.0 self.tableSliderWidget.setToolTip("Table Translation.") self.tableSliderWidget.connect('valueChanged(double)', self.onTableValuesChanged) parametersFormLayout.addRow("Table Translation", self.tableSliderWidget) # Start Module Button self.startModuleButton = qt.QPushButton('Start Module') self.startModuleButton.connect('clicked(bool)', self.onStartModuleButtonClicked) parametersFormLayout.addRow(self.startModuleButton) # Collect Image Button self.collectImageButton = qt.QPushButton('Collect Image') self.collectImageButton.connect('clicked(bool)', self.onCollectImageButtonClicked) parametersFormLayout.addRow(self.collectImageButton) # Shoot Fluoro Button self.shootFluoroButton = qt.QPushButton('ShootFluoro') self.shootFluoroButton.connect('clicked(bool)', self.onShootFluoroButtonClicked) parametersFormLayout.addRow(self.shootFluoroButton) # Create Logic Instance self.logic = CarmSimulatorLogic() # Disable All Buttons until generate scene is clicked self.toggleDRRButton.setDisabled(True) self.fieldOfViewSlider.setDisabled(True) self.toggleVRButton.setDisabled(True) self.zoomSlider.setDisabled(True) self.xRotationSliderWidget.setDisabled(True) self.zRotationSliderWidget.setDisabled(True) self.wagRotationSliderWidget.setDisabled(True) self.tableSliderWidget.setDisabled(True) self.startModuleButton.setDisabled(True) self.collectImageButton.setDisabled(True) #self.interactorObserver = slicer.modules.virtualReality self.vrInteractorObserver = 0 self.gestureObserverNum = 0 self.vrInteractor = None # Grab gesturerecognition logic instance so we can observe for events #self.gestureObserver = slicer.modules.gesturerecognition.logic() #self.useGestureRecognition = True #self.gestureObserverNum = 0 #if not self.gestureObserver: # self.useGestureRecognition = False #self.useGestureRecognition = False self.timer = qt.QTimer() self.elapsed = qt.QElapsedTimer() self.timerIteration = 0 self.movement = 1 self.direction = 0 self.timer.connect('timeout()', self.processOneThing) #self.timer.setInterval(30) self.timer.start() # Add vertical Spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # # Parameter Combobox # self.parameterSelector = slicer.qMRMLNodeComboBox() self.parameterLabel = qt.QLabel(" Parameter set: ") self.parameterSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"] self.parameterSelector.removeEnabled = False self.parameterSelector.showHidden = True self.parameterSelector.setMRMLScene( slicer.mrmlScene ) self.parameterLayout = qt.QHBoxLayout() self.parameterLayout.addWidget(self.parameterLabel) self.parameterLayout.addWidget(self.parameterSelector) self.layout.addLayout(self.parameterLayout) # # Input Area # inputCollapsibleButton = ctk.ctkCollapsibleButton() inputCollapsibleButton.text = "Input" self.layout.addWidget(inputCollapsibleButton) # Layout within the dummy collapsible button inputFormLayout = qt.QFormLayout(inputCollapsibleButton) # # Input first DVH selector # self.dvh1Selector = slicer.qMRMLNodeComboBox() self.dvh1Selector.nodeTypes = ["vtkMRMLTableNode"] self.dvh1Selector.addAttribute("vtkMRMLTableNode", "DoseVolumeHistogram.DVH") self.dvh1Selector.removeEnabled = False self.dvh1Selector.setMRMLScene( slicer.mrmlScene ) inputFormLayout.addRow("DVH 1: ", self.dvh1Selector) # # Input second DVH selector # self.dvh2Selector = slicer.qMRMLNodeComboBox() self.dvh2Selector.nodeTypes = ["vtkMRMLTableNode"] self.dvh1Selector.addAttribute("vtkMRMLTableNode", "DoseVolumeHistogram.DVH") self.dvh2Selector.removeEnabled = False self.dvh2Selector.setMRMLScene( slicer.mrmlScene ) inputFormLayout.addRow("DVH 2: ", self.dvh2Selector) # # Input the dose volume # self.doseVolumeSelector = slicer.qMRMLNodeComboBox() self.doseVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.doseVolumeSelector.addAttribute("vtkMRMLScalarVolumeNode", "DicomRtImport.DoseVolume") self.doseVolumeSelector.removeEnabled = False self.doseVolumeSelector.setMRMLScene( slicer.mrmlScene ) inputFormLayout.addRow("Dose Volume: ", self.doseVolumeSelector) # # Dose volume only check box # self.showDoseVolumeOnlyCheckbox = qt.QCheckBox("Show dose volume only") self.showDoseVolumeOnlyCheckbox.setChecked(2) inputFormLayout.addWidget(self.showDoseVolumeOnlyCheckbox) # # Volume difference criterion spin box # self.volumeDifferenceSpinbox = qt.QDoubleSpinBox() self.volumeDifferenceSpinbox.setValue(1.0) self.volumeDifferenceSpinbox.setDecimals(1) self.volumeDifferenceSpinbox.setSingleStep(0.1) inputFormLayout.addRow("Volume difference criterion: ", self.volumeDifferenceSpinbox) # # Dose to agreement criterion spin box # self.doseToAgreementSpinbox = qt.QDoubleSpinBox() self.doseToAgreementSpinbox.setValue(1.0) self.doseToAgreementSpinbox.setDecimals(1) self.doseToAgreementSpinbox.setSingleStep(0.1) inputFormLayout.addRow("Dose to agreement criterion: ", self.doseToAgreementSpinbox) # # Compute button # self.computeButton = qt.QPushButton("Compute") self.computeButtonLayout = qt.QVBoxLayout() self.computeButtonLayout.addStrut(100) self.computeButtonLayout.setAlignment(2) self.computeButtonLayout.addWidget(self.computeButton) self.computeButtonFont = qt.QFont() self.computeButtonFont.setBold(True) self.computeButton.setFont(self.computeButtonFont) inputFormLayout.addRow(self.computeButtonLayout) # # Output Area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" self.layout.addWidget(outputCollapsibleButton) # Layout within the dummy collapsible button outputFormLayout = qt.QFormLayout(outputCollapsibleButton) self.agreementAcceptanceOutput = qt.QLineEdit() self.agreementAcceptanceOutput.setReadOnly(True) outputFormLayout.addRow("Agreement acceptance %: ", self.agreementAcceptanceOutput) # # Visualize Area # visualizeCollapsibleButton = ctk.ctkCollapsibleButton() visualizeCollapsibleButton.text = "Visualize" sizePolicy = qt.QSizePolicy() sizePolicy.setHorizontalPolicy(qt.QSizePolicy.Preferred) sizePolicy.setVerticalPolicy(qt.QSizePolicy.Expanding) visualizeCollapsibleButton.setSizePolicy(sizePolicy) self.layout.addWidget(visualizeCollapsibleButton) # Layout within the dummy collapsible button visualizeLayout = qt.QVBoxLayout(visualizeCollapsibleButton) # # DVH Table # self.dvhTable = slicer.qMRMLTableView() self.dvhTable.setMRMLScene(slicer.mrmlScene) self.dvhTable.setSelectionMode(qt.QAbstractItemView.NoSelection) self.dvhTable.setSizePolicy(sizePolicy) visualizeLayout.addWidget(self.dvhTable) # Connections self.parameterSelector.connect('nodeAddedByUser(vtkMRMLNode*)', self.parameterNodeCreated) self.parameterSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.updateWidgetFromMRML) self.showDoseVolumeOnlyCheckbox.connect('stateChanged(int)', self.showDoseVolumesOnlyCheckboxChanged) self.dvh1Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.dvh1SelectorChanged) self.dvh2Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.dvh2SelectorChanged) self.doseVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.doseVolumeSelectorChanged) self.volumeDifferenceSpinbox.connect("valueChanged(double)", self.volumeDifferenceSpinboxChanged) self.doseToAgreementSpinbox.connect("valueChanged(double)", self.doseToAgreementSpinboxChanged) self.computeButton.connect('clicked(bool)', self.onComputeButton) self.updateWidgetFromMRML()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.reloadCollapsibleButton.collapsed = 1 # Instantiate and connect widgets ... # # Data selection area # self.DataCollapsibleButton = ctk.ctkCollapsibleButton() self.DataCollapsibleButton.text = "Data Selection" self.layout.addWidget(self.DataCollapsibleButton) self.DataInterfaceLayout = qt.QGridLayout(self.DataCollapsibleButton) self.DataInterfaceLayout.setHorizontalSpacing(12) # Checkbox to indicate whether to operate on all MarkupsNodes, or to select one self.ModifyAllNodesCheckBox = qt.QCheckBox() self.ModifyAllNodesCheckBox.checked = 0 self.ModifyAllNodesCheckBox.toolTip = "Check if you want to operate on all MarkupsNodes in the scene, uncheck if you want to select one" self.DataInterfaceLayout.addWidget(qt.QLabel("All Nodes?"), 0, 0, 1, 1) self.DataInterfaceLayout.addWidget(self.ModifyAllNodesCheckBox, 0, 1, 1, 1) # Single node ComboBox selector self.SingleNodeSelector = slicer.qMRMLNodeComboBox() self.SingleNodeSelector.nodeTypes = [ "vtkMRMLMarkupsFiducialNode", ] self.SingleNodeSelector.enabled = True self.SingleNodeSelector.selectNodeUponCreation = True self.SingleNodeSelector.addEnabled = False self.SingleNodeSelector.removeEnabled = False self.SingleNodeSelector.noneEnabled = True self.SingleNodeSelector.showHidden = False self.SingleNodeSelector.showChildNodeTypes = False self.SingleNodeSelector.setMRMLScene(slicer.mrmlScene) self.SingleNodeSelector.setToolTip("Pick the input to the algorithm.") self.DataInterfaceLayout.addWidget(qt.QLabel("Node selector"), 0, 2, 1, 1) self.DataInterfaceLayout.addWidget(self.SingleNodeSelector, 0, 3, 1, 1) # # Operations Interface # self.OperationsCollapsibleButton = ctk.ctkCollapsibleButton() self.OperationsCollapsibleButton.text = "Operations" self.layout.addWidget(self.OperationsCollapsibleButton) self.DataInterfaceLayout = qt.QGridLayout( self.OperationsCollapsibleButton) self.DataInterfaceLayout.setHorizontalSpacing(12) # Extrapolate button self.ExtrapolateLandmarksButton = qt.QPushButton( "Extrapolate Landmarks") self.ExtrapolateLandmarksButton.toolTip = "Extend incomplete (but gap-free) landmark set to include T1-L5" self.ExtrapolateLandmarksButton.enabled = True self.ExtrapolateLandmarksButton.checkable = True self.DataInterfaceLayout.addWidget(self.ExtrapolateLandmarksButton, 1, 1, 1, 2) # Center button self.CenterLandmarksButton = qt.QPushButton("Center Landmarks") self.CenterLandmarksButton.toolTip = "Center the landmarks about the origin (subtract average locations)" self.CenterLandmarksButton.enabled = True self.CenterLandmarksButton.checkable = True self.DataInterfaceLayout.addWidget(self.CenterLandmarksButton, 2, 1, 1, 2) # Normalize button self.NormalizeLandmarksButton = qt.QPushButton("Normalize Landmarks") self.NormalizeLandmarksButton.toolTip = "Normalize landmarks coordinate over range [0,1] (divide by largest coordinate in each node)" self.NormalizeLandmarksButton.enabled = True self.NormalizeLandmarksButton.checkable = True self.DataInterfaceLayout.addWidget(self.NormalizeLandmarksButton, 3, 1, 1, 2) # Apply Button self.PerformOperationsButton = qt.QPushButton("Perform Operations") self.PerformOperationsButton.toolTip = "Run the algorithm." self.PerformOperationsButton.enabled = False self.DataInterfaceLayout.addWidget(self.PerformOperationsButton, 4, 1, 1, 2) # # Connections # self.ModifyAllNodesCheckBox.connect('stateChanged(int)', self.OnAllNodesChecked) self.SingleNodeSelector.connect('currentNodeChanged(bool)', self.OnSelectedNodeChanged) self.PerformOperationsButton.connect('clicked(bool)', self.OnPerformOperationsButton) # # Seperate reload button # self.ReloadButton = qt.QPushButton("Reload Module") self.ReloadButton.toolTip = "Reload this module, reflecting any changes in its code" self.ReloadButton.enabled = True self.layout.addWidget(self.ReloadButton) self.ReloadButton.connect('clicked(bool)', self.OnReloadButtonClicked)
def _createSmall(self): """Make the internals of the widget to display in the Data Probe frame (lower left of slicer main window by default)""" # this method makes SliceView Annotation self.sliceAnnotations = DataProbeLib.SliceAnnotations() # goto module button self.goToModule = qt.QPushButton('->', self.frame) self.goToModule.setToolTip( 'Go to the DataProbe module for more information and options') self.frame.layout().addWidget(self.goToModule) self.goToModule.connect("clicked()", self.onGoToModule) # hide this for now - there's not much to see in the module itself self.goToModule.hide() # image view: To ensure the height of the checkbox matches the height of the # viewerFrame, it is added to a frame setting the layout and hard-coding the # content margins. # TODO: Revisit the approach and avoid hard-coding content margins self.showImageFrame = qt.QFrame(self.frame) self.frame.layout().addWidget(self.showImageFrame) self.showImageFrame.setLayout(qt.QHBoxLayout()) self.showImageFrame.layout().setContentsMargins(0, 3, 0, 3) self.showImageBox = qt.QCheckBox('Show Zoomed Slice', self.showImageFrame) self.showImageFrame.layout().addWidget(self.showImageBox) self.showImageBox.connect("toggled(bool)", self.onShowImage) self.showImageBox.setChecked(False) self.imageLabel = qt.QLabel() # qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # fails on some systems, therefore set the policies using separate method calls qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) qSize.setVerticalPolicy(qt.QSizePolicy.Expanding) self.imageLabel.setSizePolicy(qSize) #self.imageLabel.setScaledContents(True) self.frame.layout().addWidget(self.imageLabel) self.onShowImage(False) # top row - things about the viewer itself self.viewerFrame = qt.QFrame(self.frame) self.viewerFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.viewerFrame) self.viewerColor = qt.QLabel(self.viewerFrame) self.viewerFrame.layout().addWidget(self.viewerColor) self.viewInfo = qt.QLabel() self.viewerFrame.layout().addWidget(self.viewInfo) self.viewerFrame.layout().addStretch(1) def _setFixedFontFamily(widget, family='Monospace'): font = widget.font font.setFamily(family) widget.font = font _setFixedFontFamily(self.viewInfo) # the grid - things about the layers # this method makes labels self.layerGrid = qt.QFrame(self.frame) layout = qt.QGridLayout() self.layerGrid.setLayout(layout) self.frame.layout().addWidget(self.layerGrid) layers = ('L', 'F', 'B') self.layerNames = {} self.layerIJKs = {} self.layerValues = {} for (row, layer) in enumerate(layers): col = 0 layout.addWidget(qt.QLabel(layer), row, col) col += 1 self.layerNames[layer] = qt.QLabel() layout.addWidget(self.layerNames[layer], row, col) col += 1 self.layerIJKs[layer] = qt.QLabel() layout.addWidget(self.layerIJKs[layer], row, col) col += 1 self.layerValues[layer] = qt.QLabel() layout.addWidget(self.layerValues[layer], row, col) layout.setColumnStretch(col, 100) _setFixedFontFamily(self.layerNames[layer]) _setFixedFontFamily(self.layerIJKs[layer]) _setFixedFontFamily(self.layerValues[layer]) # information collected about the current crosshair position # from displayable managers registered to the current view self.displayableManagerInfo = qt.QLabel() self.displayableManagerInfo.indent = 6 self.displayableManagerInfo.wordWrap = True self.frame.layout().addWidget(self.displayableManagerInfo) # only show if not empty self.displayableManagerInfo.hide() # goto module button self.goToModule = qt.QPushButton('->', self.frame) self.goToModule.setToolTip( 'Go to the DataProbe module for more information and options') self.frame.layout().addWidget(self.goToModule) self.goToModule.connect("clicked()", self.onGoToModule) # hide this for now - there's not much to see in the module itself self.goToModule.hide()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = ElastixLogic() self.logic.logCallback = self.addLog self.registrationInProgress = False # Instantiate and connect widgets ... # Parameter sets defaultinputParametersCollapsibleButton = ctk.ctkCollapsibleButton() defaultinputParametersCollapsibleButton.text = "Parameter set" defaultinputParametersCollapsibleButton.collapsed = True self.layout.addWidget(defaultinputParametersCollapsibleButton) defaultParametersLayout = qt.QFormLayout( defaultinputParametersCollapsibleButton) self.parameterNodeSelector = slicer.qMRMLNodeComboBox() self.parameterNodeSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"] self.parameterNodeSelector.addAttribute("vtkMRMLScriptedModuleNode", "ModuleName", "Elastix") self.parameterNodeSelector.selectNodeUponCreation = True self.parameterNodeSelector.addEnabled = True self.parameterNodeSelector.renameEnabled = True self.parameterNodeSelector.removeEnabled = True self.parameterNodeSelector.noneEnabled = False self.parameterNodeSelector.showHidden = True self.parameterNodeSelector.showChildNodeTypes = False self.parameterNodeSelector.baseName = "General Registration (Elastix)" self.parameterNodeSelector.setMRMLScene(slicer.mrmlScene) self.parameterNodeSelector.setToolTip("Pick parameter set") defaultParametersLayout.addRow("Parameter set: ", self.parameterNodeSelector) # # Inputs # inputParametersCollapsibleButton = ctk.ctkCollapsibleButton() inputParametersCollapsibleButton.text = "Inputs" self.layout.addWidget(inputParametersCollapsibleButton) # Layout within the dummy collapsible button inputParametersFormLayout = qt.QFormLayout( inputParametersCollapsibleButton) # # fixed volume selector # self.fixedVolumeSelector = slicer.qMRMLNodeComboBox() self.fixedVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.fixedVolumeSelector.selectNodeUponCreation = True self.fixedVolumeSelector.addEnabled = False self.fixedVolumeSelector.removeEnabled = False self.fixedVolumeSelector.noneEnabled = False self.fixedVolumeSelector.showHidden = False self.fixedVolumeSelector.showChildNodeTypes = False self.fixedVolumeSelector.setMRMLScene(slicer.mrmlScene) self.fixedVolumeSelector.setToolTip( "The moving volume will be transformed into this image space.") inputParametersFormLayout.addRow("Fixed volume: ", self.fixedVolumeSelector) # # moving volume selector # self.movingVolumeSelector = slicer.qMRMLNodeComboBox() self.movingVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.movingVolumeSelector.selectNodeUponCreation = True self.movingVolumeSelector.addEnabled = False self.movingVolumeSelector.removeEnabled = False self.movingVolumeSelector.noneEnabled = False self.movingVolumeSelector.showHidden = False self.movingVolumeSelector.showChildNodeTypes = False self.movingVolumeSelector.setMRMLScene(slicer.mrmlScene) self.movingVolumeSelector.setToolTip( "This volume will be transformed into the fixed image space") inputParametersFormLayout.addRow("Moving volume: ", self.movingVolumeSelector) self.registrationPresetSelector = qt.QComboBox() for preset in self.logic.getRegistrationPresets(): self.registrationPresetSelector.addItem("{0} ({1})".format( preset[RegistrationPresets_Modality], preset[RegistrationPresets_Content])) inputParametersFormLayout.addRow("Preset: ", self.registrationPresetSelector) # # Outputs # maskingParametersCollapsibleButton = ctk.ctkCollapsibleButton() maskingParametersCollapsibleButton.text = "Masking" maskingParametersCollapsibleButton.collapsed = True self.layout.addWidget(maskingParametersCollapsibleButton) # Layout within the dummy collapsible button maskingParametersFormLayout = qt.QFormLayout( maskingParametersCollapsibleButton) # # fixed volume mask selector # self.fixedVolumeMaskSelector = slicer.qMRMLNodeComboBox() self.fixedVolumeMaskSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.fixedVolumeMaskSelector.addEnabled = False self.fixedVolumeMaskSelector.removeEnabled = False self.fixedVolumeMaskSelector.noneEnabled = True self.fixedVolumeMaskSelector.showHidden = False self.fixedVolumeMaskSelector.showChildNodeTypes = False self.fixedVolumeMaskSelector.setMRMLScene(slicer.mrmlScene) self.fixedVolumeMaskSelector.setToolTip( "Areas of the fixed volume where mask label is 0 will be ignored in the registration." ) maskingParametersFormLayout.addRow("Fixed volume mask: ", self.fixedVolumeMaskSelector) # # moving volume mask selector # self.movingVolumeMaskSelector = slicer.qMRMLNodeComboBox() self.movingVolumeMaskSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.movingVolumeMaskSelector.selectNodeUponCreation = True self.movingVolumeMaskSelector.addEnabled = False self.movingVolumeMaskSelector.removeEnabled = False self.movingVolumeMaskSelector.noneEnabled = True self.movingVolumeMaskSelector.showHidden = False self.movingVolumeMaskSelector.showChildNodeTypes = False self.movingVolumeMaskSelector.setMRMLScene(slicer.mrmlScene) self.movingVolumeMaskSelector.setToolTip( "Areas of the moving volume where mask label is 0 will be ignored in the registration" ) maskingParametersFormLayout.addRow("Moving volume mask: ", self.movingVolumeMaskSelector) # # Outputs # outputParametersCollapsibleButton = ctk.ctkCollapsibleButton() outputParametersCollapsibleButton.text = "Outputs" self.layout.addWidget(outputParametersCollapsibleButton) # Layout within the dummy collapsible button outputParametersFormLayout = qt.QFormLayout( outputParametersCollapsibleButton) # # output volume selector # self.outputVolumeSelector = slicer.qMRMLNodeComboBox() self.outputVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.outputVolumeSelector.selectNodeUponCreation = True self.outputVolumeSelector.addEnabled = True self.outputVolumeSelector.renameEnabled = True self.outputVolumeSelector.removeEnabled = True self.outputVolumeSelector.noneEnabled = True self.outputVolumeSelector.showHidden = False self.outputVolumeSelector.showChildNodeTypes = False self.outputVolumeSelector.setMRMLScene(slicer.mrmlScene) self.outputVolumeSelector.setToolTip( "(optional) The moving image warped to the fixed image space. NOTE: You must set at least one output object (transform and/or output volume)" ) outputParametersFormLayout.addRow("Output volume: ", self.outputVolumeSelector) # # output transform selector # self.outputTransformSelector = slicer.qMRMLNodeComboBox() self.outputTransformSelector.nodeTypes = ["vtkMRMLTransformNode"] self.outputTransformSelector.selectNodeUponCreation = True self.outputTransformSelector.addEnabled = True self.outputTransformSelector.renameEnabled = True self.outputTransformSelector.removeEnabled = True self.outputTransformSelector.noneEnabled = True self.outputTransformSelector.showHidden = False self.outputTransformSelector.showChildNodeTypes = False self.outputTransformSelector.setMRMLScene(slicer.mrmlScene) self.outputTransformSelector.setToolTip( "(optional) Computed displacement field that transform nodes from moving volume space to fixed volume space. NOTE: You must set at least one output object (transform and/or output volume)." ) outputParametersFormLayout.addRow("Output transform: ", self.outputTransformSelector) # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = True self.layout.addWidget(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) self.showDetailedLogDuringExecutionCheckBox = qt.QCheckBox(" ") self.showDetailedLogDuringExecutionCheckBox.checked = False self.showDetailedLogDuringExecutionCheckBox.setToolTip( "Show detailed log during registration.") advancedFormLayout.addRow("Show detailed log during registration:", self.showDetailedLogDuringExecutionCheckBox) self.keepTemporaryFilesCheckBox = qt.QCheckBox(" ") self.keepTemporaryFilesCheckBox.checked = False self.keepTemporaryFilesCheckBox.setToolTip( "Keep temporary files (inputs, computed outputs, logs) after the registration is completed." ) self.showTemporaryFilesFolderButton = qt.QPushButton( "Show temp folder") self.showTemporaryFilesFolderButton.toolTip = "Open the folder where temporary files are stored." self.showTemporaryFilesFolderButton.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) hbox = qt.QHBoxLayout() hbox.addWidget(self.keepTemporaryFilesCheckBox) hbox.addWidget(self.showTemporaryFilesFolderButton) advancedFormLayout.addRow("Keep temporary files:", hbox) self.showRegistrationParametersDatabaseFolderButton = qt.QPushButton( "Show database folder") self.showRegistrationParametersDatabaseFolderButton.toolTip = "Open the folder where temporary files are stored." self.showRegistrationParametersDatabaseFolderButton.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) advancedFormLayout.addRow( "Registration presets:", self.showRegistrationParametersDatabaseFolderButton) customElastixBinDir = self.logic.getCustomElastixBinDir() self.customElastixBinDirSelector = ctk.ctkPathLineEdit() self.customElastixBinDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.customElastixBinDirSelector.setCurrentPath(customElastixBinDir) self.customElastixBinDirSelector.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) self.customElastixBinDirSelector.setToolTip( "Set bin directory of an Elastix installation (where elastix executable is located). " "If value is empty then default elastix (bundled with SlicerElastix extension) will be used." ) advancedFormLayout.addRow("Custom Elastix toolbox location:", self.customElastixBinDirSelector) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False self.layout.addWidget(self.applyButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) self.statusLabel.setCenterOnScroll(True) self.layout.addWidget(self.statusLabel) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.showTemporaryFilesFolderButton.connect( 'clicked(bool)', self.onShowTemporaryFilesFolder) self.showRegistrationParametersDatabaseFolderButton.connect( 'clicked(bool)', self.onShowRegistrationParametersDatabaseFolder) self.fixedVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.movingVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputTransformSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Immediately update deleteTemporaryFiles in the logic to make it possible to decide to # keep the temporary file while the registration is running self.keepTemporaryFilesCheckBox.connect( "toggled(bool)", self.onKeepTemporaryFilesToggled) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # File area # filesCollapsibleButton = ctk.ctkCollapsibleButton() filesCollapsibleButton.text = "Input files" filesCollapsibleButton.collapsed = False self.layout.addWidget(filesCollapsibleButton) # Layout within the files collapsible button filesFormLayout = qt.QFormLayout(filesCollapsibleButton) # select one file buttonLayout = qt.QHBoxLayout() self.archetypeText = qt.QLineEdit() buttonLayout.addWidget(self.archetypeText) self.addFromArchetype = qt.QPushButton("Browse...") buttonLayout.addWidget(self.addFromArchetype) self.archetypeStartNumber = 0 filesFormLayout.addRow("Filename pattern: ", buttonLayout) # file list group fileListGroupBox = ctk.ctkCollapsibleGroupBox() fileListGroupBox.title = "File list" fileListLayout = qt.QVBoxLayout() fileListGroupBox.setLayout(fileListLayout) filesFormLayout.addRow("", fileListGroupBox) self.addByBrowsingButton = qt.QPushButton("Select files...") fileListLayout.addWidget(self.addByBrowsingButton) self.fileTable = qt.QTextBrowser() fileListLayout.addWidget(self.fileTable) fileListGroupBox.collapsed = True # original volume size self.originalVolumeSizeLabel = qt.QLabel() filesFormLayout.addRow("Size: ", self.originalVolumeSizeLabel) # reverse slice order self.reverseCheckBox = qt.QCheckBox() self.reverseCheckBox.toolTip = "Read the images in reverse order (flips loaded volume along IS axis)" filesFormLayout.addRow("Reverse: ", self.reverseCheckBox) # original spacing self.spacingWidget = slicer.qMRMLCoordinatesWidget() self.spacingWidget.setMRMLScene(slicer.mrmlScene) self.spacingWidget.decimalsOption = ctk.ctkDoubleSpinBox.DecimalsByKey | ctk.ctkDoubleSpinBox.DecimalsByShortcuts | ctk.ctkDoubleSpinBox.DecimalsByValue self.spacingWidget.minimum = 0.0 self.spacingWidget.maximum = 1000000000.0 self.spacingWidget.quantity = "length" self.spacingWidget.unitAwareProperties = slicer.qMRMLCoordinatesWidget.Precision | slicer.qMRMLCoordinatesWidget.Prefix | slicer.qMRMLCoordinatesWidget.Scaling | slicer.qMRMLCoordinatesWidget.Suffix self.spacingWidget.coordinates = "1,1,1" self.spacingWidget.toolTip = "Set the colunm, row, slice spacing; original spacing not including downsample" filesFormLayout.addRow("Spacing: ", self.spacingWidget) # # output area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" outputCollapsibleButton.collapsed = False self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = [ "vtkMRMLScalarVolumeNode", "vtkMRMLVectorVolumeNode" ] self.outputSelector.showChildNodeTypes = False self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.selectNodeUponCreation = True self.outputSelector.noneEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.renameEnabled = True self.outputSelector.addEnabled = True self.outputSelector.noneDisplay = "(Create new volume)" self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip( "Pick the output volume to populate or None to autogenerate.") outputFormLayout.addRow("Output Volume: ", self.outputSelector) # # output ROI selector # self.outputROISelector = slicer.qMRMLNodeComboBox() self.outputROISelector.nodeTypes = [ "vtkMRMLAnnotationROINode", "vtkMRMLMarkupsROINode" ] self.outputROISelector.showChildNodeTypes = False self.outputROISelector.showHidden = False self.outputROISelector.showChildNodeTypes = False self.outputROISelector.noneEnabled = True self.outputROISelector.removeEnabled = True self.outputROISelector.renameEnabled = True self.outputROISelector.addEnabled = False self.outputROISelector.noneDisplay = "(Full volume)" self.outputROISelector.setMRMLScene(slicer.mrmlScene) self.outputROISelector.setToolTip( "Set the region of the volume that will be loaded") outputFormLayout.addRow("Region of interest: ", self.outputROISelector) # # Quality selector # qualityLayout = qt.QVBoxLayout() self.qualityPreviewRadioButton = qt.QRadioButton("preview") self.qualityHalfRadioButton = qt.QRadioButton("half resolution") self.qualityFullRadioButton = qt.QRadioButton("full resolution") qualityLayout.addWidget(self.qualityPreviewRadioButton) qualityLayout.addWidget(self.qualityHalfRadioButton) qualityLayout.addWidget(self.qualityFullRadioButton) self.qualityPreviewRadioButton.setChecked(True) outputFormLayout.addRow("Quality: ", qualityLayout) self.sliceSkipSpinBox = qt.QSpinBox() self.sliceSkipSpinBox.toolTip = "Skips the selected number of slices between each pair of output volume slices (use, for example, on long thin samples with more slices than in-plane resolution)" outputFormLayout.addRow("Slice skip: ", self.sliceSkipSpinBox) # Force grayscale output self.grayscaleCheckBox = qt.QCheckBox() self.grayscaleCheckBox.toolTip = "Force reading the image in grayscale. Only makes a difference if the input has color (RGB or RGBA) voxels." self.grayscaleCheckBox.checked = True outputFormLayout.addRow("Grayscale: ", self.grayscaleCheckBox) # output volume size self.outputVolumeSizeLabel = qt.QLabel() outputFormLayout.addRow("Output size: ", self.outputVolumeSizeLabel) # output volume spacing self.outputSpacingWidget = slicer.qMRMLCoordinatesWidget() self.outputSpacingWidget.setMRMLScene(slicer.mrmlScene) self.outputSpacingWidget.readOnly = True self.outputSpacingWidget.frame = False self.outputSpacingWidget.decimalsOption = ctk.ctkDoubleSpinBox.DecimalsByKey | ctk.ctkDoubleSpinBox.DecimalsByShortcuts | ctk.ctkDoubleSpinBox.DecimalsByValue self.outputSpacingWidget.minimum = 0.0 self.outputSpacingWidget.maximum = 1000000000.0 self.outputSpacingWidget.quantity = "length" self.outputSpacingWidget.unitAwareProperties = slicer.qMRMLCoordinatesWidget.Precision | slicer.qMRMLCoordinatesWidget.Prefix | slicer.qMRMLCoordinatesWidget.Scaling | slicer.qMRMLCoordinatesWidget.Suffix self.outputSpacingWidget.coordinates = "1,1,1" self.outputSpacingWidget.toolTip = "Slice spacing of the volume that will be loaded" outputFormLayout.addRow("Output spacing: ", self.outputSpacingWidget) self.loadButton = qt.QPushButton("Load files") self.loadButton.toolTip = "Load files as a 3D volume" self.loadButton.enabled = False outputFormLayout.addRow(self.loadButton) # connections self.reverseCheckBox.connect('toggled(bool)', self.updateLogicFromWidget) self.sliceSkipSpinBox.connect("valueChanged(int)", self.updateLogicFromWidget) self.spacingWidget.connect("coordinatesChanged(double*)", self.updateLogicFromWidget) self.qualityPreviewRadioButton.connect( "toggled(bool)", lambda toggled, widget=self.qualityPreviewRadioButton: self. onQualityToggled(toggled, widget)) self.qualityHalfRadioButton.connect( "toggled(bool)", lambda toggled, widget=self.qualityHalfRadioButton: self. onQualityToggled(toggled, widget)) self.qualityFullRadioButton.connect( "toggled(bool)", lambda toggled, widget=self.qualityFullRadioButton: self. onQualityToggled(toggled, widget)) self.grayscaleCheckBox.connect('toggled(bool)', self.updateLogicFromWidget) self.outputROISelector.connect("currentNodeChanged(vtkMRMLNode*)", self.setOutputROINode) self.addByBrowsingButton.connect('clicked()', self.addByBrowsing) self.addFromArchetype.connect('clicked()', self.selectArchetype) self.archetypeText.connect('textChanged(const QString &)', self.populateFromArchetype) self.loadButton.connect('clicked()', self.onLoadButton) # Add vertical spacer self.layout.addStretch(1) self.loadButton.enabled = False
def __init__(self, logic): super(VisualizationWidget, self).__init__() self.rockCount = 0 self.rocking = False self.rockTimer = None self.flickerTimer = None self.logic = logic self.revealCursor = None self.volumes = ( "Fixed", "Moving", "Transformed", ) self.layoutOptions = ( "Axial", "Coronal", "Sagittal", "Axi/Sag/Cor", ) self.layoutOption = 'Axi/Sag/Cor' self.volumeDisplayCheckboxes = {} # mimic the structure of the LandmarksWidget for visual # consistency (it needs sub widget so it can delete and refresh the internals) self.widget = qt.QWidget() self.layout = qt.QFormLayout(self.widget) self.boxHolder = qt.QWidget() self.boxHolder.setLayout(qt.QVBoxLayout()) self.layout.addRow(self.boxHolder) self.groupBox = qt.QGroupBox("Visualization") self.groupBoxLayout = qt.QFormLayout(self.groupBox) self.boxHolder.layout().addWidget(self.groupBox) # # layout selection # layoutHolder = qt.QWidget() layout = qt.QHBoxLayout() layoutHolder.setLayout(layout) for layoutOption in self.layoutOptions: layoutButton = qt.QPushButton(layoutOption) layoutButton.connect('clicked()', lambda lo=layoutOption: self.selectLayout(lo)) layout.addWidget(layoutButton) self.groupBoxLayout.addRow("Layout", layoutHolder) # # Volume display selection # checkboxHolder = qt.QWidget() layout = qt.QHBoxLayout() checkboxHolder.setLayout(layout) for volume in self.volumes: checkBox = qt.QCheckBox() checkBox.text = volume checkBox.checked = True checkBox.connect('toggled(bool)', self.updateVisualization) layout.addWidget(checkBox) self.volumeDisplayCheckboxes[volume] = checkBox checkBox = qt.QCheckBox() checkBox.text = "RevealCursor" checkBox.checked = False checkBox.connect('toggled(bool)', self.revealToggled) layout.addWidget(checkBox) self.groupBoxLayout.addRow("Display", checkboxHolder) # # fade slider # fadeHolder = qt.QWidget() fadeLayout = qt.QHBoxLayout() fadeHolder.setLayout(fadeLayout) self.fadeSlider = ctk.ctkSliderWidget() self.fadeSlider.minimum = 0 self.fadeSlider.maximum = 1.0 self.fadeSlider.value = 0.5 self.fadeSlider.singleStep = 0.05 self.fadeSlider.connect('valueChanged(double)', self.onFadeChanged) fadeLayout.addWidget(self.fadeSlider) # # Rock and Flicker # animaHolder = qt.QWidget() animaLayout = qt.QVBoxLayout() animaHolder.setLayout(animaLayout) fadeLayout.addWidget(animaHolder) # Rock checkBox = qt.QCheckBox() checkBox.text = "Rock" checkBox.checked = False checkBox.connect('toggled(bool)', self.onRockToggled) animaLayout.addWidget(checkBox) # Flicker checkBox = qt.QCheckBox() checkBox.text = "Flicker" checkBox.checked = False checkBox.connect('toggled(bool)', self.onFlickerToggled) animaLayout.addWidget(checkBox) self.groupBoxLayout.addRow("Fade", fadeHolder) # # zoom control # zoomHolder = qt.QWidget() layout = qt.QHBoxLayout() zoomHolder.setLayout(layout) zooms = { "+": 0.7, "-": 1.3, "Fit": "Fit", } for zoomLabel, zoomFactor in zooms.items(): zoomButton = qt.QPushButton(zoomLabel) zoomButton.connect('clicked()', lambda zf=zoomFactor: self.onZoom(zf)) layout.addWidget(zoomButton) self.groupBoxLayout.addRow("Zoom", zoomHolder)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input landmark directory selector # self.inputLandmarkDirectory = ctk.ctkDirectoryButton() self.inputLandmarkDirectory.directory = qt.QDir.homePath() parametersFormLayout.addRow("Landmark Directory:", self.inputLandmarkDirectory) self.inputLandmarkDirectory.setToolTip( "Select directory containing landmark files") # # input landmark numbers for grid # gridPointsLayout = qt.QGridLayout() self.landmarkGridPoint1 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint1.minimum = 0 self.landmarkGridPoint1.singleStep = 1 self.landmarkGridPoint1.setDecimals(0) self.landmarkGridPoint1.setToolTip( "Input the landmark numbers to create grid") self.landmarkGridPoint2 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint2.minimum = 0 self.landmarkGridPoint2.singleStep = 1 self.landmarkGridPoint2.setDecimals(0) self.landmarkGridPoint2.setToolTip( "Input the landmark numbers to create grid") self.landmarkGridPoint3 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint3.minimum = 0 self.landmarkGridPoint3.singleStep = 1 self.landmarkGridPoint3.setDecimals(0) self.landmarkGridPoint3.setToolTip( "Input the landmark numbers to create grid") self.landmarkGridPoint4 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint4.minimum = 0 self.landmarkGridPoint4.singleStep = 1 self.landmarkGridPoint4.setDecimals(0) self.landmarkGridPoint4.setToolTip( "Input the landmark numbers to create grid") gridPointsLayout.addWidget(self.landmarkGridPoint1, 1, 2) gridPointsLayout.addWidget(self.landmarkGridPoint2, 1, 3) gridPointsLayout.addWidget(self.landmarkGridPoint3, 1, 4) gridPointsLayout.addWidget(self.landmarkGridPoint4, 1, 5) parametersFormLayout.addRow("Semi-landmark grid points:", gridPointsLayout) # # input mesh directory selector # self.inputMeshDirectory = ctk.ctkDirectoryButton() self.inputMeshDirectory.directory = qt.QDir.homePath() parametersFormLayout.addRow("Mesh Directory:", self.inputMeshDirectory) self.inputMeshDirectory.setToolTip( "Select directory containing mesh files") # # output directory selector # self.outputDirectory = ctk.ctkDirectoryButton() self.outputDirectory.directory = qt.QDir.homePath() parametersFormLayout.addRow("Output Directory:", self.outputDirectory) self.inputMeshDirectory.setToolTip( "Select directory for output semi-landmark files") # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the conversion." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # input warp selector # inputFrame = qt.QFrame() inputFrame.setLayout(qt.QHBoxLayout()) self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLGridTransformNode"] self.inputSelector.selectNodeUponCreation = False self.inputSelector.addEnabled = True self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = True self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") inputFrame.layout().addWidget(qt.QLabel('Input Transform: ')) inputFrame.layout().addWidget(self.inputSelector) self.layout.addWidget(inputFrame) # # Grid reference # emptyTransformCollapsibleButton = ctk.ctkCollapsibleButton() emptyTransformCollapsibleButton.text = "Grid Reference" self.layout.addWidget(emptyTransformCollapsibleButton) # Layout within the dummy collapsible button emptyTransformFormLayout = qt.QFormLayout( emptyTransformCollapsibleButton) self.transformSizeSelect = ctk.ctkCoordinatesWidget() self.transformSizeSelect.coordinates = '193,229,193' self.transformSizeSelect.setDecimals(0) emptyTransformFormLayout.addRow("Size", self.transformSizeSelect) self.transformOriginSelect = ctk.ctkCoordinatesWidget() self.transformOriginSelect.coordinates = '-96.0, -132.0, -78.0' emptyTransformFormLayout.addRow("Origin", self.transformOriginSelect) self.transformSpacingSelect = ctk.ctkCoordinatesWidget() self.transformSpacingSelect.coordinates = '1.0, 1.0, 1.0' emptyTransformFormLayout.addRow("Spacing", self.transformSpacingSelect) # # Operations # operationsCollapsibleButton = ctk.ctkCollapsibleButton() operationsCollapsibleButton.text = "Operations" self.layout.addWidget(operationsCollapsibleButton) # Layout within the dummy collapsible button operationsFormLayout = qt.QFormLayout(operationsCollapsibleButton) # Empty Button self.emptyButton = qt.QPushButton("Empty Transform") self.emptyButton.enabled = False operationsFormLayout.addRow(self.emptyButton) # Flatten Button & opts flattenFrame = qt.QFrame() flattenFrame.setLayout(qt.QHBoxLayout()) self.includeFirstLayerCB = qt.QCheckBox('Include First Layer') self.includeFirstLayerCB.toolTip = "If selected all the layers of the composite transform will be flattened taking the first grid as reference. If not, the layers starting from the second one will be flattened and append to the first one. In this case the reference grid is used to flatten the transform" flattenFrame.layout().addWidget(self.includeFirstLayerCB) self.flattenButton = qt.QPushButton("Flatten Transform") self.flattenButton.enabled = False flattenFrame.layout().addWidget(self.flattenButton, 2) operationsFormLayout.addRow(flattenFrame) # Remove last layer self.removeLastLayerButton = qt.QPushButton("Remove Last Layer") self.removeLastLayerButton.enabled = False operationsFormLayout.addRow(self.removeLastLayerButton) # connections self.emptyButton.connect('clicked(bool)', self.onEmptyButton) self.flattenButton.connect('clicked(bool)', self.onFlattenButton) self.removeLastLayerButton.connect('clicked(bool)', self.onRemoveLastLayerButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Connection connectionCollapsibleButton = ctk.ctkCollapsibleButton() connectionCollapsibleButton.text = "OSC server connection" self.layout.addWidget(connectionCollapsibleButton) connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton) self.hostnameLineEdit = qt.QLineEdit("localhost") connectionFormLayout.addRow("Host name: ", self.hostnameLineEdit) self.portLineEdit = qt.QLineEdit("7400") self.portLineEdit.setValidator( qt.QIntValidator(0, 65535, self.portLineEdit)) connectionFormLayout.addRow("Port: ", self.portLineEdit) self.addressRootLineEdit = qt.QLineEdit("SoundNav") self.addressRootLineEdit.setToolTip( "OSC address root. Complete address: /<address root>/<instrument name>/<parameter name>." ) connectionFormLayout.addRow("Address root: ", self.addressRootLineEdit) self.enableConnectionCheckBox = qt.QCheckBox() self.enableConnectionCheckBox.checked = False self.enableConnectionCheckBox.setToolTip( "If checked, then transform changes will be immediately sent to specified OSC server." ) connectionFormLayout.addRow("Transmission active: ", self.enableConnectionCheckBox) self.enableConnectionCheckBox.connect('stateChanged(int)', self.setTransmissionActive) # Parameters Area parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) parameterNode = self.logic.getParameterNode() maxNumberOfInstruments = int( parameterNode.GetParameter("MaxNumberOfInstruments")) for instrumentIndex in range(maxNumberOfInstruments): instrumentGroupBox = ctk.ctkCollapsibleGroupBox() instrumentGroupBox.title = "Instrument " + str(instrumentIndex + 1) parametersFormLayout.addWidget(instrumentGroupBox) instrumentLayout = qt.QFormLayout(instrumentGroupBox) nameLineEdit = qt.QLineEdit() instrumentLayout.addRow("Instrument name: ", nameLineEdit) nameLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) instrumentSourceSelector = slicer.qMRMLNodeComboBox() instrumentNodeTypes = ["vtkMRMLLinearTransformNode"] if hasattr(slicer.modules, 'breachwarning'): instrumentNodeTypes.append("vtkMRMLBreachWarningNode") instrumentSourceSelector.nodeTypes = instrumentNodeTypes instrumentSourceSelector.addEnabled = True instrumentSourceSelector.removeEnabled = True instrumentSourceSelector.noneEnabled = True instrumentSourceSelector.renameEnabled = True instrumentSourceSelector.setMRMLScene(slicer.mrmlScene) instrumentSourceSelector.setToolTip( "Defines position and orientation of the instrument (transform or breach warning node)" ) instrumentLayout.addRow("Instrument node: ", instrumentSourceSelector) instrumentSourceSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) instrumentReferenceSelector = slicer.qMRMLNodeComboBox() instrumentReferenceSelector.nodeTypes = [ "vtkMRMLLinearTransformNode" ] instrumentReferenceSelector.addEnabled = True instrumentReferenceSelector.removeEnabled = True instrumentReferenceSelector.noneEnabled = True instrumentReferenceSelector.renameEnabled = True instrumentReferenceSelector.setMRMLScene(slicer.mrmlScene) instrumentReferenceSelector.setToolTip( "Position and orientation is defined relative to this transform" ) instrumentLayout.addRow("Reference transform: ", instrumentReferenceSelector) instrumentReferenceSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) widgets = {} widgets['instrumentGroupBox'] = instrumentGroupBox widgets['nameLineEdit'] = nameLineEdit widgets['instrumentSourceSelector'] = instrumentSourceSelector widgets[ 'instrumentReferenceSelector'] = instrumentReferenceSelector self.instrumentWidgets.append(widgets) self.updateGUIFromMRML() self.hostnameLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) self.portLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) self.addressRootLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) for instrumentIndex in range(len(self.instrumentWidgets)): widgets = self.instrumentWidgets[instrumentIndex] # Collapse unused instrument groupboxes widgets['instrumentGroupBox'].collapsed = not widgets[ 'nameLineEdit'].text # Observe widget changes to update MRML node immediately (this way always up-to-date values will be saved in the scene) widgets['nameLineEdit'].connect('editingFinished()', self.updateMRMLFromGUI) widgets['instrumentSourceSelector'].connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) widgets['instrumentReferenceSelector'].connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) self.parameterNodeObserverTag = parameterNode.AddObserver( vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML) # Add vertical spacer self.layout.addStretch(1)
def setup(self): # Instantiate and connect widgets ... # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "NeurosurgicalPlanningTutorialTractographySelfTest 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) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip( "Set scale factor for the screen shots.") parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # 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)
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) # 3D view set up tab self.meshSelect = slicer.qMRMLNodeComboBox() self.meshSelect.nodeTypes = ( ("vtkMRMLModelNode"), "" ) self.meshSelect.selectNodeUponCreation = False self.meshSelect.addEnabled = False self.meshSelect.removeEnabled = False self.meshSelect.noneEnabled = True self.meshSelect.showHidden = False self.meshSelect.setMRMLScene( slicer.mrmlScene ) self.meshSelect.connect("currentNodeChanged(vtkMRMLNode*)", self.onMeshSelect) parametersFormLayout.addRow("Model: ", self.meshSelect) self.meshSelect.setToolTip( "Select model node for semilandmarking" ) self.LMSelect = slicer.qMRMLNodeComboBox() self.LMSelect.nodeTypes = ( ('vtkMRMLMarkupsFiducialNode'), "" ) self.LMSelect.selectNodeUponCreation = False self.LMSelect.addEnabled = False self.LMSelect.removeEnabled = False self.LMSelect.noneEnabled = True self.LMSelect.showHidden = False self.LMSelect.showChildNodeTypes = False self.LMSelect.setMRMLScene( slicer.mrmlScene ) self.LMSelect.connect("currentNodeChanged(vtkMRMLNode*)", self.onLMSelect) parametersFormLayout.addRow("Landmark set: ", self.LMSelect) self.LMSelect.setToolTip( "Select the landmark set that corresponds to the model" ) # # input landmark numbers for grid # gridPointsLayout= qt.QGridLayout() self.landmarkGridPoint1 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint1.minimum = 0 self.landmarkGridPoint1.singleStep = 1 self.landmarkGridPoint1.setDecimals(0) self.landmarkGridPoint1.setToolTip("Input the landmark numbers to create grid") self.landmarkGridPoint2 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint2.minimum = 0 self.landmarkGridPoint2.singleStep = 1 self.landmarkGridPoint2.setDecimals(0) self.landmarkGridPoint2.setToolTip("Input the landmark numbers to create grid") self.landmarkGridPoint3 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint3.minimum = 0 self.landmarkGridPoint3.singleStep = 1 self.landmarkGridPoint3.setDecimals(0) self.landmarkGridPoint3.setToolTip("Input the landmark numbers to create grid") gridPointsLayout.addWidget(self.landmarkGridPoint1,1,2) gridPointsLayout.addWidget(self.landmarkGridPoint2,1,3) gridPointsLayout.addWidget(self.landmarkGridPoint3,1,4) parametersFormLayout.addRow("Semi-landmark grid points:", gridPointsLayout) # # set number of sample points in each triangle # self.gridSamplingRate = ctk.ctkDoubleSpinBox() self.gridSamplingRate.minimum = 3 self.gridSamplingRate.maximum = 50 self.gridSamplingRate.singleStep = 1 self.gridSamplingRate.setDecimals(0) self.gridSamplingRate.value = 10 self.gridSamplingRate.setToolTip("Input the landmark numbers to create grid") parametersFormLayout.addRow("Select number of rows/columns in resampled grid:", self.gridSamplingRate) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Advanced menu # advancedCollapsibleButton = ctk.ctkCollapsibleButton() advancedCollapsibleButton.text = "Advanced" advancedCollapsibleButton.collapsed = True parametersFormLayout.addRow(advancedCollapsibleButton) # Layout within the dummy collapsible button advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton) # # Maximum projection slider # self.projectionDistanceSlider = ctk.ctkSliderWidget() self.projectionDistanceSlider.singleStep = 1 self.projectionDistanceSlider.minimum = 0 self.projectionDistanceSlider.maximum = 100 self.projectionDistanceSlider.value = 25 self.projectionDistanceSlider.setToolTip("Set maximum projection distance as a percentage of image size") advancedFormLayout.addRow("Set maximum projection distance: ", self.projectionDistanceSlider) # # Normal smoothing slider # self.smoothingSlider = ctk.ctkSliderWidget() self.smoothingSlider.singleStep = 1 self.smoothingSlider.minimum = 0 self.smoothingSlider.maximum = 100 self.smoothingSlider.value = 0 self.smoothingSlider.setToolTip("Set smothing of normal vectors for projection") advancedFormLayout.addRow("Set smoothing of projection vectors: ", self.smoothingSlider) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Generate semilandmarks." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # # Fiducials view # self.fiducialView = slicer.qMRMLSubjectHierarchyTreeView() self.fiducialView.setMRMLScene(slicer.mrmlScene) self.fiducialView.setMultiSelection(True) self.fiducialView.setAlternatingRowColors(True) self.fiducialView.setDragDropMode(True) self.fiducialView.setColumnHidden(self.fiducialView.model().transformColumn, True); self.fiducialView.sortFilterProxyModel().setNodeTypes(["vtkMRMLMarkupsFiducialNode"]) parametersFormLayout.addRow(self.fiducialView) # # Apply Button # self.mergeButton = qt.QPushButton("Merge highlighted nodes") self.mergeButton.toolTip = "Generate a single merged landmark file from the selected nodes" self.mergeButton.enabled = False parametersFormLayout.addRow(self.mergeButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.mergeButton.connect('clicked(bool)', self.onMergeButton) self.fiducialView.connect('currentItemChanged(vtkIdType)', self.updateMergeButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input selector # # File dialog to select a file template for series self.inputFileSelector = ctk.ctkPathLineEdit() self.inputFileSelector.filters = ctk.ctkPathLineEdit().Files self.inputFileSelector.setToolTip( "Select log file from a directory of images.") parametersFormLayout.addRow("Select log file from image series:", self.inputFileSelector) # # output volume selector # # self.outputSelector = slicer.qMRMLNodeComboBox() # self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] # self.outputSelector.selectNodeUponCreation = True # self.outputSelector.addEnabled = True # self.outputSelector.removeEnabled = True # self.outputSelector.noneEnabled = True # self.outputSelector.showHidden = False # self.outputSelector.showChildNodeTypes = False # self.outputSelector.renameEnabled = True # self.outputSelector.setMRMLScene( slicer.mrmlScene ) # self.outputSelector.setToolTip( "Pick the output to the algorithm." ) # parametersFormLayout.addRow("Output Volume: ", self.outputSelector) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) #self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.inputFileSelector.connect("currentPathChanged(const QString &)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... inputModelSelectorFrame = qt.QFrame(self.parent) inputModelSelectorFrame.setLayout(qt.QHBoxLayout()) self.parent.layout().addWidget(inputModelSelectorFrame) inputModelSelectorLabel = qt.QLabel("Input Model: ", inputModelSelectorFrame) inputModelSelectorLabel.setToolTip("Select the input model") inputModelSelectorFrame.layout().addWidget(inputModelSelectorLabel) inputModelSelector = slicer.qMRMLNodeComboBox(inputModelSelectorFrame) inputModelSelector.nodeTypes = ["vtkMRMLModelNode"] inputModelSelector.selectNodeUponCreation = False inputModelSelector.addEnabled = False inputModelSelector.removeEnabled = False inputModelSelector.noneEnabled = True inputModelSelector.showHidden = False inputModelSelector.showChildNodeTypes = False inputModelSelector.setMRMLScene(slicer.mrmlScene) inputModelSelectorFrame.layout().addWidget(inputModelSelector) outputModelSelectorFrame = qt.QFrame(self.parent) outputModelSelectorFrame.setLayout(qt.QHBoxLayout()) self.parent.layout().addWidget(outputModelSelectorFrame) outputModelSelectorLabel = qt.QLabel("Output Model: ", outputModelSelectorFrame) outputModelSelectorLabel.setToolTip("Select the output model") outputModelSelectorFrame.layout().addWidget(outputModelSelectorLabel) outputModelSelector = slicer.qMRMLNodeComboBox( outputModelSelectorFrame) outputModelSelector.nodeTypes = ["vtkMRMLModelNode"] outputModelSelector.selectNodeUponCreation = False outputModelSelector.addEnabled = True outputModelSelector.renameEnabled = True outputModelSelector.removeEnabled = True outputModelSelector.noneEnabled = True outputModelSelector.showHidden = False outputModelSelector.showChildNodeTypes = False outputModelSelector.baseName = "Model" outputModelSelector.selectNodeUponCreation = True outputModelSelector.setMRMLScene(slicer.mrmlScene) outputModelSelectorFrame.layout().addWidget(outputModelSelector) decimationButton = qt.QPushButton("Decimation") decimationButton.checkable = True self.layout.addWidget(decimationButton) decimationFrame = qt.QFrame(self.parent) self.layout.addWidget(decimationFrame) decimationFormLayout = qt.QFormLayout(decimationFrame) reductionFrame, reductionSlider, reductionSpinBox = numericInputFrame( self.parent, "Reduction:", "Tooltip", 0.0, 1.0, 0.05, 2) decimationFormLayout.addWidget(reductionFrame) boundaryDeletionCheckBox = qt.QCheckBox("Boundary deletion") decimationFormLayout.addWidget(boundaryDeletionCheckBox) smoothingButton = qt.QPushButton("Smoothing") smoothingButton.checkable = True self.layout.addWidget(smoothingButton) smoothingFrame = qt.QFrame(self.parent) self.layout.addWidget(smoothingFrame) smoothingFormLayout = qt.QFormLayout(smoothingFrame) smoothingMethodCombo = qt.QComboBox(smoothingFrame) smoothingMethodCombo.addItem("Laplace") smoothingMethodCombo.addItem("Taubin") smoothingFormLayout.addWidget(smoothingMethodCombo) laplaceMethodFrame = qt.QFrame(self.parent) smoothingFormLayout.addWidget(laplaceMethodFrame) laplaceMethodFormLayout = qt.QFormLayout(laplaceMethodFrame) laplaceIterationsFrame, laplaceIterationsSlider, laplaceIterationsSpinBox = numericInputFrame( self.parent, "Iterations:", "Determines the maximum number of smoothing iterations. Higher value allows more smoothing." + " In general, small relaxation factors and large numbers of iterations are more stable than" + " larger relaxation factors and smaller numbers of iterations. ", 0.0, 500.0, 1.0, 0) laplaceMethodFormLayout.addWidget(laplaceIterationsFrame) laplaceRelaxationFrame, laplaceRelaxationSlider, laplaceRelaxationSpinBox = numericInputFrame( self.parent, "Relaxation:", "Specifies how much points may be displaced during each iteration. Higher value results in more smoothing.", 0.0, 1.0, 0.1, 1) laplaceMethodFormLayout.addWidget(laplaceRelaxationFrame) taubinMethodFrame = qt.QFrame(self.parent) smoothingFormLayout.addWidget(taubinMethodFrame) taubinMethodFormLayout = qt.QFormLayout(taubinMethodFrame) taubinIterationsFrame, taubinIterationsSlider, taubinIterationsSpinBox = numericInputFrame( self.parent, "Iterations:", "Determines the maximum number of smoothing iterations. Higher value allows more accurate smoothing." + " Typically 10-20 iterations are enough.", 0.0, 100.0, 1.0, 0) taubinMethodFormLayout.addWidget(taubinIterationsFrame) taubinPassBandFrame, taubinPassBandSlider, taubinPassBandSpinBox = numericInputFrame( self.parent, "Pass Band:", "Number between 0 and 2. Lower values produce more smoothing.", 0.0, 2.0, 0.0001, 4) taubinMethodFormLayout.addWidget(taubinPassBandFrame) boundarySmoothingCheckBox = qt.QCheckBox("Boundary Smoothing") smoothingFormLayout.addWidget(boundarySmoothingCheckBox) normalsButton = qt.QPushButton("Normals") normalsButton.checkable = True self.layout.addWidget(normalsButton) normalsFrame = qt.QFrame(self.parent) self.layout.addWidget(normalsFrame) normalsFormLayout = qt.QFormLayout(normalsFrame) autoOrientNormalsCheckBox = qt.QCheckBox("Auto-orient Normals") autoOrientNormalsCheckBox.setToolTip( "Orient the normals outwards from closed surface") normalsFormLayout.addWidget(autoOrientNormalsCheckBox) flipNormalsCheckBox = qt.QCheckBox("Flip Normals") flipNormalsCheckBox.setToolTip( "Flip normal direction from its current or auto-oriented state") normalsFormLayout.addWidget(flipNormalsCheckBox) splittingCheckBox = qt.QCheckBox("Splitting") normalsFormLayout.addWidget(splittingCheckBox) featureAngleFrame, featureAngleSlider, featureAngleSpinBox = numericInputFrame( self.parent, "Feature Angle:", "Tooltip", 0.0, 180.0, 1.0, 0) normalsFormLayout.addWidget(featureAngleFrame) mirrorButton = qt.QPushButton("Mirror") mirrorButton.checkable = True self.layout.addWidget(mirrorButton) mirrorFrame = qt.QFrame(self.parent) self.layout.addWidget(mirrorFrame) mirrorFormLayout = qt.QFormLayout(mirrorFrame) mirrorXCheckBox = qt.QCheckBox("X-axis") mirrorXCheckBox.setToolTip("Flip model along its X axis") mirrorFormLayout.addWidget(mirrorXCheckBox) mirrorYCheckBox = qt.QCheckBox("Y-axis") mirrorYCheckBox.setToolTip("Flip model along its Y axis") mirrorFormLayout.addWidget(mirrorYCheckBox) mirrorZCheckBox = qt.QCheckBox("Z-axis") mirrorZCheckBox.setToolTip("Flip model along its Z axis") mirrorFormLayout.addWidget(mirrorZCheckBox) cleanerButton = qt.QPushButton("Cleaner") cleanerButton.checkable = True self.layout.addWidget(cleanerButton) connectivityButton = qt.QPushButton("Connectivity") connectivityButton.checkable = True self.layout.addWidget(connectivityButton) #connectivityFrame = qt.QFrame(self.parent) #self.layout.addWidget(connectivityFrame) #connectivityFormLayout = qt.QFormLayout(connectivityFrame) # TODO: connectivity could be # - largest connected # - threshold connected (discard below point count) # - pick a region interactively # - turn a multiple connected surface into a model hierarchy buttonFrame = qt.QFrame(self.parent) buttonFrame.setLayout(qt.QHBoxLayout()) self.layout.addWidget(buttonFrame) toggleModelsButton = qt.QPushButton("Toggle Models") toggleModelsButton.toolTip = "Show original model." buttonFrame.layout().addWidget(toggleModelsButton) applyButton = qt.QPushButton("Apply") applyButton.toolTip = "Filter surface." buttonFrame.layout().addWidget(applyButton) self.layout.addStretch(1) class state(object): inputModelNode = None outputModelNode = None decimation = False reduction = 0.8 boundaryDeletion = False smoothing = False smoothingMethod = "Laplace" laplaceIterations = 100.0 laplaceRelaxation = 0.5 taubinIterations = 30.0 taubinPassBand = 0.1 boundarySmoothing = True normals = False flipNormals = False autoOrientNormals = False mirror = False mirrorX = False mirrorY = False mirrorZ = False splitting = False featureAngle = 30.0 cleaner = False connectivity = False scope_locals = locals() def connect(obj, evt, cmd): def callback(*args): current_locals = scope_locals.copy() current_locals.update({'args': args}) exec cmd in globals(), current_locals updateGUI() obj.connect(evt, callback) def updateGUI(): def button_stylesheet(active): if active: return "background-color: green" else: return "" decimationButton.checked = state.decimation #decimationButton.setStyleSheet(button_stylesheet(state.decimation)) decimationFrame.visible = state.decimation boundaryDeletionCheckBox.checked = state.boundaryDeletion reductionSlider.value = state.reduction reductionSpinBox.value = state.reduction smoothingButton.checked = state.smoothing smoothingFrame.visible = state.smoothing laplaceMethodFrame.visible = state.smoothingMethod == "Laplace" laplaceIterationsSlider.value = state.laplaceIterations laplaceIterationsSpinBox.value = state.laplaceIterations laplaceRelaxationSlider.value = state.laplaceRelaxation laplaceRelaxationSpinBox.value = state.laplaceRelaxation taubinMethodFrame.visible = state.smoothingMethod == "Taubin" taubinIterationsSlider.value = state.taubinIterations taubinIterationsSpinBox.value = state.taubinIterations taubinPassBandSlider.value = state.taubinPassBand taubinPassBandSpinBox.value = state.taubinPassBand boundarySmoothingCheckBox.checked = state.boundarySmoothing normalsButton.checked = state.normals normalsFrame.visible = state.normals autoOrientNormalsCheckBox.checked = state.autoOrientNormals flipNormalsCheckBox.checked = state.flipNormals splittingCheckBox.checked = state.splitting featureAngleFrame.visible = state.splitting featureAngleSlider.value = state.featureAngle featureAngleSpinBox.value = state.featureAngle mirrorButton.checked = state.mirror mirrorFrame.visible = state.mirror mirrorXCheckBox.checked = state.mirrorX mirrorYCheckBox.checked = state.mirrorY mirrorZCheckBox.checked = state.mirrorZ cleanerButton.checked = state.cleaner connectivityButton.checked = state.connectivity toggleModelsButton.enabled = state.inputModelNode is not None and state.outputModelNode is not None applyButton.enabled = state.inputModelNode is not None and state.outputModelNode is not None connect(inputModelSelector, 'currentNodeChanged(vtkMRMLNode*)', 'state.inputModelNode = args[0]') connect(outputModelSelector, 'currentNodeChanged(vtkMRMLNode*)', 'state.outputModelNode = args[0]') def initializeModelNode(node): displayNode = slicer.vtkMRMLModelDisplayNode() storageNode = slicer.vtkMRMLModelStorageNode() displayNode.SetScene(slicer.mrmlScene) storageNode.SetScene(slicer.mrmlScene) slicer.mrmlScene.AddNode(displayNode) slicer.mrmlScene.AddNode(storageNode) node.SetAndObserveDisplayNodeID(displayNode.GetID()) node.SetAndObserveStorageNodeID(storageNode.GetID()) outputModelSelector.connect('nodeAddedByUser(vtkMRMLNode*)', initializeModelNode) connect(decimationButton, 'clicked(bool)', 'state.decimation = args[0]') connect(reductionSlider, 'valueChanged(double)', 'state.reduction = args[0]') connect(reductionSpinBox, 'valueChanged(double)', 'state.reduction = args[0]') connect(boundaryDeletionCheckBox, 'stateChanged(int)', 'state.boundaryDeletion = bool(args[0])') connect(smoothingButton, 'clicked(bool)', 'state.smoothing = args[0]') connect(smoothingMethodCombo, 'currentIndexChanged(QString)', 'state.smoothingMethod = args[0]') connect(laplaceIterationsSlider, 'valueChanged(double)', 'state.laplaceIterations = int(args[0])') connect(laplaceIterationsSpinBox, 'valueChanged(double)', 'state.laplaceIterations = int(args[0])') connect(laplaceRelaxationSlider, 'valueChanged(double)', 'state.laplaceRelaxation = args[0]') connect(laplaceRelaxationSpinBox, 'valueChanged(double)', 'state.laplaceRelaxation = args[0]') connect(taubinIterationsSlider, 'valueChanged(double)', 'state.taubinIterations = int(args[0])') connect(taubinIterationsSpinBox, 'valueChanged(double)', 'state.taubinIterations = int(args[0])') connect(taubinPassBandSlider, 'valueChanged(double)', 'state.taubinPassBand = args[0]') connect(taubinPassBandSpinBox, 'valueChanged(double)', 'state.taubinPassBand = args[0]') connect(boundarySmoothingCheckBox, 'stateChanged(int)', 'state.boundarySmoothing = bool(args[0])') connect(normalsButton, 'clicked(bool)', 'state.normals = args[0]') connect(autoOrientNormalsCheckBox, 'toggled(bool)', 'state.autoOrientNormals = bool(args[0])') connect(flipNormalsCheckBox, 'toggled(bool)', 'state.flipNormals = bool(args[0])') connect(splittingCheckBox, 'stateChanged(int)', 'state.splitting = bool(args[0])') connect(featureAngleSlider, 'valueChanged(double)', 'state.featureAngle = args[0]') connect(featureAngleSpinBox, 'valueChanged(double)', 'state.featureAngle = args[0]') connect(mirrorButton, 'clicked(bool)', 'state.mirror = args[0]') connect(mirrorXCheckBox, 'toggled(bool)', 'state.mirrorX = bool(args[0])') connect(mirrorYCheckBox, 'toggled(bool)', 'state.mirrorY = bool(args[0])') connect(mirrorZCheckBox, 'toggled(bool)', 'state.mirrorZ = bool(args[0])') connect(cleanerButton, 'clicked(bool)', 'state.cleaner = args[0]') connect(connectivityButton, 'clicked(bool)', 'state.connectivity = args[0]') def onApply(): updateGUI() applyButton.text = "Working..." applyButton.repaint() slicer.app.processEvents() logic = SurfaceToolboxLogic() result = logic.applyFilters(state) if result: state.inputModelNode.GetModelDisplayNode().VisibilityOff() state.outputModelNode.GetModelDisplayNode().VisibilityOn() else: state.inputModelNode.GetModelDisplayNode().VisibilityOn() state.outputModelNode.GetModelDisplayNode().VisibilityOff() applyButton.text = "Apply" applyButton.connect('clicked()', onApply) def onToggleModels(): updateGUI() if state.inputModelNode.GetModelDisplayNode().GetVisibility(): state.inputModelNode.GetModelDisplayNode().VisibilityOff() state.outputModelNode.GetModelDisplayNode().VisibilityOn() toggleModelsButton.text = "Toggle Models (Output)" else: state.inputModelNode.GetModelDisplayNode().VisibilityOn() state.outputModelNode.GetModelDisplayNode().VisibilityOff() toggleModelsButton.text = "Toggle Models (Input)" toggleModelsButton.connect('clicked()', onToggleModels) updateGUI() self.updateGUI = updateGUI
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = SegmentMesherLogic() self.logic.logCallback = self.addLog self.modelGenerationInProgress = False # Instantiate and connect widgets ... # Parameter sets defaultinputParametersCollapsibleButton = ctk.ctkCollapsibleButton() defaultinputParametersCollapsibleButton.text = "Parameter set" defaultinputParametersCollapsibleButton.collapsed = True self.layout.addWidget(defaultinputParametersCollapsibleButton) defaultParametersLayout = qt.QFormLayout(defaultinputParametersCollapsibleButton) self.parameterNodeSelector = slicer.qMRMLNodeComboBox() self.parameterNodeSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"] self.parameterNodeSelector.addAttribute( "vtkMRMLScriptedModuleNode", "ModuleName", "SegmentMesher" ) self.parameterNodeSelector.selectNodeUponCreation = True self.parameterNodeSelector.addEnabled = True self.parameterNodeSelector.renameEnabled = True self.parameterNodeSelector.removeEnabled = True self.parameterNodeSelector.noneEnabled = False self.parameterNodeSelector.showHidden = True self.parameterNodeSelector.showChildNodeTypes = False self.parameterNodeSelector.baseName = "SegmentMesher" self.parameterNodeSelector.setMRMLScene( slicer.mrmlScene ) self.parameterNodeSelector.setToolTip( "Pick parameter set" ) defaultParametersLayout.addRow("Parameter set: ", self.parameterNodeSelector) # # Inputs # inputParametersCollapsibleButton = ctk.ctkCollapsibleButton() inputParametersCollapsibleButton.text = "Inputs" self.layout.addWidget(inputParametersCollapsibleButton) # Layout within the dummy collapsible button inputParametersFormLayout = qt.QFormLayout(inputParametersCollapsibleButton) self.inputModelSelector = slicer.qMRMLNodeComboBox() self.inputModelSelector.nodeTypes = ["vtkMRMLSegmentationNode"] self.inputModelSelector.selectNodeUponCreation = True self.inputModelSelector.addEnabled = False self.inputModelSelector.removeEnabled = False self.inputModelSelector.noneEnabled = False self.inputModelSelector.showHidden = False self.inputModelSelector.showChildNodeTypes = False self.inputModelSelector.setMRMLScene( slicer.mrmlScene ) self.inputModelSelector.setToolTip( "Volumetric mesh will be generated for all visible segments in this segmentation node." ) inputParametersFormLayout.addRow("Input segmentation: ", self.inputModelSelector) self.methodSelectorComboBox = qt.QComboBox() self.methodSelectorComboBox.addItem("Cleaver", METHOD_CLEAVER) self.methodSelectorComboBox.addItem("TetGen", METHOD_TETGEN) inputParametersFormLayout.addRow("Meshing method: ", self.methodSelectorComboBox) # # Outputs # outputParametersCollapsibleButton = ctk.ctkCollapsibleButton() outputParametersCollapsibleButton.text = "Outputs" self.layout.addWidget(outputParametersCollapsibleButton) outputParametersFormLayout = qt.QFormLayout(outputParametersCollapsibleButton) # # output volume selector # self.outputModelSelector = slicer.qMRMLNodeComboBox() self.outputModelSelector.nodeTypes = ["vtkMRMLModelNode"] self.outputModelSelector.selectNodeUponCreation = True self.outputModelSelector.addEnabled = True self.outputModelSelector.renameEnabled = True self.outputModelSelector.removeEnabled = True self.outputModelSelector.noneEnabled = False self.outputModelSelector.showHidden = False self.outputModelSelector.showChildNodeTypes = False self.outputModelSelector.setMRMLScene( slicer.mrmlScene ) self.outputModelSelector.setToolTip( "Created volumetric mesh" ) outputParametersFormLayout.addRow("Output model: ", self.outputModelSelector) # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = True self.layout.addWidget(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) self.cleaverAdditionalParametersWidget = qt.QLineEdit() self.cleaverAdditionalParametersWidget.setToolTip('See description of parameters in module documentation ') advancedFormLayout.addRow("Cleaver meshing options:", self.cleaverAdditionalParametersWidget) self.cleaverAdditionalParametersWidget.text = "--scale 0.2 --multiplier 2 --grading 5" self.tetGenAdditionalParametersWidget = qt.QLineEdit() self.tetGenAdditionalParametersWidget.setToolTip('See description of parameters in module documentation ') advancedFormLayout.addRow("TetGen meshing options:", self.tetGenAdditionalParametersWidget) self.tetGenAdditionalParametersWidget.text = "" self.showDetailedLogDuringExecutionCheckBox = qt.QCheckBox(" ") self.showDetailedLogDuringExecutionCheckBox.checked = False self.showDetailedLogDuringExecutionCheckBox.setToolTip("Show detailed log during model generation.") advancedFormLayout.addRow("Show detailed log:", self.showDetailedLogDuringExecutionCheckBox) self.keepTemporaryFilesCheckBox = qt.QCheckBox(" ") self.keepTemporaryFilesCheckBox.checked = False self.keepTemporaryFilesCheckBox.setToolTip("Keep temporary files (inputs, computed outputs, logs) after the model generation is completed.") self.showTemporaryFilesFolderButton = qt.QPushButton("Show temp folder") self.showTemporaryFilesFolderButton.toolTip = "Open the folder where temporary files are stored." self.showTemporaryFilesFolderButton.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) hbox = qt.QHBoxLayout() hbox.addWidget(self.keepTemporaryFilesCheckBox) hbox.addWidget(self.showTemporaryFilesFolderButton) advancedFormLayout.addRow("Keep temporary files:", hbox) customCleaverPath = self.logic.getCustomCleaverPath() self.customCleaverPathSelector = ctk.ctkPathLineEdit() self.customCleaverPathSelector.setCurrentPath(customCleaverPath) self.customCleaverPathSelector.nameFilters = [self.logic.cleaverFilename] self.customCleaverPathSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) self.customCleaverPathSelector.setToolTip("Set cleaver-cli executable path. " "If value is empty then cleaver-cli bundled with this extension will be used.") advancedFormLayout.addRow("Custom Cleaver executable path:", self.customCleaverPathSelector) customTetGenPath = self.logic.getCustomTetGenPath() self.customTetGenPathSelector = ctk.ctkPathLineEdit() self.customTetGenPathSelector.setCurrentPath(customTetGenPath) self.customTetGenPathSelector.nameFilters = [self.logic.tetGenFilename] self.customTetGenPathSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) self.customTetGenPathSelector.setToolTip("Set tetgen executable path. " "If value is empty then tetgen bundled with this extension will be used.") advancedFormLayout.addRow("Custom TetGen executable path:", self.customTetGenPathSelector) # # Display # displayParametersCollapsibleButton = ctk.ctkCollapsibleButton() displayParametersCollapsibleButton.text = "Display" displayParametersCollapsibleButton.collapsed = True self.layout.addWidget(displayParametersCollapsibleButton) displayParametersFormLayout = qt.QFormLayout(displayParametersCollapsibleButton) self.clipNodeWidget=slicer.qMRMLClipNodeWidget() clipNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLClipModelsNode") self.clipNodeWidget.setMRMLClipNode(clipNode) displayParametersFormLayout.addRow(self.clipNodeWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False self.layout.addWidget(self.applyButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) self.statusLabel.setCenterOnScroll(True) self.layout.addWidget(self.statusLabel) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.showTemporaryFilesFolderButton.connect('clicked(bool)', self.onShowTemporaryFilesFolder) self.inputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) self.outputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI) # Immediately update deleteTemporaryFiles in the logic to make it possible to decide to # keep the temporary file while the model generation is running self.keepTemporaryFilesCheckBox.connect("toggled(bool)", self.onKeepTemporaryFilesToggled) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.updateMRMLFromGUI()
def _addCustomizationSection(self): customizationCollapsibleButton = ctk.ctkCollapsibleButton() customizationCollapsibleButton.text = 'Extraction Customization' customizationCollapsibleButton.collapsed = True self.layout.addWidget(customizationCollapsibleButton) customizationFormLayout = qt.QFormLayout( customizationCollapsibleButton) # # Radiobuttons to select customization Type # self.manualCustomizationRadioButton = qt.QRadioButton() self.manualCustomizationRadioButton.text = 'Manual Customization' self.manualCustomizationRadioButton.checked = True customizationFormLayout.layout().addWidget( self.manualCustomizationRadioButton) self.parameterFileCustomizationRadioButton = qt.QRadioButton() self.parameterFileCustomizationRadioButton.text = 'Parameter File Customization' self.parameterFileCustomizationRadioButton.checked = False customizationFormLayout.layout().addWidget( self.parameterFileCustomizationRadioButton) # # Manual Customization # self.manualCustomizationGroupBox = qt.QGroupBox('Manual Customization') self.manualCustomizationGroupBox.visible = True # self.manualCustomizationGroupBox.checkable = True customizationFormLayout.addWidget(self.manualCustomizationGroupBox) manualCustomizationFormLayout = qt.QFormLayout( self.manualCustomizationGroupBox) # Feature Class section featureClassCollapsibleButton = ctk.ctkCollapsibleButton() featureClassCollapsibleButton.text = 'Feature Classes' featureClassCollapsibleButton.collapsed = False manualCustomizationFormLayout.addWidget(featureClassCollapsibleButton) featureClassLayout = qt.QFormLayout(featureClassCollapsibleButton) self.featuresLayout = qt.QHBoxLayout() featureClassLayout.addRow('Features:', self.featuresLayout) self.featuresButtonGroup = qt.QButtonGroup(self.featuresLayout) self.featuresButtonGroup.exclusive = False # Get the feature classes dynamically self.features = list(getFeatureClasses().keys()) # Create a checkbox for each feature featureButtons = {} for feature in self.features: featureButtons[feature] = qt.QCheckBox(feature) # TODO: decide which features to enable by default featureButtons[feature].checked = False if feature == 'firstorder': featureButtons[feature].checked = True self.featuresButtonGroup.addButton(featureButtons[feature]) self.featuresLayout.layout().addWidget(featureButtons[feature]) # set the ID to be the index of this feature in the list self.featuresButtonGroup.setId(featureButtons[feature], self.features.index(feature)) # Add buttons to select all or none self.buttonsLayout = qt.QHBoxLayout() featureClassLayout.addRow('Toggle Features:', self.buttonsLayout) self.calculateAllFeaturesButton = qt.QPushButton('All Features') self.calculateAllFeaturesButton.toolTip = 'Calculate all feature classes.' self.calculateAllFeaturesButton.enabled = True self.buttonsLayout.addWidget(self.calculateAllFeaturesButton) self.calculateNoFeaturesButton = qt.QPushButton('No Features') self.calculateNoFeaturesButton.toolTip = 'Calculate no feature classes.' self.calculateNoFeaturesButton.enabled = True self.buttonsLayout.addWidget(self.calculateNoFeaturesButton) # Resampling and Filtering filteringCollapsibleButton = ctk.ctkCollapsibleButton() filteringCollapsibleButton.text = 'Resampling and Filtering' filteringCollapsibleButton.collapsed = False manualCustomizationFormLayout.addRow(filteringCollapsibleButton) # Layout within the dummy collapsible button filteringFormLayout = qt.QFormLayout(filteringCollapsibleButton) # Resampling self.resampledVoxelSize = qt.QLineEdit() self.resampledVoxelSize.toolTip = 'Three floating-point numbers separated by comma defining the resampled pixel ' \ 'size (mm).' filteringFormLayout.addRow('Resampled voxel size', self.resampledVoxelSize) # LoG kernel sizes. default to 5 (?) self.logKernelSizes = qt.QLineEdit() self.logKernelSizes.toolTip = 'Laplacian of Gaussian filter kernel sizes (mm), separated by comma. ' \ 'If empty, no LoG filtering will be applied.' filteringFormLayout.addRow('LoG kernel sizes', self.logKernelSizes) # Wavelet self.waveletCheckBox = qt.QCheckBox() self.waveletCheckBox.checked = 0 self.waveletCheckBox.toolTip = 'If checked, PyRadiomics will calculate features on the image after applying ' \ 'wavelet transformation' filteringFormLayout.addRow('Wavelet-based features', self.waveletCheckBox) # # Feature calculation settings # settingsCollapsibleButton = ctk.ctkCollapsibleButton() settingsCollapsibleButton.text = 'Settings' settingsCollapsibleButton.collapsed = False manualCustomizationFormLayout.addWidget(settingsCollapsibleButton) # Layout within the dummy collapsible button settingsFormLayout = qt.QFormLayout(settingsCollapsibleButton) # bin width, defaults to 25 self.binWidthSliderWidget = ctk.ctkSliderWidget() self.binWidthSliderWidget.singleStep = 1 self.binWidthSliderWidget.decimals = 2 self.binWidthSliderWidget.minimum = 0.01 self.binWidthSliderWidget.maximum = 100 self.binWidthSliderWidget.value = 25 self.binWidthSliderWidget.toolTip = 'Set the bin width' settingsFormLayout.addRow('Bin Width', self.binWidthSliderWidget) # symmetricalGLCM flag, defaults to false self.symmetricalGLCMCheckBox = qt.QCheckBox() self.symmetricalGLCMCheckBox.checked = 1 self.symmetricalGLCMCheckBox.toolTip = 'Use a symmetrical GLCM matrix' settingsFormLayout.addRow('Enforce Symmetrical GLCM', self.symmetricalGLCMCheckBox) # # Parameter File Customization # self.parameterCustomizationGroupBox = qt.QGroupBox( 'Parameter File Customization') self.parameterCustomizationGroupBox.visible = False # self.parameterCustomizationGroupBox.checkable = True customizationFormLayout.addWidget(self.parameterCustomizationGroupBox) parameterCustomizationFormLayout = qt.QFormLayout( self.parameterCustomizationGroupBox) # Path edit to select parameter file self.parameterFilePathLineEdit = ctk.ctkPathLineEdit() parameterCustomizationFormLayout.addRow("Parameter File", self.parameterFilePathLineEdit)
def setup(self): self.detailsPopup = None self.setDetailsPopup(self.getSavedDICOMDetailsWidgetType()()) # XXX Slicer 4.5 - Remove these. Here only for backward compatibility. self.dicomBrowser = self.detailsPopup.dicomBrowser self.tables = self.detailsPopup.tables layoutManager = slicer.app.layoutManager() if layoutManager is not None: layoutManager.layoutChanged.connect(self.onLayoutChanged) # connect to the 'Show DICOM Browser' button self.showBrowserButton = qt.QPushButton('Show DICOM database browser') self.showBrowserButton.setCheckable(True) self.layout.addWidget(self.showBrowserButton) self.showBrowserButton.setStyleSheet("font:Bold;" "font-size:12px") self.showBrowserButton.connect('clicked()', self.toggleDetailsPopup) self.loadedDataLabel = qt.QLabel("Loaded data") self.loadedDataLabel.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed) self.layout.addWidget(self.loadedDataLabel) font = qt.QFont() font.setBold(True) font.setPointSize(12) self.loadedDataLabel.setFont(font) self.layout.addWidget(self.loadedDataLabel) self.subjectHierarchyTree = slicer.qMRMLSubjectHierarchyTreeView() self.layout.addWidget(self.subjectHierarchyTree) self.subjectHierarchyTree.setMRMLScene(slicer.mrmlScene) self.subjectHierarchyTree.currentItemChanged.connect( self.onCurrentItemChanged) self.subjectHierarchyTree.currentItemModified.connect( self.onCurrentItemModified) self.subjectHierarchyCurrentVisibility = False self.subjectHierarchyTree.setColumnHidden( self.subjectHierarchyTree.model().idColumn, True) self.browserSettingsWidget = ctk.ctkCollapsibleGroupBox() self.browserSettingsWidget.title = "Browser settings" self.layout.addWidget(self.browserSettingsWidget) self.browserSettingsWidget.collapsed = True self.browserSettingsWidget.setLayout(qt.QFormLayout()) self.directoryButton = ctk.ctkDirectoryButton() self.browserSettingsWidget.layout().addRow("Local database:", self.directoryButton) self.directoryButton.directoryChanged.connect( self.onDatabaseDirectoryButtonChanged) self.onDatabaseDirectoryDetailsPopupChanged( self.detailsPopup.dicomBrowser.databaseDirectory) self.tableDensityComboBox = qt.QComboBox() self.browserSettingsWidget.layout().addRow("Table density:", self.tableDensityComboBox) self.tableDensityComboBox.currentIndexChanged.connect( self.onTableDensityChanged) self.updateTableDensityComboBox() self.horizontalCheckBox = qt.QCheckBox() self.horizontalCheckBox.checked = settingsValue( 'DICOM/horizontalTables', 0, converter=int) self.horizontalCheckBox.stateChanged.connect( self.onHorizontalStateChanged) self.browserSettingsWidget.layout().addRow("Horizontal:", self.horizontalCheckBox) self.browserPersistentCheckBox = qt.QCheckBox() self.browserPersistentCheckBox.checked = settingsValue( 'DICOM/BrowserPersistent', False, converter=toBool) self.browserPersistentCheckBox.stateChanged.connect( self.onBrowserPersistentStateChanged) self.browserSettingsWidget.layout().addRow( "Browser persistent:", self.browserPersistentCheckBox) self.additionalSettingsLayout = qt.QHBoxLayout() # # servers # # testing server - not exposed (used for development) self.localFrame = ctk.ctkCollapsibleButton(self.parent) self.localFrame.setLayout(qt.QVBoxLayout()) self.localFrame.setText("Servers") self.layout.addWidget(self.localFrame) self.localFrame.collapsed = True self.toggleServer = qt.QPushButton("Start Testing Server") self.localFrame.layout().addWidget(self.toggleServer) self.toggleServer.connect('clicked()', self.onToggleServer) self.verboseServer = qt.QCheckBox("Verbose") self.localFrame.layout().addWidget(self.verboseServer) # advanced options - not exposed to end users # developers can uncomment these lines to access testing server self.toggleServer.hide() self.verboseServer.hide() # Listener settings = qt.QSettings() self.toggleListener = qt.QPushButton() self.toggleListener.checkable = True if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect( 'stateChanged(QProcess::ProcessState)', self.onListenerStateChanged) else: self.toggleListener.text = "Start Listener" self.localFrame.layout().addWidget(self.toggleListener) self.toggleListener.connect('clicked()', self.onToggleListener) self.runListenerAtStart = qt.QCheckBox( "Start Listener when Slicer Starts") self.localFrame.layout().addWidget(self.runListenerAtStart) self.runListenerAtStart.checked = settingsValue( 'DICOM/RunListenerAtStart', False, converter=toBool) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # connect to the main window's dicom button mw = slicer.util.mainWindow() if mw: try: action = slicer.util.findChildren(mw, name='LoadDICOMAction')[0] action.connect('triggered()', self.onOpenDetailsPopup) except IndexError: logging.error( 'Could not connect to the main window DICOM button') if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) # the recent activity frame self.activityFrame = ctk.ctkCollapsibleButton(self.parent) self.activityFrame.collapsed = True self.activityFrame.setLayout(qt.QVBoxLayout()) self.activityFrame.setText("Recent DICOM Activity") self.layout.addWidget(self.activityFrame) self.recentActivity = DICOMLib.DICOMRecentActivityWidget( self.activityFrame, detailsPopup=self.detailsPopup) self.activityFrame.layout().addWidget(self.recentActivity) self.requestUpdateRecentActivity()
def setupOptionsFrame(self): self.autoUpdateCheckBox = qt.QCheckBox("Auto-update") self.autoUpdateCheckBox.setToolTip( "Auto-update results preview when input segments change.") self.autoUpdateCheckBox.setChecked(True) self.autoUpdateCheckBox.setEnabled(False) self.previewButton = qt.QPushButton("Initialize") self.previewButton.objectName = self.__class__.__name__ + 'Preview' self.previewButton.setToolTip("Preview complete segmentation") # qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # fails on some systems, therefore set the policies using separate method calls qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) self.previewButton.setSizePolicy(qSize) previewFrame = qt.QHBoxLayout() previewFrame.addWidget(self.autoUpdateCheckBox) previewFrame.addWidget(self.previewButton) self.scriptedEffect.addLabeledOptionsWidget("Preview:", previewFrame) self.previewOpacitySlider = ctk.ctkSliderWidget() self.previewOpacitySlider.setToolTip( "Adjust visibility of results preview.") self.previewOpacitySlider.minimum = 0 self.previewOpacitySlider.maximum = 1.0 self.previewOpacitySlider.value = 0.0 self.previewOpacitySlider.singleStep = 0.05 self.previewOpacitySlider.pageStep = 0.1 self.previewOpacitySlider.spinBoxVisible = False self.previewShow3DButton = qt.QPushButton("Show 3D") self.previewShow3DButton.setToolTip("Preview results in 3D.") self.previewShow3DButton.setCheckable(True) displayFrame = qt.QHBoxLayout() displayFrame.addWidget(qt.QLabel("inputs")) displayFrame.addWidget(self.previewOpacitySlider) displayFrame.addWidget(qt.QLabel("results")) displayFrame.addWidget(self.previewShow3DButton) self.scriptedEffect.addLabeledOptionsWidget("Display:", displayFrame) self.cancelButton = qt.QPushButton("Cancel") self.cancelButton.objectName = self.__class__.__name__ + 'Cancel' self.cancelButton.setToolTip("Clear preview and cancel auto-complete") self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Replace segments by previewed result") finishFrame = qt.QHBoxLayout() finishFrame.addWidget(self.cancelButton) finishFrame.addWidget(self.applyButton) self.scriptedEffect.addOptionsWidget(finishFrame) self.previewButton.connect('clicked()', self.onPreview) self.cancelButton.connect('clicked()', self.onCancel) self.applyButton.connect('clicked()', self.onApply) self.previewOpacitySlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.previewShow3DButton.connect("toggled(bool)", self.updateMRMLFromGUI) self.autoUpdateCheckBox.connect("stateChanged(int)", self.updateMRMLFromGUI)
def setup(self): ScriptedLoadableModuleWidget.setup(self) #################### # 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 = "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) # # input magnitude volume # self.magnitudevolume = slicer.qMRMLNodeComboBox() self.magnitudevolume.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.magnitudevolume.selectNodeUponCreation = True self.magnitudevolume.addEnabled = True self.magnitudevolume.removeEnabled = True self.magnitudevolume.noneEnabled = True self.magnitudevolume.showHidden = False self.magnitudevolume.showChildNodeTypes = False self.magnitudevolume.setMRMLScene(slicer.mrmlScene) self.magnitudevolume.setToolTip("Select the magnitude image") parametersFormLayout.addRow("Magnitude Image: ", self.magnitudevolume) # # input phase volume # self.phasevolume = slicer.qMRMLNodeComboBox() self.phasevolume.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.phasevolume.selectNodeUponCreation = True self.phasevolume.addEnabled = True self.phasevolume.removeEnabled = True self.phasevolume.noneEnabled = True self.phasevolume.showHidden = False self.phasevolume.showChildNodeTypes = False self.phasevolume.setMRMLScene(slicer.mrmlScene) self.phasevolume.setToolTip("Select the phase image") parametersFormLayout.addRow("Phase Image: ", self.phasevolume) # # True phase points (vtkMRMLMarkupsFiducialNode) # self.truePhasePointSelector = slicer.qMRMLNodeComboBox() self.truePhasePointSelector.nodeTypes = (( "vtkMRMLMarkupsFiducialNode"), "") self.truePhasePointSelector.addEnabled = True self.truePhasePointSelector.removeEnabled = False self.truePhasePointSelector.noneEnabled = True self.truePhasePointSelector.showHidden = False self.truePhasePointSelector.renameEnabled = True self.truePhasePointSelector.showChildNodeTypes = False self.truePhasePointSelector.setMRMLScene(slicer.mrmlScene) self.truePhasePointSelector.setToolTip( "Pick up a Markups node listing a true phase point.") parametersFormLayout.addRow("True Phase Point: ", self.truePhasePointSelector) # # Select which scene view to track # self.sceneViewButton_red = qt.QRadioButton('Red') self.sceneViewButton_yellow = qt.QRadioButton('Yellow') self.sceneViewButton_green = qt.QRadioButton('Green') self.sceneViewButton_green.checked = 1 layout = qt.QHBoxLayout(parametersCollapsibleButton) layout.addWidget(self.sceneViewButton_red) layout.addWidget(self.sceneViewButton_yellow) layout.addWidget(self.sceneViewButton_green) parametersFormLayout.addRow("Scene view:", layout) # Auto slice selecter self.autosliceselecterButton = qt.QPushButton("Segment Needle") self.autosliceselecterButton.toolTip = "Observe slice from scene viewer" self.autosliceselecterButton.enabled = False parametersFormLayout.addRow(self.autosliceselecterButton) realtimebutton = qt.QHBoxLayout() # # Start Real-Time Tracking # self.trackingButton = qt.QPushButton("Start Simulated Tracking") self.trackingButton.toolTip = "Observe slice from scene viewer" self.trackingButton.enabled = False self.trackingButton.clicked.connect(self.SimStartTimer) realtimebutton.addWidget(self.trackingButton) self.SimTimer = qt.QTimer() self.SimTimer.timeout.connect(self.onRealTimeTracking) # Stop Real-Time Tracking self.stopsequence = qt.QPushButton('Stop Simulated Tracking') self.stopsequence.clicked.connect(self.SimStopTimer) realtimebutton.addWidget(self.stopsequence) parametersFormLayout.addRow("", realtimebutton) # Add vertical spacer self.layout.addStretch(1) #################################### ## ## ## Scanner Remote Control Protocol## ## ## #################################### SRCcollapsibleButton = ctk.ctkCollapsibleButton() SRCcollapsibleButton.text = "Scanner Remote Control Protocol" self.layout.addWidget(SRCcollapsibleButton) SRCFormLayout = qt.QFormLayout(SRCcollapsibleButton) realtimebutton = qt.QHBoxLayout() # FPS self.fpsBox = qt.QDoubleSpinBox() self.fpsBox.setSingleStep(0.1) self.fpsBox.setMaximum(40) self.fpsBox.setMinimum(0.1) self.fpsBox.setSuffix(" FPS") self.fpsBox.value = 0.5 SRCFormLayout.addRow("Update Rate:", self.fpsBox) # Start SRC Real-Time Tracking self.SRCtrackingButton = qt.QPushButton("Start Live Tracking") self.SRCtrackingButton.toolTip = "Observe slice from scene viewer" self.SRCtrackingButton.enabled = False self.SRCtrackingButton.clicked.connect(self.StartTimer) realtimebutton.addWidget(self.SRCtrackingButton) self.timer = qt.QTimer() self.timer.timeout.connect(self.SRCRealTimeTracking) # Stop Real-Time Tracking self.stopsequence = qt.QPushButton('Stop Live Tracking') self.stopsequence.clicked.connect(self.StopTimer) realtimebutton.addWidget(self.stopsequence) SRCFormLayout.addRow("", realtimebutton) # Add vertical spacer self.layout.addStretch(1) ###################### # Advanced Parameters# ###################### advancedCollapsibleButton = ctk.ctkCollapsibleButton() advancedCollapsibleButton.text = "Advanced" advancedCollapsibleButton.collapsed = 1 self.layout.addWidget(advancedCollapsibleButton) # Layout within the collapsible button advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton) # # 2D slice value # self.imageSliceSliderWidget = ctk.ctkSliderWidget() self.imageSliceSliderWidget.singleStep = 1 self.imageSliceSliderWidget.minimum = 0 self.imageSliceSliderWidget.maximum = 70 self.imageSliceSliderWidget.value = 1 self.imageSliceSliderWidget.setToolTip("Select 2D slice") advancedFormLayout.addRow("2D Slice ", self.imageSliceSliderWidget) # # Mask Threshold # self.maskThresholdWidget = ctk.ctkSliderWidget() self.maskThresholdWidget.singleStep = 1 self.maskThresholdWidget.minimum = 0 self.maskThresholdWidget.maximum = 100 self.maskThresholdWidget.value = 20 self.maskThresholdWidget.setToolTip( "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero." ) advancedFormLayout.addRow("Mask Threshold ", self.maskThresholdWidget) # # Ridge operator filter # self.ridgeOperatorWidget = ctk.ctkSliderWidget() self.ridgeOperatorWidget.singleStep = 1 self.ridgeOperatorWidget.minimum = 0 self.ridgeOperatorWidget.maximum = 100 self.ridgeOperatorWidget.value = 5 self.ridgeOperatorWidget.setToolTip( "set up meijering filter threshold") advancedFormLayout.addRow("Ridge Operator Threshold", self.ridgeOperatorWidget) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Manual apply Button # self.applyButton = qt.QPushButton("Manual") self.applyButton.toolTip = "Select slice manually" self.applyButton.enabled = False advancedFormLayout.addRow(self.applyButton) # Refresh Apply button state self.onSelect() # # check box to trigger preview final processed image # self.enableprocessedimagecheckbox = qt.QCheckBox() self.enableprocessedimagecheckbox.checked = 0 self.enableprocessedimagecheckbox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) advancedFormLayout.addRow("Enable Processed Image", self.enableprocessedimagecheckbox) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.trackingButton.connect('clicked(bool)', self.onRealTimeTracking) self.SRCtrackingButton.connect('clicked(bool)', self.SRCRealTimeTracking) self.autosliceselecterButton.connect('clicked(bool)', self.autosliceselecter) self.magnitudevolume.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.phasevolume.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.lastMatrix = vtk.vtkMatrix4x4() self.timer = qt.QTimer() self.timer.timeout.connect(self.SRCRealTimeTracking) self.SimTimer = qt.QTimer() self.SimTimer.timeout.connect(self.onRealTimeTracking)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # File area # filesCollapsibleButton = ctk.ctkCollapsibleButton() filesCollapsibleButton.text = "Files" filesCollapsibleButton.collapsed = False self.layout.addWidget(filesCollapsibleButton) # Layout within the files collapsible button filesFormLayout = qt.QFormLayout(filesCollapsibleButton) self.fileModel = qt.QStandardItemModel() self.fileTable = qt.QTableView() self.fileTable.horizontalHeader().stretchLastSection = True self.fileTable.horizontalHeader().visible = False self.fileTable.setModel(self.fileModel) filesFormLayout.addRow(self.fileTable) buttonLayout = qt.QHBoxLayout() self.addByBrowsingButton = qt.QPushButton("Browse for files") self.clearButton = qt.QPushButton("Clear") buttonLayout.addWidget(self.addByBrowsingButton) buttonLayout.addWidget(self.clearButton) filesFormLayout.addRow(buttonLayout) self.propertiesLabel = qt.QLabel() filesFormLayout.addRow(self.propertiesLabel) # # output area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" outputCollapsibleButton.collapsed = False self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode",] self.outputSelector.showChildNodeTypes = False self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.selectNodeUponCreation = True self.outputSelector.noneEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.renameEnabled = True self.outputSelector.addEnabled = True self.outputSelector.setMRMLScene( slicer.mrmlScene ) self.outputSelector.setToolTip( "Pick the output volume to populate or None to autogenerate." ) outputFormLayout.addRow("Output Volume: ", self.outputSelector) self.spacing = slicer.qMRMLCoordinatesWidget() self.spacing.decimalsOption = ctk.ctkDoubleSpinBox.DecimalsByKey | ctk.ctkDoubleSpinBox.DecimalsByShortcuts | ctk.ctkDoubleSpinBox.DecimalsByValue self.spacing.minimum = 0.0 self.spacing.maximum = 1000000000.0 self.spacing.quantity = "length" self.spacing.unitAwareProperties = slicer.qMRMLCoordinatesWidget.Precision | slicer.qMRMLCoordinatesWidget.Prefix | slicer.qMRMLCoordinatesWidget.Scaling | slicer.qMRMLCoordinatesWidget.Suffix self.spacing.decimals = 8 self.spacing.coordinates = "1,1,1" self.spacing.toolTip = "Set the colunm, row, slice spacing in mm; original spacing not including downsample" outputFormLayout.addRow("Spacing: ", self.spacing) self.downsample = qt.QCheckBox() self.downsample.toolTip = "Reduces data size by half in each dimension by skipping every other pixel and slice (uses about 1/8 memory)" outputFormLayout.addRow("Downsample: ", self.downsample) self.reverse = qt.QCheckBox() self.reverse.toolTip = "Read the images in reverse order" outputFormLayout.addRow("Reverse: ", self.reverse) self.sliceSkip = ctk.ctkDoubleSpinBox() self.sliceSkip.decimals = 0 self.sliceSkip.minimum = 0 self.sliceSkip.toolTip = "Skips the selected number of slices (use, for example, on long thin samples with more slices than in-plane resolution)" outputFormLayout.addRow("Slice skip: ", self.sliceSkip) self.loadButton = qt.QPushButton("Load files") outputFormLayout.addRow(self.loadButton) # # Add by name area # addByNameCollapsibleButton = ctk.ctkCollapsibleButton() addByNameCollapsibleButton.text = "Add files by name" addByNameCollapsibleButton.collapsed = True addByNameFormLayout = qt.QFormLayout(addByNameCollapsibleButton) # Don't enable Add by name for now - let's see if it's actually needed # self.layout.addWidget(addByNameCollapsibleButton) forExample = """ directoryPath = '/Volumes/SSD2T/data/SlicerMorph/Sample_for_steve/1326_Rec' pathFormat = '%s/1326__rec%04d.png' start, end = (50, 621) """ self.archetypePathEdit = ctk.ctkPathLineEdit() self.archetypePathEdit.filters = ctk.ctkPathLineEdit().Files addByNameFormLayout.addRow("Archetype file", self.archetypePathEdit) self.archetypeFormat = qt.QLineEdit() addByNameFormLayout.addRow("Name format", self.archetypeFormat) self.indexRange = ctk.ctkRangeWidget() self.indexRange.decimals = 0 self.indexRange.maximum = 0 addByNameFormLayout.addRow("Index range", self.indexRange) self.generateNamesButton = qt.QPushButton("Apply") self.generateNamesButton.toolTip = "Run the algorithm." self.generateNamesButton.enabled = False addByNameFormLayout.addRow(self.generateNamesButton) # connections self.addByBrowsingButton.connect('clicked()', self.addByBrowsing) self.clearButton.connect('clicked()', self.onClear) self.archetypePathEdit.connect('currentPathChanged(QString)', self.validateInput) self.archetypePathEdit.connect('currentPathChanged(QString)', self.updateGUIFromArchetype) self.archetypeFormat.connect('textChanged(QString)', self.validateInput) self.generateNamesButton.connect('clicked()', self.onGenerateNames) # self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.validateInput) # TODO - this is missing self.loadButton.connect('clicked()', self.onLoadButton) # refill last selection self.archetypePathEdit.currentPath = slicer.util.settingsValue("ImageStacks/lastArchetypePath", "") # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.validateInput()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = MyModuleLogic() # ------ 1. CREATE LAYOUT AND BUTTONS ------ # Layout setup: 3D Only self.layoutManager = slicer.app.layoutManager() self.layoutManager.setLayout( slicer.vtkMRMLLayoutNode.SlicerLayoutOneUp3DView) # # LOAD DATA # # Create layout collapsibleButtonLoad = ctk.ctkCollapsibleButton() collapsibleButtonLoad.text = "LOAD DATA" # title for layout self.layout.addWidget(collapsibleButtonLoad) formLayout_load = qt.QFormLayout(collapsibleButtonLoad) # Segment 1 Selector self.segment1_pathSelector = ctk.ctkPathLineEdit() self.segment1_pathSelector.enabled = True self.segment1_pathSelector.setMaximumWidth(400) self.segment1_pathSelector.currentPath = slicer.modules.mymodule.path.replace( "MyModule.py", "") + 'Data/Liver1.stl' formLayout_load.addRow("Segment 1: ", self.segment1_pathSelector) # Segment 1 Selector self.segment2_pathSelector = ctk.ctkPathLineEdit() self.segment2_pathSelector.enabled = True self.segment2_pathSelector.setMaximumWidth(400) self.segment2_pathSelector.currentPath = slicer.modules.mymodule.path.replace( "MyModule.py", "") + 'Data/Liver1beforeMM.stl' formLayout_load.addRow("Segment 2: ", self.segment2_pathSelector) # Button to load segments self.loadSegmentsButton = qt.QPushButton( "LOAD MODELS AS SEGMENTS") # text in button self.loadSegmentsButton.toolTip = "Load segments as segments" # hint text for button (appears when cursor is above the button for more than one second) self.loadSegmentsButton.enabled = True # if True it can be clicked formLayout_load.addRow( self.loadSegmentsButton) # include button in layout # # ALIGNMENT # # Create Layout collapsibleButtonAlignment = ctk.ctkCollapsibleButton() collapsibleButtonAlignment.text = "ALIGNMENT" self.layout.addWidget(collapsibleButtonAlignment) formLayout_alignment = qt.QFormLayout(collapsibleButtonAlignment) # Button for masks alignment self.alignSegmentsButton = qt.QPushButton( "ALIGN MODELS") # text in button self.alignSegmentsButton.toolTip = "Align segments" # hint text for button (appears when cursor is above the button for more than one second) self.alignSegmentsButton.enabled = True formLayout_alignment.addRow(self.alignSegmentsButton) # COMPARISON BETWEEN MASKS # # SORENSEN-DICE COEFFICIENT & HOUSDORFF DISTANCE BUTTONS # # Create layout collapsibleButtonComparison = ctk.ctkCollapsibleButton() collapsibleButtonComparison.text = "COMPARISON" # title for layout self.layout.addWidget(collapsibleButtonComparison) formLayout_comparison = qt.QFormLayout(collapsibleButtonComparison) # Button to obtain the Sorensen-Dice Coefficient self.diceCoeffButton = qt.QPushButton( "SORENSEN-DICE COEFFICIENT") # text in button self.diceCoeffButton.toolTip = "Sorensen-Dice Coefficient" # hint text for button (appears when the cursor is above the button for more than one second) self.diceCoeffButton.enabled = True # if true it can be clicked formLayout_comparison.addRow( self.diceCoeffButton) # include button in layout #Button to obtain the Hausdorff Distance self.hausDistButton = qt.QPushButton( "HAUSDORFF DISTANCE") # text in button self.hausDistButton.toolTip = qt.QPushButton( "Hausdorff Distance" ) # hint text for button (appears when the cursor is above the button for more than a second) self.hausDistButton.enabled = True # if true it can be clicked formLayout_comparison.addRow( self.hausDistButton) # include button in layout # # VISUALIZATION # # Create layout collapsibleButtonVisualization = ctk.ctkCollapsibleButton() collapsibleButtonVisualization.text = "VISUALIZATION" # title for layout self.layout.addWidget(collapsibleButtonVisualization) formLayout_visualization = qt.QFormLayout( collapsibleButtonVisualization) # # Segment visibility layout # # Create collapsible button inside layout segmentVisibility_GroupBox = ctk.ctkCollapsibleGroupBox() segmentVisibility_GroupBox.setTitle( "MODEL VISIBILITY") # title for collapsible button segmentVisibility_GroupBox.collapsed = False # if True it appears collapsed formLayout_visualization.addRow( segmentVisibility_GroupBox) # add collapsible button to layout # Create layout inside collapsible button segmentVisibility_GroupBox_Layout = qt.QFormLayout( segmentVisibility_GroupBox) # Create horizontal section segmentVisibilityLayout_1 = qt.QHBoxLayout() segmentVisibility_GroupBox_Layout.addRow( segmentVisibilityLayout_1) # insert section in current layout # Show or Hide Segment 1 in 3D scene self.segment1_checkBox = qt.QCheckBox('Segment 1') # text in checkbox self.segment1_checkBox.checked = True # if True it is initially checked self.segment1_checkBox.enabled = True # if True it can be checked segmentVisibilityLayout_1.addWidget( self.segment1_checkBox) # add checkbox to layout # Show or Hide Segment 2 in 3D scene self.segment2_checkBox = qt.QCheckBox('Segment 2') # text in checkbox self.segment2_checkBox.checked = True # if True it is initially checked self.segment2_checkBox.checked = True # if True it can be checked segmentVisibilityLayout_1.addWidget( self.segment2_checkBox) # add checkbox to layout # # Segment transparency layout # # Create collapsible button inside layout segmentOpacity_GroupBox = ctk.ctkCollapsibleGroupBox() segmentOpacity_GroupBox.setTitle( "MODEL OPACITY") # title for collapsible button segmentOpacity_GroupBox.collapsed = False # if True it appears collapsed formLayout_visualization.addRow( segmentOpacity_GroupBox) # add collapsible button to layout # Create layout inside collapsible button segmentOpacity_GroupBox_Layout = qt.QFormLayout( segmentOpacity_GroupBox) # Create an opacity Value Slider - Segment 1 self.opacityValueSliderWidget_1 = ctk.ctkSliderWidget() self.opacityValueSliderWidget_1.singleStep = 5 # step for range of values to be selected self.opacityValueSliderWidget_1.minimum = 0 # minimum value self.opacityValueSliderWidget_1.maximum = 100 # maximum value self.opacityValueSliderWidget_1.value = 100 # initial value segmentOpacity_GroupBox_Layout.addRow( "[%]: ", self.opacityValueSliderWidget_1) # add slider to layout # Create an opacity Value Slider - Segment 2 self.opacityValueSliderWidget_2 = ctk.ctkSliderWidget() self.opacityValueSliderWidget_2.singleStep = 5 # step for range of values to be selected self.opacityValueSliderWidget_2.minimum = 0 # minimum value self.opacityValueSliderWidget_2.maximum = 100 # maximum value self.opacityValueSliderWidget_2.value = 100 # initial value segmentOpacity_GroupBox_Layout.addRow( "[%]: ", self.opacityValueSliderWidget_2) # add slider to layout # # COLOR MAP # collapsibleButtonColorMap = ctk.ctkCollapsibleButton() collapsibleButtonColorMap.text = "COLOR MAP" self.layout.addWidget(collapsibleButtonColorMap) formLayout_colorMap = qt.QFormLayout(collapsibleButtonColorMap) self.showColorMapButton = qt.QPushButton( "SHOW COLOR MAP") # text in button self.showColorMapButton.toolTip = "Align segments" # hint text for button (appears when cursor is above the button for more than one second) self.showColorMapButton.enabled = True formLayout_colorMap.addRow(self.showColorMapButton) # Displayed Range group box self.displayedRange_GroupBox = ctk.ctkCollapsibleGroupBox() self.displayedRange_GroupBox.setTitle("Displayed Range") self.displayedRange_GroupBox.collapsed = False self.displayedRange_GroupBox.enabled = False formLayout_colorMap.addRow(self.displayedRange_GroupBox) displayedRange_GroupBox_Layout = qt.QFormLayout( self.displayedRange_GroupBox) displayedRange_H_Layout = qt.QHBoxLayout() displayedRange_GroupBox_Layout.addRow(displayedRange_H_Layout) ## Minimum value - displayed range self.minDisplayedRange_SpinBox = qt.QDoubleSpinBox() self.minDisplayedRange_SpinBox.setMaximum(40.0) self.minDisplayedRange_SpinBox.setMinimum(-40.0) self.minDisplayedRange_SpinBox.setSingleStep(0.1) self.minDisplayedRange_SpinBox.enabled = True self.minDisplayedRange_SpinBox.value = 0.0 displayedRange_H_Layout.addWidget(self.minDisplayedRange_SpinBox) ## Displayed range Slider self.displayedRange_SliderWidget = ctk.ctkDoubleRangeSlider() self.displayedRange_SliderWidget.setValues(0.0, 10.0) self.displayedRange_SliderWidget.orientation = 1 self.displayedRange_SliderWidget.singleStep = 0.1 self.displayedRange_SliderWidget.minimum = -40.0 self.displayedRange_SliderWidget.maximum = 40.0 displayedRange_H_Layout.addWidget(self.displayedRange_SliderWidget) ## Maximum value - displayed range self.maxDisplayedRange_SpinBox = qt.QDoubleSpinBox() self.maxDisplayedRange_SpinBox.setMaximum(40.0) self.maxDisplayedRange_SpinBox.setMinimum(-40.0) self.maxDisplayedRange_SpinBox.setSingleStep(0.1) self.maxDisplayedRange_SpinBox.enabled = True self.maxDisplayedRange_SpinBox.value = 10.0 displayedRange_H_Layout.addWidget(self.maxDisplayedRange_SpinBox) # Scalar Bar Visibility Checkbox self.ScalarBar_visibility_checkBox = qt.QCheckBox('Scalar Bar Visible') self.ScalarBar_visibility_checkBox.checked = True displayedRange_GroupBox_Layout.addRow( self.ScalarBar_visibility_checkBox) # Add vertical spacing self.layout.addStretch(1) # ------ 2. CONNECT BUTTONS WITH FUNCTIONS ------ # Connect each button with a function self.loadSegmentsButton.connect( 'clicked(bool)', self.onloadSegmentsButton ) # when the button is pressed we call the function onLoadSegment1Button self.segment1_checkBox.connect('stateChanged(int)', self.onupdateSegment1Visibility) self.segment2_checkBox.connect('stateChanged(int)', self.onupdateSegment2Visibility) self.opacityValueSliderWidget_1.connect("valueChanged(double)", self.onupdateSegment1Opacity) self.opacityValueSliderWidget_2.connect("valueChanged(double)", self.onupdateSegment2Opacity) self.alignSegmentsButton.connect('clicked(bool)', self.onAlignSegmentsButton) self.diceCoeffButton.connect('clicked(bool)', self.onDiceCoeffButton) self.hausDistButton.connect('clicked(bool)', self.onHausdorffDistButton) self.showColorMapButton.connect('clicked(bool)', self.onShowColorMapButton) self.displayedRange_SliderWidget.connect( "valuesChanged(double,double)", self.onDisplayedRangeSliderChanged) self.minDisplayedRange_SpinBox.connect( "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged) self.maxDisplayedRange_SpinBox.connect( "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged) self.ScalarBar_visibility_checkBox.connect( 'stateChanged(int)', self.onScalarBarVisibilityChecked)
def _createSmall(self): """Make the internals of the widget to display in the Data Probe frame (lower left of slicer main window by default)""" # this method makes SliceView Annotation self.sliceAnnotations = DataProbeLib.SliceAnnotations() # goto module button self.goToModule = qt.QPushButton('->', self.frame) self.goToModule.setToolTip( 'Go to the DataProbe module for more information and options') self.frame.layout().addWidget(self.goToModule) self.goToModule.connect("clicked()", self.onGoToModule) # hide this for now - there's not much to see in the module itself self.goToModule.hide() # image view self.showImageBox = qt.QCheckBox('Show Zoomed Slice', self.frame) self.frame.layout().addWidget(self.showImageBox) self.showImageBox.connect("toggled(bool)", self.onShowImage) self.showImageBox.setChecked(False) self.imageLabel = qt.QLabel() # qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # fails on some systems, therefore set the policies using separate method calls qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) qSize.setVerticalPolicy(qt.QSizePolicy.Expanding) self.imageLabel.setSizePolicy(qSize) #self.imageLabel.setScaledContents(True) self.frame.layout().addWidget(self.imageLabel) self.onShowImage(False) # top row - things about the viewer itself self.viewerFrame = qt.QFrame(self.frame) self.viewerFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.viewerFrame) self.viewerColor = qt.QLabel(self.viewerFrame) self.viewerFrame.layout().addWidget(self.viewerColor) self.viewInfo = qt.QLabel() self.viewerFrame.layout().addWidget(self.viewInfo) self.viewerFrame.layout().addStretch(1) def _setFixedFontFamily(widget, family='Monospace'): font = widget.font font.setFamily(family) widget.font = font _setFixedFontFamily(self.viewInfo) # the grid - things about the layers # this method makes labels self.layerGrid = qt.QFrame(self.frame) layout = qt.QGridLayout() self.layerGrid.setLayout(layout) self.frame.layout().addWidget(self.layerGrid) layers = ('L', 'F', 'B') self.layerNames = {} self.layerIJKs = {} self.layerValues = {} for (row, layer) in enumerate(layers): col = 0 layout.addWidget(qt.QLabel(layer), row, col) col += 1 self.layerNames[layer] = qt.QLabel() layout.addWidget(self.layerNames[layer], row, col) col += 1 self.layerIJKs[layer] = qt.QLabel() layout.addWidget(self.layerIJKs[layer], row, col) col += 1 self.layerValues[layer] = qt.QLabel() layout.addWidget(self.layerValues[layer], row, col) layout.setColumnStretch(col, 100) _setFixedFontFamily(self.layerNames[layer]) _setFixedFontFamily(self.layerIJKs[layer]) _setFixedFontFamily(self.layerValues[layer]) # goto module button self.goToModule = qt.QPushButton('->', self.frame) self.goToModule.setToolTip( 'Go to the DataProbe module for more information and options') self.frame.layout().addWidget(self.goToModule) self.goToModule.connect("clicked()", self.onGoToModule) # hide this for now - there's not much to see in the module itself self.goToModule.hide()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Volume: ", self.inputSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip("Pick the output to the algorithm.") parametersFormLayout.addRow("Output Volume: ", self.outputSelector) # # threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 0.1 self.imageThresholdSliderWidget.minimum = -100 self.imageThresholdSliderWidget.maximum = 100 self.imageThresholdSliderWidget.value = 0.5 self.imageThresholdSliderWidget.setToolTip( "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero." ) parametersFormLayout.addRow("Image threshold", self.imageThresholdSliderWidget) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect() #Modyfikacja kodu # Parameters Area # parametersCollapsibleButton2 = ctk.ctkCollapsibleButton() parametersCollapsibleButton2.text = "Adjust" self.layout.addWidget(parametersCollapsibleButton2) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton2) # # input model selector # self.inputSelector2 = slicer.qMRMLNodeComboBox() self.inputSelector2.nodeTypes = ["vtkMRMLModelNode"] self.inputSelector2.selectNodeUponCreation = True self.inputSelector2.addEnabled = False self.inputSelector2.removeEnabled = False self.inputSelector2.noneEnabled = False self.inputSelector2.showHidden = False self.inputSelector2.showChildNodeTypes = False self.inputSelector2.setMRMLScene(slicer.mrmlScene) self.inputSelector2.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Model: ", self.inputSelector2) # # opacity value # self.imageOpacitySliderWidget = ctk.ctkSliderWidget() self.imageOpacitySliderWidget.singleStep = 0.1 self.imageOpacitySliderWidget.minimum = 0 self.imageOpacitySliderWidget.maximum = 100 self.imageOpacitySliderWidget.value = 50 self.imageOpacitySliderWidget.setToolTip("Set opacity value.") parametersFormLayout.addRow("Image threshold", self.imageOpacitySliderWidget) # # Apply Button # self.applyButton1 = qt.QPushButton("Apply") self.applyButton1.toolTip = "Run the algorithm." self.applyButton1.enabled = False parametersFormLayout.addRow(self.applyButton1) # connections self.applyButton1.connect('clicked(bool)', self.onApplyButton1) self.inputSelector2.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect2) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.chartOptions = ("Count", "Volume mm^3", "Volume cc", "Min", "Max", "Mean", "Median", "StdDev") self.logic = None self.grayscaleNode = None self.labelNode = None self.fileName = None self.fileDialog = None # Instantiate and connect widgets ... # # the grayscale volume selector # self.grayscaleSelectorFrame = qt.QFrame(self.parent) self.grayscaleSelectorFrame.setLayout(qt.QHBoxLayout()) self.parent.layout().addWidget(self.grayscaleSelectorFrame) self.grayscaleSelectorLabel = qt.QLabel("Grayscale Volume: ", self.grayscaleSelectorFrame) self.grayscaleSelectorLabel.setToolTip( "Select the grayscale volume (background grayscale scalar volume node) for statistics calculations" ) self.grayscaleSelectorFrame.layout().addWidget( self.grayscaleSelectorLabel) self.grayscaleSelector = slicer.qMRMLNodeComboBox( self.grayscaleSelectorFrame) self.grayscaleSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.grayscaleSelector.selectNodeUponCreation = False self.grayscaleSelector.addEnabled = False self.grayscaleSelector.removeEnabled = False self.grayscaleSelector.noneEnabled = True self.grayscaleSelector.showHidden = False self.grayscaleSelector.showChildNodeTypes = False self.grayscaleSelector.setMRMLScene(slicer.mrmlScene) # TODO: need to add a QLabel # self.grayscaleSelector.SetLabelText( "Master Volume:" ) self.grayscaleSelectorFrame.layout().addWidget(self.grayscaleSelector) # # the label volume selector # self.labelSelectorFrame = qt.QFrame() self.labelSelectorFrame.setLayout(qt.QHBoxLayout()) self.parent.layout().addWidget(self.labelSelectorFrame) self.labelSelectorLabel = qt.QLabel() self.labelSelectorLabel.setText("Label Map: ") self.labelSelectorFrame.layout().addWidget(self.labelSelectorLabel) self.labelSelector = slicer.qMRMLNodeComboBox() self.labelSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] # todo addAttribute self.labelSelector.selectNodeUponCreation = False self.labelSelector.addEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.removeEnabled = False self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = True self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Pick the label map to edit") self.labelSelectorFrame.layout().addWidget(self.labelSelector) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Calculate Statistics." self.applyButton.enabled = False self.parent.layout().addWidget(self.applyButton) # model and view for stats table self.view = qt.QTableView() self.view.sortingEnabled = True self.parent.layout().addWidget(self.view) # Chart button self.chartFrame = qt.QFrame() self.chartFrame.setLayout(qt.QHBoxLayout()) self.parent.layout().addWidget(self.chartFrame) self.chartButton = qt.QPushButton("Chart") self.chartButton.toolTip = "Make a chart from the current statistics." self.chartFrame.layout().addWidget(self.chartButton) self.chartOption = qt.QComboBox() self.chartOption.addItems(self.chartOptions) self.chartFrame.layout().addWidget(self.chartOption) self.chartIgnoreZero = qt.QCheckBox() self.chartIgnoreZero.setText('Ignore Zero') self.chartIgnoreZero.checked = False self.chartIgnoreZero.setToolTip( 'Do not include the zero index in the chart to avoid dwarfing other bars' ) self.chartFrame.layout().addWidget(self.chartIgnoreZero) self.chartFrame.enabled = False # Save button self.exportToTableButton = qt.QPushButton("Export to table") self.exportToTableButton.toolTip = "Export statistics to table node" self.exportToTableButton.enabled = False self.parent.layout().addWidget(self.exportToTableButton) # Add vertical spacer self.parent.layout().addStretch(1) # connections self.applyButton.connect('clicked()', self.onApply) self.chartButton.connect('clicked()', self.onChart) self.exportToTableButton.connect('clicked()', self.onExportToTable) self.grayscaleSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onGrayscaleSelect) self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelSelect)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Input inputsCollapsibleButton = ctk.ctkCollapsibleButton() inputsCollapsibleButton.text = "Inputs" self.layout.addWidget(inputsCollapsibleButton) inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton) self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = True self.inputSelector.renameEnabled = True self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.setMRMLScene(slicer.mrmlScene) inputsFormLayout.addRow("Input Node: ", self.inputSelector) self.showHiddenNodesCheckBox = qt.QCheckBox('') self.showHiddenNodesCheckBox.checked = False inputsFormLayout.addRow('Show Hidden Nodes: ', self.showHiddenNodesCheckBox) # Quick info quickInfoCollapsibleButton = ctk.ctkCollapsibleButton() quickInfoCollapsibleButton.text = "Node overview" self.layout.addWidget(quickInfoCollapsibleButton) quickInfoFormLayout = qt.QFormLayout(quickInfoCollapsibleButton) self.nodeNameLabel = qt.QLabel() quickInfoFormLayout.addRow("Node name: ", self.nodeNameLabel) self.nodeIdLabel = qt.QLabel() quickInfoFormLayout.addRow("Node ID: ", self.nodeIdLabel) self.nodeTypeLabel = qt.QLabel() quickInfoFormLayout.addRow("Node type: ", self.nodeTypeLabel) referencedNodeFrame = qt.QFrame() hbox = qt.QHBoxLayout() referencedNodeFrame.setLayout(hbox) self.referencedNodeSelector = qt.QComboBox() self.referencedNodeSelectButton = qt.QPushButton("Select") hbox.addWidget(self.referencedNodeSelector) hbox.addWidget(self.referencedNodeSelectButton) quickInfoFormLayout.addRow("Referenced nodes: ", referencedNodeFrame) referencingNodeFrame = qt.QFrame() hbox = qt.QHBoxLayout() referencingNodeFrame.setLayout(hbox) self.referencingNodeSelector = qt.QComboBox() self.referencingNodeSelectButton = qt.QPushButton("Select") hbox.addWidget(self.referencingNodeSelector) hbox.addWidget(self.referencingNodeSelectButton) quickInfoFormLayout.addRow("Nodes referencing this node: ", referencingNodeFrame) self.showInfoButton = qt.QPushButton("Show node information window") quickInfoFormLayout.addRow(self.showInfoButton) self.createVariableButtonBaseText = "Create variable in Python console" self.createVariableButton = qt.QPushButton( self.createVariableButtonBaseText) quickInfoFormLayout.addRow(self.createVariableButton) # connections self.showInfoButton.connect('clicked(bool)', self.onShowInfoClicked) self.createVariableButton.connect('clicked(bool)', self.onCreateVariableClicked) self.showHiddenNodesCheckBox.connect('stateChanged(int)', self.onShowHiddenNodesChecked) self.inputSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onSelectNode) self.referencedNodeSelectButton.connect( 'clicked(bool)', self.onSelectReferencedNodeClicked) self.referencingNodeSelectButton.connect( 'clicked(bool)', self.onSelectReferencingNodeClicked) # Add vertical spacer self.layout.addStretch(1) # Initialize self.onSelectNode()
def setup(self): # # servers # # testing server - not exposed (used for development) self.localFrame = ctk.ctkCollapsibleButton(self.parent) self.localFrame.setLayout(qt.QVBoxLayout()) self.localFrame.setText("Servers") self.layout.addWidget(self.localFrame) self.localFrame.collapsed = False self.toggleServer = qt.QPushButton("Start Testing Server") self.localFrame.layout().addWidget(self.toggleServer) self.toggleServer.connect('clicked()', self.onToggleServer) self.verboseServer = qt.QCheckBox("Verbose") self.localFrame.layout().addWidget(self.verboseServer) # advanced options - not exposed to end users # developers can uncomment these lines to access testing server self.toggleServer.hide() self.verboseServer.hide() # Listener settings = qt.QSettings() self.toggleListener = qt.QPushButton() self.toggleListener.checkable = True if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect( 'stateChanged(QProcess::ProcessState)', self.onListenerStateChanged) else: self.toggleListener.text = "Start Listener" self.localFrame.layout().addWidget(self.toggleListener) self.toggleListener.connect('clicked()', self.onToggleListener) self.runListenerAtStart = qt.QCheckBox( "Start Listener when Slicer Starts") self.localFrame.layout().addWidget(self.runListenerAtStart) self.runListenerAtStart.checked = settingsValue( 'DICOM/RunListenerAtStart', False, converter=toBool) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # the Database frame (home of the ctkDICOM widget) self.dicomFrame = ctk.ctkCollapsibleButton(self.parent) self.dicomFrame.setLayout(qt.QVBoxLayout()) self.dicomFrame.setText("DICOM Database and Networking") self.layout.addWidget(self.dicomFrame) self.detailsPopup = self.getSavedDICOMDetailsWidgetType()() # XXX Slicer 4.5 - Remove these. Here only for backward compatibility. self.dicomBrowser = self.detailsPopup.dicomBrowser self.tables = self.detailsPopup.tables # connect to the 'Show DICOM Browser' button self.showBrowserButton = qt.QPushButton('Show DICOM Browser') self.dicomFrame.layout().addWidget(self.showBrowserButton) self.showBrowserButton.connect('clicked()', self.onOpenDetailsPopup) # connect to the main window's dicom button mw = slicer.util.mainWindow() if mw: try: action = slicer.util.findChildren(mw, name='LoadDICOMAction')[0] action.connect('triggered()', self.onOpenDetailsPopup) except IndexError: logging.error( 'Could not connect to the main window DICOM button') if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) # the recent activity frame self.activityFrame = ctk.ctkCollapsibleButton(self.parent) self.activityFrame.setLayout(qt.QVBoxLayout()) self.activityFrame.setText("Recent DICOM Activity") self.layout.addWidget(self.activityFrame) self.recentActivity = DICOMLib.DICOMRecentActivityWidget( self.activityFrame, detailsPopup=self.detailsPopup) self.activityFrame.layout().addWidget(self.recentActivity) self.requestUpdateRecentActivity() # Add spacer to layout self.layout.addStretch(1)
def setupFlicker(self): self.flickerTimer = self.createTimer(400, self.onFlickerToggled, singleShot=False) self.flickerCheckBox = qt.QCheckBox("Flicker") self.flickerCheckBox.checked = False