Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
  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)
Ejemplo n.º 7
0
    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()
Ejemplo n.º 8
0
    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()
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
    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()
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
  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)
Ejemplo n.º 16
0
    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()
Ejemplo n.º 17
0
    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)
Ejemplo n.º 20
0
    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()
Ejemplo n.º 21
0
    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)
Ejemplo n.º 22
0
    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)
Ejemplo n.º 23
0
  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()
Ejemplo n.º 24
0
    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)
Ejemplo n.º 25
0
    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()
Ejemplo n.º 26
0
    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()
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
    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()
Ejemplo n.º 29
0
    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)
Ejemplo n.º 30
0
 def setupFlicker(self):
   self.flickerTimer = self.createTimer(400, self.onFlickerToggled, singleShot=False)
   self.flickerCheckBox = qt.QCheckBox("Flicker")
   self.flickerCheckBox.checked = False