Beispiel #1
0
  def setup(self):
    # this is the function that implements all GUI 
    ScriptedLoadableModuleWidget.setup(self)

    # This sets the view being used to the red view only 
    slicer.app.layoutManager().setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)

    l = slicer.modules.createmodels.logic()
    self.needleModel = l.CreateNeedle(150, 0.4, 0, False)
    #This code block creates a collapsible button 
    #This defines which type of button you are using 
    self.usContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.usContainer.text = "Ultrasound Information"
    #Thiss actually creates that button
    self.layout.addWidget(self.usContainer)
    #This creates a variable that describes layout within this collapsible button 
    self.usLayout = qt.QFormLayout(self.usContainer)

    #This descirbes the type of widget 
    self.inputIPLineEdit = qt.QLineEdit()
    #This sets a placehoder example of what should be inputted to the line edit 
    self.inputIPLineEdit.setPlaceholderText("127.0.0.1")
    #This is the help tooltip 
    self.inputIPLineEdit.toolTip = "Put the IP address of your ultrasound device here"
    #This is the text that is input inot the line 
    self.IPLabel = qt.QLabel("Server IP:")
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addRow(self.IPLabel, self.inputIPLineEdit)

    #This code block is the exact same as the one above only it asks for the server port 
    self.layout.addWidget(self.usContainer)
    self.inputPortLineEdit = qt.QLineEdit()
    self.inputPortLineEdit.setPlaceholderText("18944")
    self.inputPortLineEdit.setValidator(qt.QIntValidator())
    self.inputPortLineEdit.toolTip = "Put the Port of your ultrasound device here"
    self.portLabel = qt.QLabel("Sever Port:")
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addRow(self.portLabel, self.inputPortLineEdit)

    #This is a push button 
    self.connectButton = qt.QPushButton()
    self.connectButton.setDefault(False)
    #This button says connect 
    self.connectButton.text = "Connect"
    #help tooltip that explains the funciton 
    self.connectButton.toolTip = "Connects to Ultrasound"
    #adds the widget to the layout 
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addWidget(self.connectButton)

    # Combobox for image selection
    self.imageSelector = slicer.qMRMLNodeComboBox()
    self.imageSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
    self.imageSelector.selectNodeUponCreation = True
    self.imageSelector.addEnabled = False
    self.imageSelector.removeEnabled = False
    self.imageSelector.noneEnabled = True
    self.imageSelector.showHidden = False
    self.imageSelector.showChildNodeTypes = False
    self.imageSelector.setMRMLScene( slicer.mrmlScene )
    self.imageSelector.setToolTip( "Pick the image to be used." )
    self.usLayout.addRow("US Volume: ", self.imageSelector)
    
    #add combo box for linear transform node 
    self.TransformSelector = slicer.qMRMLNodeComboBox()
    self.TransformSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
    self.TransformSelector.selectNodeUponCreation = True
    self.TransformSelector.addEnabled = False
    self.TransformSelector.removeEnabled = False
    self.TransformSelector.noneEnabled = True
    self.TransformSelector.showHidden = False
    self.TransformSelector.showChildNodeTypes = False
    self.TransformSelector.setMRMLScene( slicer.mrmlScene )
    self.TransformSelector.setToolTip( "Pick the transform representing the straw line." )
    self.usLayout.addRow("Tip to Probe: ", self.TransformSelector)
    
    self.calibrationContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.calibrationContainer.text = "Calibration Parameters"
    #Thiss actually creates that button
    self.layout.addWidget(self.calibrationContainer)
    #This creates a variable that describes layout within this collapsible button 
    self.calibrationLayout = qt.QFormLayout(self.calibrationContainer)
    
    self.segLabel = qt.QLabel()
    self.calibrationLayout.addRow(qt.QLabel("Type of segmentation:"), self.segLabel)
    
    self.recordContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.recordContainer.text = "Recording Options"
    #Thiss actually creates that button
    #This creates a variable that describes layout within this collapsible button 
    self.recordLayout = qt.QFormLayout(self.recordContainer)
    
    self.RecordButton = qt.QPushButton() 
    self.RecordButton.text = "Start Recording" 
    self.recordLayout.addWidget(self.RecordButton)
    
    self.StopRecordButton = qt.QPushButton() 
    self.StopRecordButton.text = "Stop Recording" 
    self.recordLayout.addWidget(self.StopRecordButton)
    
    self.pathInput = qt.QLineEdit()
    self.pathInput.setPlaceholderText("Enter the path to save files to")
    self.pathText = qt.QLabel("File Path:")
    self.recordLayout.addRow(self.pathText, self.pathInput)
    
    self.SaveRecordButton = qt.QPushButton() 
    self.SaveRecordButton.text = "Save Recording" 
    self.recordLayout.addWidget(self.SaveRecordButton)
    
    # This creates another collapsible button
    self.fiducialContainer = ctk.ctkCollapsibleButton()
    self.fiducialContainer.text = "Registration"

    self.fiducialLayout = qt.QFormLayout(self.fiducialContainer)

    #This is the exact same as the code block below but it freezes the US to capture a screenshot 
    self.freezeButton = qt.QPushButton()
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.freezeButton.text = "Freeze"
    else:
      self.freezeButton.text = "Place Fiducial"
    self.freezeButton.toolTip = "Freeze the ultrasound image for fiducial placement"
    self.fiducialLayout.addRow(self.freezeButton)
    self.shortcut = qt.QShortcut(qt.QKeySequence('f'), slicer.util.mainWindow())
    
    self.numFidLabel = qt.QLabel()
    self.fiducialLayout.addRow(qt.QLabel("Fiducials collected:"), self.numFidLabel)

    self.transformTable = qt.QTableWidget() 
    self.transTableItem = qt.QTableWidgetItem()
    self.fidError = qt.QLabel()
    self.transformTable.setRowCount(4)
    self.transformTable.setColumnCount(4)
    self.transformTable.horizontalHeader().hide()
    self.transformTable.verticalHeader().hide()
    self.transformTable.setItem(0,0, qt.QTableWidgetItem("1"))
    self.transformTable.setItem(0,1, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(0,2, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(0,3, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(1,0, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(1,1, qt.QTableWidgetItem("1"))
    self.transformTable.setItem(1,2, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(1,3, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(2,0, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(2,1, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(2,2, qt.QTableWidgetItem("1"))
    self.transformTable.setItem(2,3, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,0, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,1, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,2, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,3, qt.QTableWidgetItem("1"))
    self.transformTable.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.MinimumExpanding)
    self.copyIcon =qt.QIcon(":Icons/Medium/SlicerEditCopy.png")
    self.copyButton = qt.QPushButton()
    self.copyButton.setIcon(self.copyIcon)
    self.copyButton.toolTip = "Copy" 
    self.copyButton.setMaximumWidth(64)
    self.copyHbox = qt.QHBoxLayout()
    self.copyHbox.addWidget(self.copyButton)
    
    self.copyButton.enabled = False 
    if self.numFidLabel >= 2: 
      self.copyButton.enabled = True 
      
    self.fiducialLayout.addRow(qt.QLabel("Image to probe transform:"))
    self.fiducialLayout.addRow(self.transformTable)
         # Add vertical spacer
    self.layout.addStretch(1)
    
         # Add vertical spacer
    self.layout.addStretch(1)
    
    self.fiducialLayout.addRow("Copy:", self.copyHbox)
 

    self.validationContainer = ctk.ctkCollapsibleButton()
    self.validationContainer.text = "Validation"
    self.validationLayout = qt.QFormLayout(self.validationContainer)

    self.visualizeButton = qt.QPushButton('Show 3D Scene')
    self.visualizeButton.toolTip = "This button enables the 3D view for visual validation"
    self.validationLayout.addRow(self.visualizeButton)
    self.visualizeButton.connect('clicked(bool)', self.onVisualizeButtonClicked)


    self.resetButton = qt.QPushButton('Reset')
    self.resetButton.setDefault(False)
    self.resetButton.toolTip = "This Button Resets the Module"
    self.validationLayout.addRow(self.resetButton)

    # Add the containers to the parent
    self.layout.addWidget(self.usContainer)
    self.layout.addWidget(self.calibrationContainer)
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.layout.addWidget(self.recordContainer)
    self.layout.addWidget(self.fiducialContainer)

    #self.layout.addWidget(self.transformContainer)
    self.layout.addWidget(self.validationContainer)

     # Add vertical spacer
    self.layout.addStretch(1)

    # Connections
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.connectButton.connect('clicked(bool)', self.onConnectButtonClicked)
      self.freezeButton.connect('clicked(bool)', self.onConnectButtonClicked)
      self.shortcut.connect('activated()', self.onConnectButtonClicked)
    else: 
      self.shortcut.connect('activated()', self.onFiducialClicked)
      self.freezeButton.connect('clicked(bool)', self.onFiducialClicked)
    self.RecordButton.connect('clicked(bool)', self.onRecordButtonClicked)
    self.StopRecordButton.connect('clicked(bool)', self.onStopRecordButtonClicked)
    self.SaveRecordButton.connect('clicked(bool)', self.onSaveRecordButtonClicked)
    self.copyButton.connect('clicked(bool)', self.onCopyButtonClicked)
    self.inputIPLineEdit.connect('textChanged(QString)', self.onInputChanged)
    self.inputPortLineEdit.connect('textChanged(QString)', self.onInputChanged)
    self.imageSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onImageChanged)
    self.TransformSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onTransformChanged)
    self.resetButton.connect('clicked(bool)', self.onResetButtonClicked)
    # Disable buttons until conditions are met
    self.connectButton.setEnabled(True) 
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.freezeButton.setEnabled(False) 
    self.StopRecordButton.setEnabled(False)
    
    self.sceneObserverTag = slicer.mrmlScene.AddObserver(slicer.mrmlScene.NodeAddedEvent, self.onNodeAdded)
Beispiel #2
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        # Input file

        # Text + Button invoking QFileDialog
        self.inputFileLayout = qt.QHBoxLayout()
        self.inputFileLabelHeader = qt.QLabel()
        self.inputFileLabelHeader.text = "Input File: "
        self.inputFileLabelFile = qt.QLabel()
        self.inputFileLabelFile.text = "Input header.xml or .m3d"
        self.inputFileButton = qt.QPushButton()
        self.inputFileButton.text = "Browse"
        self.inputFileLayout.addWidget(self.inputFileLabelHeader)
        self.inputFileLayout.addWidget(self.inputFileLabelFile)
        self.inputFileLayout.addWidget(self.inputFileButton)
        self.layout.addLayout(self.inputFileLayout)

        #
        # Parameters Area
        #
        self.parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        self.parametersCollapsibleButton.collapsed = True
        self.parametersCollapsibleButton.text = "Parameters for legacy m3d format"
        self.layout.addWidget(self.parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersFormLayout = qt.QFormLayout(self.parametersCollapsibleButton)

        # set distance of fold curve from interior points
        self.distSlider = slicer.qMRMLSliderWidget()
        self.distSlider.setProperty('maximum', 0.6)
        self.distSlider.setProperty('minimum', 0.0)
        self.distSlider.setProperty('singleStep', 0.01)

        self.distSlider.setToolTip(
            "Parameter used in transformation from legacy s-rep to new s-rep")
        parametersFormLayout.addRow("Set distance to expand fold curve",
                                    self.distSlider)

        self.outputFolderLayout = qt.QHBoxLayout()
        self.outputFolderLabelHeader = qt.QLabel()
        self.outputFolderLabelHeader.text = "Output folder: "
        self.outputFolderLabelFile = qt.QLabel()
        self.outputFolderLabelFile.text = "Folder to save the new xml format"
        self.outputFolderButton = qt.QPushButton()
        self.outputFolderButton.text = "Browse"
        self.outputFolderLayout.addWidget(self.outputFolderLabelHeader)
        self.outputFolderLayout.addWidget(self.outputFolderLabelFile)
        self.outputFolderLayout.addWidget(self.outputFolderButton)
        parametersFormLayout.addRow(self.outputFolderLayout)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Visualize s-rep file")
        self.applyButton.toolTip = "Parse and visualize s-rep."
        self.layout.addWidget(self.applyButton)

        # Unused
        # self.boundarySurfaceRendering = qt.QCheckBox()
        # self.boundarySurfaceRendering.checked = 0
        # self.boundarySurfaceRendering.setToolTip("If checked, set the visibility of the boundary mesh")
        # self.layout.addWidget(self.boundarySurfaceRendering)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputFileButton.connect('clicked(bool)',
                                     self.onInputFileButtonClicked)
        self.outputFolderButton.connect('clicked(bool)',
                                        self.onOutputFolderButtonClicked)
        # Add vertical spacer
        self.layout.addStretch(1)
  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 setupOptionsFrame(self):
        self.thresholdSliderLabel = qt.QLabel("Threshold Range:")
        self.thresholdSliderLabel.setToolTip(
            "Set the range of the background values that should be labeled.")
        self.scriptedEffect.addOptionsWidget(self.thresholdSliderLabel)

        self.thresholdSlider = ctk.ctkRangeWidget()
        self.thresholdSlider.spinBoxAlignment = qt.Qt.AlignTop
        self.thresholdSlider.singleStep = 0.01
        self.scriptedEffect.addOptionsWidget(self.thresholdSlider)

        self.autoThresholdMethodSelectorComboBox = qt.QComboBox()
        self.autoThresholdMethodSelectorComboBox.addItem("Otsu", METHOD_OTSU)
        self.autoThresholdMethodSelectorComboBox.addItem("Huang", METHOD_HUANG)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "IsoData", METHOD_ISO_DATA)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Kittler-Illingworth", METHOD_KITTLER_ILLINGWORTH)
        self.autoThresholdMethodSelectorComboBox.addItem("Li", METHOD_LI)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Maximum entropy", METHOD_MAXIMUM_ENTROPY)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Moments", METHOD_MOMENTS)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Renyi entropy", METHOD_RENYI_ENTROPY)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Shanbhag", METHOD_SHANBHAG)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Triangle", METHOD_TRIANGLE)
        self.autoThresholdMethodSelectorComboBox.addItem("Yen", METHOD_YEN)
        self.autoThresholdMethodSelectorComboBox.setToolTip(
            "Select method to compute threshold value automatically.")

        self.autoThresholdModeSelectorComboBox = qt.QComboBox()
        self.autoThresholdModeSelectorComboBox.addItem("set auto->maximum",
                                                       MODE_SET_LOWER_MAX)
        self.autoThresholdModeSelectorComboBox.addItem("set minimum->auto",
                                                       MODE_SET_MIN_UPPER)
        self.autoThresholdModeSelectorComboBox.addItem("set as lower",
                                                       MODE_SET_LOWER)
        self.autoThresholdModeSelectorComboBox.addItem("set as upper",
                                                       MODE_SET_UPPER)
        self.autoThresholdMethodSelectorComboBox.setToolTip(
            "How to set lower and upper threshold values. Current refers to keeping the current value."
        )

        self.selectNextAutoThresholdButton = qt.QPushButton(">")
        self.selectNextAutoThresholdButton.setToolTip(
            "Select next thresholding method and set thresholds using that." +
            " Useful for iterating through all available methods.")

        self.setAutoThresholdButton = qt.QPushButton("Set")
        self.setAutoThresholdButton.setToolTip(
            "Compute automatic threshold and set as threshold limit.")
        # 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.setAutoThresholdButton.setSizePolicy(qSize)

        autoThresholdFrame = qt.QHBoxLayout()
        autoThresholdFrame.addWidget(self.autoThresholdMethodSelectorComboBox)
        autoThresholdFrame.addWidget(self.autoThresholdModeSelectorComboBox)
        autoThresholdFrame.addWidget(self.selectNextAutoThresholdButton)
        autoThresholdFrame.addWidget(self.setAutoThresholdButton)
        self.scriptedEffect.addLabeledOptionsWidget("Automatic threshold:",
                                                    autoThresholdFrame)

        self.useForPaintButton = qt.QPushButton("Use for masking")
        self.useForPaintButton.setToolTip(
            "Use specified intensity range for masking and switch to Paint effect."
        )
        self.scriptedEffect.addOptionsWidget(self.useForPaintButton)

        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.objectName = self.__class__.__name__ + 'Apply'
        self.applyButton.setToolTip(
            "Fill selected segment in regions that are in the specified intensity range."
        )
        self.scriptedEffect.addOptionsWidget(self.applyButton)

        self.useForPaintButton.connect('clicked()', self.onUseForPaint)
        self.thresholdSlider.connect('valuesChanged(double,double)',
                                     self.onThresholdValuesChanged)
        self.autoThresholdMethodSelectorComboBox.connect(
            "currentIndexChanged(int)", self.updateMRMLFromGUI)
        self.autoThresholdModeSelectorComboBox.connect(
            "currentIndexChanged(int)", self.updateMRMLFromGUI)
        self.selectNextAutoThresholdButton.connect(
            'clicked()', self.onSelectNextAutoThresholdMethod)
        self.setAutoThresholdButton.connect('clicked()', self.onAutoThreshold)
        self.applyButton.connect('clicked()', self.onApply)
Beispiel #5
0
    def buildInterface(self):
        self.layout = qt.QHBoxLayout(self)

        self.titleLabel = QubLabel("<B>Title<B>", self)
        self.titleLabel.setAlignment(qt.Qt.AlignCenter)
        self.titleLabel.setSizePolicy(
            qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed))
        self.layout.addWidget(self.titleLabel)
        """
        move and configure appearence
        """
        self.radioGroup = QubRadioGroup(QubRadioGroup.Horizontal, self)
        self.radioGroup.hide()
        self.connect(self.radioGroup, qt.PYSIGNAL("PositionClicked"),
                     self.positionClicked)
        self.layout.addWidget(self.radioGroup)

        self.setButton = qt.QPushButton("Set", self)
        self.setButton.hide()
        self.connect(self.setButton, qt.SIGNAL("clicked()"), self.setPosition)
        self.setButton.setEnabled(False)
        self.layout.addWidget(self.setButton)
        """
        display appearence
        """
        self.valueLabel = qt.QLabel("no value", self)
        self.valueLabel.hide()
        self.valueLabel.setAlignment(qt.Qt.AlignCenter)
        self.layout.addWidget(self.valueLabel)
        """
        incremental appearence
        """
        self.frame = qt.QFrame(self)
        self.frame.hide()
        self.frame.setFrameShape(qt.QFrame.NoFrame)
        self.frame.setFrameShadow(qt.QFrame.Plain)
        self.layout.addWidget(self.frame)

        vlayout = qt.QVBoxLayout(self.frame)
        vlayout.setMargin(10)

        self.valueWidget = QubValue(self.frame,
                                    titleType=QubValue.Label,
                                    valueType=QubValue.Label,
                                    orientation=QubValue.Horizontal)
        self.valueWidget.setTitle("Current Position")
        vlayout.addWidget(self.valueWidget)

        vlayout.addSpacing(5)

        hlayout = qt.QHBoxLayout(vlayout)

        self.positionList = qt.QListBox(self.frame)
        hlayout.addWidget(self.positionList)

        hlayout.addSpacing(5)

        vlayout1 = qt.QVBoxLayout(hlayout)

        self.gotoButton = qt.QPushButton("Go", self.frame)
        self.connect(self.gotoButton, qt.SIGNAL("clicked()"),
                     self.gotoPosition)
        vlayout1.addWidget(self.gotoButton)

        vlayout1.addStretch(1)

        self.addButton = qt.QPushButton("Add", self.frame)
        self.connect(self.addButton, qt.SIGNAL("clicked()"), self.addPosition)
        vlayout1.addWidget(self.addButton)

        vlayout1.addSpacing(5)

        self.remButton = qt.QPushButton("Delete", self.frame)
        self.connect(self.remButton, qt.SIGNAL("clicked()"), self.remPosition)
        vlayout1.addWidget(self.remButton)
        """
        popup config
        """
        self.configWindow = MultiplePositionConfigurator(self)
        self.popupMenu = qt.QPopupMenu(self.titleLabel)
        self.popupMenu.insertItem("Configure", self.configWindow.show)
Beispiel #6
0
    def setupOptionsFrame(self):
        self.thresholdSliderLabel = qt.QLabel("Threshold Range:")
        self.thresholdSliderLabel.setToolTip(
            "Set the range of the background values that should be labeled.")
        self.scriptedEffect.addOptionsWidget(self.thresholdSliderLabel)

        self.thresholdSlider = ctk.ctkRangeWidget()
        self.thresholdSlider.spinBoxAlignment = qt.Qt.AlignTop
        self.thresholdSlider.singleStep = 0.01
        self.scriptedEffect.addOptionsWidget(self.thresholdSlider)

        self.autoThresholdModeSelectorComboBox = qt.QComboBox()
        self.autoThresholdModeSelectorComboBox.addItem("auto->maximum",
                                                       MODE_SET_LOWER_MAX)
        self.autoThresholdModeSelectorComboBox.addItem("minimum->auto",
                                                       MODE_SET_MIN_UPPER)
        self.autoThresholdModeSelectorComboBox.addItem("as lower",
                                                       MODE_SET_LOWER)
        self.autoThresholdModeSelectorComboBox.addItem("as upper",
                                                       MODE_SET_UPPER)
        self.autoThresholdModeSelectorComboBox.setToolTip(
            "How to set lower and upper threshold values. Current refers to keeping the current value."
        )

        self.autoThresholdMethodSelectorComboBox = qt.QComboBox()
        self.autoThresholdMethodSelectorComboBox.addItem("Otsu", METHOD_OTSU)
        self.autoThresholdMethodSelectorComboBox.addItem("Huang", METHOD_HUANG)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "IsoData", METHOD_ISO_DATA)
        # Kittler-Illingworth sometimes fails with an exception, but it does not cause any major issue,
        # it just logs an error message and does not compute a new threshold value
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Kittler-Illingworth", METHOD_KITTLER_ILLINGWORTH)
        # Li sometimes crashes (index out of range error in
        # ITK/Modules/Filtering/Thresholding/include/itkLiThresholdCalculator.hxx#L94)
        # We can add this method back when issue is fixed in ITK.
        #self.autoThresholdMethodSelectorComboBox.addItem("Li", METHOD_LI)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Maximum entropy", METHOD_MAXIMUM_ENTROPY)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Moments", METHOD_MOMENTS)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Renyi entropy", METHOD_RENYI_ENTROPY)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Shanbhag", METHOD_SHANBHAG)
        self.autoThresholdMethodSelectorComboBox.addItem(
            "Triangle", METHOD_TRIANGLE)
        self.autoThresholdMethodSelectorComboBox.addItem("Yen", METHOD_YEN)
        self.autoThresholdMethodSelectorComboBox.setToolTip(
            "Select method to compute threshold value automatically.")

        self.selectPreviousAutoThresholdButton = qt.QToolButton()
        self.selectPreviousAutoThresholdButton.text = "<"
        self.selectPreviousAutoThresholdButton.setToolTip(
            "Select previous thresholding method and set thresholds." +
            " Useful for iterating through all available methods.")

        self.selectNextAutoThresholdButton = qt.QToolButton()
        self.selectNextAutoThresholdButton.text = ">"
        self.selectNextAutoThresholdButton.setToolTip(
            "Select next thresholding method and set thresholds." +
            " Useful for iterating through all available methods.")

        self.setAutoThresholdButton = qt.QPushButton("Set")
        self.setAutoThresholdButton.setToolTip(
            "Set threshold using selected method.")

        # 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.setAutoThresholdButton.setSizePolicy(qSize)

        autoThresholdFrame = qt.QHBoxLayout()
        autoThresholdFrame.addWidget(self.autoThresholdModeSelectorComboBox)
        autoThresholdFrame.addWidget(self.autoThresholdMethodSelectorComboBox)
        autoThresholdFrame.addWidget(self.selectPreviousAutoThresholdButton)
        autoThresholdFrame.addWidget(self.selectNextAutoThresholdButton)
        autoThresholdFrame.addWidget(self.setAutoThresholdButton)
        self.scriptedEffect.addLabeledOptionsWidget("Automatic threshold:",
                                                    autoThresholdFrame)

        self.useForPaintButton = qt.QPushButton("Use for masking")
        self.useForPaintButton.setToolTip(
            "Use specified intensity range for masking and switch to Paint effect."
        )
        self.scriptedEffect.addOptionsWidget(self.useForPaintButton)

        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.objectName = self.__class__.__name__ + 'Apply'
        self.applyButton.setToolTip(
            "Fill selected segment in regions that are in the specified intensity range."
        )
        self.scriptedEffect.addOptionsWidget(self.applyButton)

        self.useForPaintButton.connect('clicked()', self.onUseForPaint)
        self.thresholdSlider.connect('valuesChanged(double,double)',
                                     self.onThresholdValuesChanged)
        self.autoThresholdMethodSelectorComboBox.connect(
            "activated(int)", self.onSelectedAutoThresholdMethod)
        self.autoThresholdModeSelectorComboBox.connect(
            "activated(int)", self.onSelectedAutoThresholdMethod)
        self.selectPreviousAutoThresholdButton.connect(
            'clicked()', self.onSelectPreviousAutoThresholdMethod)
        self.selectNextAutoThresholdButton.connect(
            'clicked()', self.onSelectNextAutoThresholdMethod)
        self.setAutoThresholdButton.connect('clicked()', self.onAutoThreshold)
        self.applyButton.connect('clicked()', self.onApply)
Beispiel #7
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
Beispiel #8
0
    def __init__(self, *args):
        BaseComponents.BlissWidget.__init__(self, *args)

        self.addProperty("hwobj", "string", "")

        self.widget = CatsMaintWidgetSoleil(self)
        qt.QHBoxLayout(self)
        self.layout().addWidget(self.widget)

        qt.QObject.connect(self.widget.btPowerOn, qt.SIGNAL("clicked()"), self._powerOn)
        qt.QObject.connect(
            self.widget.btPowerOff, qt.SIGNAL("clicked()"), self._powerOff
        )
        qt.QObject.connect(
            self.widget.btLid1Open, qt.SIGNAL("clicked()"), self._lid1Open
        )
        qt.QObject.connect(
            self.widget.btLid1Close, qt.SIGNAL("clicked()"), self._lid1Close
        )
        qt.QObject.connect(
            self.widget.btLid2Open, qt.SIGNAL("clicked()"), self._lid2Open
        )
        qt.QObject.connect(
            self.widget.btLid2Close, qt.SIGNAL("clicked()"), self._lid2Close
        )
        qt.QObject.connect(
            self.widget.btLid3Open, qt.SIGNAL("clicked()"), self._lid3Open
        )
        qt.QObject.connect(
            self.widget.btLid3Close, qt.SIGNAL("clicked()"), self._lid3Close
        )
        qt.QObject.connect(
            self.widget.btResetError, qt.SIGNAL("clicked()"), self._resetError
        )
        qt.QObject.connect(self.widget.btBack, qt.SIGNAL("clicked()"), self._backTraj)
        qt.QObject.connect(self.widget.btSafe, qt.SIGNAL("clicked()"), self._safeTraj)
        # MS 2014-11-18
        qt.QObject.connect(self.widget.btHome, qt.SIGNAL("clicked()"), self._homeTraj)
        qt.QObject.connect(self.widget.btDry, qt.SIGNAL("clicked()"), self._drySoakTraj)
        qt.QObject.connect(self.widget.btSoak, qt.SIGNAL("clicked()"), self._soakTraj)
        # qt.QObject.connect(self.widget.btMemoryClear, qt.SIGNAL('clicked()'), self._clearMemory)
        qt.QObject.connect(
            self.widget.btMemoryClear, qt.SIGNAL("clicked()"), self._ackSampleMemory
        )
        qt.QObject.connect(
            self.widget.btToolOpen, qt.SIGNAL("clicked()"), self._openTool
        )
        qt.QObject.connect(
            self.widget.btToolcal, qt.SIGNAL("clicked()"), self._toolcalTraj
        )
        ###
        qt.QObject.connect(
            self.widget.btRegulationOn, qt.SIGNAL("clicked()"), self._regulationOn
        )

        self.device = None
        self._pathRunning = None
        self._poweredOn = None
        self._regulationOn = None

        self._lid1State = False
        self._lid2State = False
        self._lid3State = False

        self._updateButtons()
    def setupOptionsFrame(self):
        self.frame = qt.QFrame(self.scriptedEffect.optionsFrame())
        qt.QFormLayout(self.frame)
        #Save space in the GUI
        self.frame.layout().setSpacing(0)
        self.frame.layout().setMargin(0)

        #    self.helpLabel = qt.QLabel(self.frame)
        #    self.helpLabel.setWordWrap(True)
        #    #self.helpLabel.sizePolicy.setHorizontalPolicy(qt.QSizePolicy.Ignored)
        #    #self.helpLabel.sizePolicy.setVerticalPolicy(qt.QSizePolicy.Ignored)
        #    self.helpLabel.text = "Click on a lesion to start segmentation. \
        # Depending on refinement settings, click again to refine globally and/or locally. Options may help deal \
        # with cases such as segmenting individual lesions in a chain. \
        # See <a href=\"https://www.slicer.org/wiki/Documentation/Nightly/Extensions/PETTumorSegmentation\">the documentation</a> for more information."
        #    self.scriptedEffect.addOptionsWidget(self.helpLabel)

        # refinementBoxesFrame contains the options for how clicks are handled
        self.refinementBoxesFrame = qt.QFrame(self.frame)
        self.refinementBoxesFrame.setLayout(qt.QHBoxLayout())
        self.refinementBoxesFrame.layout().setSpacing(0)
        self.refinementBoxesFrame.layout().setMargin(0)

        #default is global refinement (threshold refinement)
        self.noRefinementRadioButton = qt.QRadioButton(
            "Create new", self.refinementBoxesFrame)
        self.noRefinementRadioButton.setToolTip(
            "On click, always segment a new object.")
        self.globalRefinementRadioButton = qt.QRadioButton(
            "Global refinement", self.refinementBoxesFrame)
        self.globalRefinementRadioButton.setToolTip(
            "On click, refine globally (adjusting then entire boundary) if no center point for the label, otherwise segment a new object."
        )
        self.localRefinementRadioButton = qt.QRadioButton(
            "Local refinement", self.refinementBoxesFrame)
        self.localRefinementRadioButton.setToolTip(
            "On click, refine locally (adjusting part of the boundary) if no center point for the label, otherwise segment a new object."
        )
        self.globalRefinementRadioButton.setChecked(True)

        #radio button so only one can be applied
        self.refinementBoxesFrame.layout().addWidget(
            qt.QLabel("Interaction style: ", self.refinementBoxesFrame))
        self.refinementBoxesFrame.layout().addWidget(
            self.noRefinementRadioButton)
        self.refinementBoxesFrame.layout().addWidget(
            self.globalRefinementRadioButton)
        self.refinementBoxesFrame.layout().addWidget(
            self.localRefinementRadioButton)
        self.refinementBoxesFrame.layout().addStretch(1)

        self.scriptedEffect.addOptionsWidget(self.refinementBoxesFrame)

        #options are hidden (collapsed) until requested
        self.optFrame = ctk.ctkCollapsibleGroupBox(self.frame)
        self.optFrame.setTitle("Options")
        self.optFrame.setLayout(qt.QVBoxLayout())
        self.optFrame.visible = True
        self.optFrame.collapsed = True
        self.optFrame.setToolTip("Displays algorithm options.")

        #most useful options are kept on top: Splitting, Sealing, Assist Centering, Allow
        #Overwriting; to save vertical space, put 2 ina  row, so subframes here with
        #horizontal layout are used

        #first row
        self.commonCheckBoxesFrame1 = qt.QFrame(self.optFrame)
        self.commonCheckBoxesFrame1.setLayout(qt.QHBoxLayout())
        self.commonCheckBoxesFrame1.layout().setSpacing(0)
        self.commonCheckBoxesFrame1.layout().setMargin(0)
        self.optFrame.layout().addWidget(self.commonCheckBoxesFrame1)

        #top left
        self.splittingCheckBox = qt.QCheckBox("Splitting",
                                              self.commonCheckBoxesFrame1)
        self.splittingCheckBox.setToolTip(
            "Cut off adjacent objects to the target via watershed or local minimum.  Useful for lymph node chains."
        )
        self.splittingCheckBox.checked = False
        self.commonCheckBoxesFrame1.layout().addWidget(self.splittingCheckBox)

        #top right
        self.sealingCheckBox = qt.QCheckBox("Sealing",
                                            self.commonCheckBoxesFrame1)
        self.sealingCheckBox.setToolTip(
            "Close single-voxel gaps in the object or between the object and other objects, if above the threshold.  Useful for lymph node chains."
        )
        self.sealingCheckBox.checked = False
        self.commonCheckBoxesFrame1.layout().addWidget(self.sealingCheckBox)

        #second row
        self.commonCheckBoxesFrame2 = qt.QFrame(self.optFrame)
        self.commonCheckBoxesFrame2.setLayout(qt.QHBoxLayout())
        self.commonCheckBoxesFrame2.layout().setSpacing(0)
        self.commonCheckBoxesFrame2.layout().setMargin(0)
        self.optFrame.layout().addWidget(self.commonCheckBoxesFrame2)

        #bottom left
        self.assistCenteringCheckBox = qt.QCheckBox(
            "Assist Centering", self.commonCheckBoxesFrame2)
        self.assistCenteringCheckBox.setToolTip(
            "Move the center to the highest voxel within 7 physical units, without being on or next to other object labels.  Improves consistency."
        )
        self.assistCenteringCheckBox.checked = True
        self.commonCheckBoxesFrame2.layout().addWidget(
            self.assistCenteringCheckBox)

        #bottom right
        self.allowOverwritingCheckBox = qt.QCheckBox(
            "Allow Overwriting", self.commonCheckBoxesFrame2)
        self.allowOverwritingCheckBox.setToolTip("Ignore other object labels.")
        self.allowOverwritingCheckBox.checked = False
        self.commonCheckBoxesFrame2.layout().addWidget(
            self.allowOverwritingCheckBox)

        self.scriptedEffect.addOptionsWidget(self.optFrame)

        #advanced options, for abnormal cases such as massive necrotic objects or
        #low-transition scans like phantoms
        #infrequently used, just keep vertical
        self.advFrame = ctk.ctkCollapsibleGroupBox(self.frame)
        self.advFrame.setTitle("Advanced")
        self.advFrame.setLayout(qt.QVBoxLayout())
        self.advFrame.visible = True
        self.advFrame.collapsed = True
        self.advFrame.setToolTip(
            "Displays more advanced algorithm options.  Do not use if you don't know what they mean."
        )

        #top
        self.necroticRegionCheckBox = qt.QCheckBox("Necrotic Region",
                                                   self.advFrame)
        self.necroticRegionCheckBox.setToolTip(
            "Prevents cutoff from low uptake.  Use if placing a center inside a necrotic region."
        )
        self.necroticRegionCheckBox.checked = False
        self.advFrame.layout().addWidget(self.necroticRegionCheckBox)

        #middle
        self.denoiseThresholdCheckBox = qt.QCheckBox("Denoise Threshold",
                                                     self.advFrame)
        self.denoiseThresholdCheckBox.setToolTip(
            "Calculates threshold based on median-filtered image.  Use only if scan is very noisey."
        )
        self.denoiseThresholdCheckBox.checked = False
        self.advFrame.layout().addWidget(self.denoiseThresholdCheckBox)

        #bottom
        self.linearCostCheckBox = qt.QCheckBox("Linear Cost", self.advFrame)
        self.linearCostCheckBox.setToolTip(
            "Cost function below threshold is linear rather than based on region.  Use only if little/no transition region in uptake."
        )
        self.linearCostCheckBox.checked = False
        self.advFrame.layout().addWidget(self.linearCostCheckBox)

        self.optFrame.layout().addWidget(self.advFrame)

        #apply button kept at bottom of all options
        self.applyButton = qt.QPushButton("Apply", self.frame)
        self.optFrame.layout().addWidget(self.applyButton)
        self.applyButton.connect('clicked()', self.onApplyParameters)
        self.applyButton.setToolTip(
            "Redo last segmentation with the same center and refinement points with any changes in options."
        )
Beispiel #10
0
    def setup(self, showPreview=False):
        """
    main window is a frame with widgets from the app
    widget repacked into it along with slicer-specific
    extra widgets
    """

        self.setWindowTitle('DICOM Browser')
        self.setLayout(qt.QVBoxLayout())

        self.dicomBrowser.databaseDirectorySelectorVisible = False
        self.dicomBrowser.toolbarVisible = False
        self.dicomBrowser.sendActionVisible = True
        self.dicomBrowser.databaseDirectorySettingsKey = slicer.dicomDatabaseDirectorySettingsKey
        self.dicomBrowser.dicomTableManager().dynamicTableLayout = False
        horizontal = self.settings.setValue('DICOM/horizontalTables', 0)
        self.dicomBrowser.dicomTableManager(
        ).tableOrientation = qt.Qt.Horizontal if horizontal else qt.Qt.Vertical
        self.layout().addWidget(self.dicomBrowser)

        self.userFrame = qt.QWidget()
        self.preview = qt.QWidget()

        #
        # preview related column
        #
        self.previewLayout = qt.QVBoxLayout()
        if showPreview:
            self.previewLayout.addWidget(self.preview)
        else:
            self.preview.hide()

        #
        # action related column (interacting with slicer)
        #
        self.loadableTableFrame = qt.QWidget()
        self.loadableTableFrame.setMaximumHeight(200)
        self.loadableTableLayout = qt.QVBoxLayout(self.loadableTableFrame)
        self.layout().addWidget(self.loadableTableFrame)

        self.loadableTableLayout.addWidget(self.userFrame)
        self.userFrame.hide()

        self.loadableTable = DICOMLoadableTable(self.userFrame)
        self.loadableTable.itemChanged.connect(self.onLoadableTableItemChanged)

        #
        # button row for action column
        #
        self.actionButtonsFrame = qt.QWidget()
        self.actionButtonsFrame.setMaximumHeight(40)
        self.actionButtonsFrame.objectName = 'ActionButtonsFrame'
        self.layout().addWidget(self.actionButtonsFrame)

        self.actionButtonLayout = qt.QHBoxLayout()
        self.actionButtonsFrame.setLayout(self.actionButtonLayout)

        self.uncheckAllButton = qt.QPushButton('Uncheck All')
        self.actionButtonLayout.addWidget(self.uncheckAllButton)
        self.uncheckAllButton.connect('clicked()', self.uncheckAllLoadables)

        self.actionButtonLayout.addStretch(0.05)

        self.examineButton = qt.QPushButton('Examine')
        self.examineButton.setSizePolicy(qt.QSizePolicy.Expanding,
                                         qt.QSizePolicy.Fixed)
        self.actionButtonLayout.addWidget(self.examineButton)
        self.examineButton.enabled = False
        self.examineButton.connect('clicked()', self.examineForLoading)

        self.loadButton = qt.QPushButton('Load')
        self.loadButton.setSizePolicy(qt.QSizePolicy.Expanding,
                                      qt.QSizePolicy.Fixed)
        self.loadButton.toolTip = 'Load selected items into the scene'
        self.actionButtonLayout.addWidget(self.loadButton)
        self.loadButton.connect('clicked()', self.loadCheckedLoadables)

        self.actionButtonLayout.addStretch(0.05)

        self.advancedViewButton = qt.QCheckBox('Advanced')
        self.advancedViewButton.objectName = 'AdvancedViewCheckBox'
        self.actionButtonLayout.addWidget(self.advancedViewButton)
        self.advancedViewButton.checked = self.advancedView
        self.advancedViewButton.toggled.connect(self.onAdvancedViewButton)

        if self.advancedView:
            self.loadableTableFrame.visible = True
        else:
            self.loadableTableFrame.visible = False
            self.examineButton.visible = False
            self.uncheckAllButton.visible = False

        #
        # Series selection
        #
        self.dicomBrowser.dicomTableManager().connect(
            'seriesSelectionChanged(QStringList)', self.onSeriesSelected)

        #
        # Loadable table widget (advanced)
        # DICOM Plugins selection widget is moved to module panel
        #
        self.loadableTableLayout.addWidget(self.loadableTable)
        self.updateButtonStates()
Beispiel #11
0
    def buildInterface(self):
        vlayout = qt.QVBoxLayout(self)

        title = qt.QLabel("<B>Pixel Size Calibration<B>", self)
        title.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Expanding,
                                           qt.QSizePolicy.Fixed))
        vlayout.addWidget(title)

        self.calibFrame = qt.QFrame(self)
        self.calibFrame.setFrameShape(qt.QFrame.Box)
        self.calibFrame.setFrameShadow(qt.QFrame.Sunken)
        vlayout.addWidget(self.calibFrame)

        vlayout1 = qt.QVBoxLayout(self.calibFrame)
        vlayout1.setMargin(10)

        self.table = qttable.QTable(0, 3, self.calibFrame)
        self.table.setFocusPolicy(qt.QWidget.NoFocus)
        self.table.setSelectionMode(qttable.QTable.NoSelection)
        self.table.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Minimum,
                                                qt.QSizePolicy.Minimum))
        self.table.verticalHeader().hide()
        self.table.setLeftMargin(0)
        self.table.setReadOnly(True)

        header = self.table.horizontalHeader()
        header.setLabel(0, "Zoom")
        header.setLabel(1, "Y Size (nm)")
        header.setLabel(2, "Z Size (nm)")

        self.table.clearSelection(True)

        vlayout1.addWidget(self.table)

        vlayout1.addSpacing(10)
        f1 = qt.QFrame(self.calibFrame)
        f1.setFrameShape(qt.QFrame.HLine)
        f1.setFrameShadow(qt.QFrame.Sunken)
        vlayout1.addWidget(f1)
        vlayout1.addSpacing(10)

        self.saveButton = qt.QPushButton("Save Current Calibration",
                                         self.calibFrame)
        self.connect(self.saveButton, qt.SIGNAL("clicked()"),
                     self.saveCalibration)
        vlayout1.addWidget(self.saveButton)

        vlayout1.addSpacing(10)
        f1 = qt.QFrame(self.calibFrame)
        f1.setFrameShape(qt.QFrame.HLine)
        f1.setFrameShadow(qt.QFrame.Sunken)
        vlayout1.addWidget(f1)
        vlayout1.addSpacing(10)

        hlayout1 = qt.QHBoxLayout(vlayout1)
        self.relYLabel = qt.QLabel("Y Move:", self.calibFrame)
        hlayout1.addWidget(self.relYLabel)
        self.relYText = qt.QLineEdit("0.1", self.calibFrame)
        hlayout1.addWidget(self.relYText)

        hlayout2 = qt.QHBoxLayout(vlayout1)
        self.relZLabel = qt.QLabel("Z Move:", self.calibFrame)
        hlayout2.addWidget(self.relZLabel)
        self.relZText = qt.QLineEdit("0.1", self.calibFrame)
        hlayout2.addWidget(self.relZText)

        vlayout1.addSpacing(5)

        self.calibButton = qt.QPushButton("Start New Calibration",
                                          self.calibFrame)
        self.connect(self.calibButton, qt.SIGNAL("clicked()"),
                     self.calibrationAction)
        vlayout1.addWidget(self.calibButton)

        vlayout1.addStretch(1)
    def setupOptionsFrame(self):
        self.methodSelectorComboBox = qt.QComboBox()
        self.methodSelectorComboBox.addItem("Grow from seeds", GROWCUT)
        self.methodSelectorComboBox.addItem("Fill between parallel slices",
                                            MORPHOLOGICAL_SLICE_INTERPOLATION)
        self.methodSelectorComboBox.setToolTip(
            """<html>Auto-complete methods:<ul style="margin: 0">
<li><b>Fill between slices:</b> Perform complete segmentation on selected slices using any editor effect.
The complete segmentation will be created by interpolating segmentations on slices that were skipped.</li>
<li><b>Expand segments:</b> Create segments using any editor effect: one segment inside
each each region that should belong to a separate segment. Segments will be expanded to create
a complete segmentation, taking into account the master volume content. Minimum two segments are required.
(see http://insight-journal.org/browse/publication/977)</li>
</ul></html>""")
        self.scriptedEffect.addLabeledOptionsWidget(
            "Method:", self.methodSelectorComboBox)

        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

        displayFrame = qt.QHBoxLayout()
        displayFrame.addWidget(qt.QLabel("inputs"))
        displayFrame.addWidget(self.previewOpacitySlider)
        displayFrame.addWidget(qt.QLabel("results"))
        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.methodSelectorComboBox.connect("currentIndexChanged(int)",
                                            self.updateMRMLFromGUI)
        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.autoUpdateCheckBox.connect("stateChanged(int)",
                                        self.updateMRMLFromGUI)
Beispiel #13
0
    def create(self):
        super().create()

        self.radiusFrame = qt.QFrame(self.frame)
        self.radiusFrame.setLayout(qt.QHBoxLayout())
        self.frame.layout().addWidget(self.radiusFrame)
        self.widgets.append(self.radiusFrame)
        self.radiusLabel = qt.QLabel("Radius:", self.radiusFrame)
        self.radiusLabel.setToolTip(
            "Set the radius of the paint brush in millimeters")
        self.radiusFrame.layout().addWidget(self.radiusLabel)
        self.widgets.append(self.radiusLabel)
        self.radiusSpinBox = slicer.qMRMLSpinBox(self.radiusFrame)
        self.radiusSpinBox.objectName = 'SpinBox_Radius'
        self.radiusSpinBox.setToolTip(
            "Set the radius of the paint brush in millimeters")
        self.radiusSpinBox.quantity = "length"
        # QFlags not wrapped in python. Equivalent to Prefix | Suffix
        # See qMRMLSpinBox for more details.
        self.radiusSpinBox.unitAwareProperties = 0x01 | 0x02
        self.radiusSpinBox.minimum = self.minimumRadius
        self.radiusSpinBox.maximum = self.maximumRadius
        self.radiusSpinBox.setMRMLScene(slicer.mrmlScene)
        from math import log, floor
        decimals = floor(log(self.minimumRadius, 10))
        if decimals < 0:
            self.radiusSpinBox.decimals = -decimals + 2
        self.radiusFrame.layout().addWidget(self.radiusSpinBox)
        self.widgets.append(self.radiusSpinBox)
        self.radiusUnitsToggle = qt.QPushButton("px:")
        self.radiusUnitsToggle.objectName = 'PushButton_RadiusUnitsToggle'
        self.radiusUnitsToggle.setToolTip(
            "Toggle radius quick set buttons between mm and label volume pixel size units"
        )
        self.radiusUnitsToggle.setFixedWidth(35)
        self.radiusFrame.layout().addWidget(self.radiusUnitsToggle)
        self.radiusUnitsToggle.connect('clicked()', self.onRadiusUnitsToggle)
        self.radiusQuickies = {}
        quickies = ((2, self.onQuickie2Clicked), (3, self.onQuickie3Clicked),
                    (4, self.onQuickie4Clicked), (5, self.onQuickie5Clicked),
                    (10, self.onQuickie10Clicked), (20,
                                                    self.onQuickie20Clicked))
        for rad, callback in quickies:
            self.radiusQuickies[rad] = qt.QPushButton(str(rad))
            self.radiusQuickies[
                rad].objectName = f'PushButton_QuickRadius_{rad}'
            self.radiusFrame.layout().addWidget(self.radiusQuickies[rad])
            self.radiusQuickies[rad].setFixedWidth(25)
            self.radiusQuickies[rad].connect('clicked()', callback)
            self.radiusQuickies[rad].setToolTip(
                "Set radius based on mm or label voxel size units depending on toggle value"
            )

        self.radius = ctk.ctkDoubleSlider(self.frame)
        self.radius.objectName = 'DoubleSlider_Radius'
        self.radius.minimum = self.minimumRadius
        self.radius.maximum = self.maximumRadius
        self.radius.orientation = 1
        self.radius.singleStep = self.minimumRadius
        self.frame.layout().addWidget(self.radius)
        self.widgets.append(self.radius)

        self.sphere = qt.QCheckBox("Sphere", self.frame)
        self.sphere.objectName = 'CheckBox_Sphere'
        self.sphere.setToolTip(
            "Use a 3D spherical brush rather than a 2D circular brush.")
        self.frame.layout().addWidget(self.sphere)
        self.widgets.append(self.sphere)

        self.smudge = qt.QCheckBox("Smudge", self.frame)
        self.smudge.objectName = 'CheckBox_Smudge'
        self.smudge.setToolTip(
            "Set the label number automatically by sampling the pixel location where the brush stroke starts."
        )
        self.frame.layout().addWidget(self.smudge)
        self.widgets.append(self.smudge)

        self.pixelMode = qt.QCheckBox("Pixel Mode", self.frame)
        self.pixelMode.objectName = 'CheckBox_PixelMode'
        self.pixelMode.setToolTip(
            "Paint exactly the pixel under the cursor, ignoring the radius, threshold, and paint over."
        )
        self.frame.layout().addWidget(self.pixelMode)
        self.widgets.append(self.pixelMode)

        HelpButton(
            self.frame,
            "Use this tool to paint with a round brush of the selected radius")

        self.connections.append(
            (self.sphere, 'clicked()', self.updateMRMLFromGUI))
        self.connections.append(
            (self.smudge, 'clicked()', self.updateMRMLFromGUI))
        self.connections.append(
            (self.pixelMode, 'clicked()', self.updateMRMLFromGUI))
        self.connections.append(
            (self.radius, 'valueChanged(double)', self.onRadiusValueChanged))
        self.connections.append((self.radiusSpinBox, 'valueChanged(double)',
                                 self.onRadiusSpinBoxChanged))

        # Add vertical spacer
        self.frame.layout().addStretch(1)
Beispiel #14
0
    def setupOptionsFrame(self):
        SegmentEditorThresholdEffect.setupOptionsFrame(self)

        # Hide threshold options
        self.applyButton.setHidden(True)
        self.useForPaintButton.setHidden(True)

        # Add diameter selector
        self.minimumDiameterSpinBox = slicer.qMRMLSpinBox()
        self.minimumDiameterSpinBox.setMRMLScene(slicer.mrmlScene)
        self.minimumDiameterSpinBox.quantity = "length"
        self.minimumDiameterSpinBox.value = 3.0
        self.minimumDiameterSpinBox.singleStep = 0.5
        self.minimumDiameterSpinBox.setToolTip(
            "Minimum diameter of the structure. Regions that are connected to the selected point by a bridge"
            " that this is thinner than this size will be excluded to prevent unwanted leaks through small holes."
        )
        self.kernelSizePixel = qt.QLabel()
        self.kernelSizePixel.setToolTip(
            "Minimum diameter of the structure in pixels. Computed from the segment's spacing and the specified feature size."
        )
        minimumDiameterFrame = qt.QHBoxLayout()
        minimumDiameterFrame.addWidget(self.minimumDiameterSpinBox)
        minimumDiameterFrame.addWidget(self.kernelSizePixel)
        self.minimumDiameterMmLabel = self.scriptedEffect.addLabeledOptionsWidget(
            "Minimum diameter:", minimumDiameterFrame)
        self.scriptedEffect.addOptionsWidget(minimumDiameterFrame)

        # Add algorithm options
        self.segmentationAlgorithmSelector = qt.QComboBox()
        self.segmentationAlgorithmSelector.addItem(
            SEGMENTATION_ALGORITHM_MASKING)
        self.segmentationAlgorithmSelector.addItem(
            SEGMENTATION_ALGORITHM_GROWCUT)
        self.segmentationAlgorithmSelector.addItem(
            SEGMENTATION_ALGORITHM_WATERSHED)
        self.scriptedEffect.addLabeledOptionsWidget(
            "Segmentation algorithm: ", self.segmentationAlgorithmSelector)

        # Add feature size selector
        self.featureSizeSpinBox = slicer.qMRMLSpinBox()
        self.featureSizeSpinBox.setMRMLScene(slicer.mrmlScene)
        self.featureSizeSpinBox.quantity = "length"
        self.featureSizeSpinBox.value = 3.0
        self.featureSizeSpinBox.singleStep = 0.5
        self.featureSizeSpinBox.setToolTip(
            "Spatial smoothness constraint used for WaterShed. Larger values result in smoother extracted surface."
        )
        self.scriptedEffect.addLabeledOptionsWidget("Feature size: ",
                                                    self.featureSizeSpinBox)

        # Add ROI options
        self.roiSelector = slicer.qMRMLNodeComboBox()
        self.roiSelector.nodeTypes = ['vtkMRMLAnnotationROINode']
        self.roiSelector.noneEnabled = True
        self.roiSelector.setMRMLScene(slicer.mrmlScene)
        self.scriptedEffect.addLabeledOptionsWidget("ROI: ", self.roiSelector)

        # Connections
        self.minimumDiameterSpinBox.connect("valueChanged(double)",
                                            self.updateMRMLFromGUI)
        self.featureSizeSpinBox.connect("valueChanged(double)",
                                        self.updateMRMLFromGUI)
        self.segmentationAlgorithmSelector.connect("currentIndexChanged(int)",
                                                   self.updateMRMLFromGUI)
Beispiel #15
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()
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        self.logic = ProstateReportingLogic()

        self.uiLoader = qt.QUiLoader()

        self.patientName = None

        self.lesionList = None
        self.lesionListTags = []

        # Instantiate and connect widgets ...

        # Load UI files
        self.scansWidget = self.loadUI('Scans')
        self.sectorMapWidget = self.loadUI('SectorMap')
        self.assessmentWidget = self.loadUI('Assessment')
        self.reportWidget = self.loadUI('Report')

        # Set up the sector relationships
        self.SectorMap = None
        self.initSectorMap()

        #
        # Volumes Area
        #
        scansCollapsibleButton = ctk.ctkCollapsibleButton()
        scansCollapsibleButton.text = "Patient Scans"
        self.layout.addWidget(scansCollapsibleButton)

        # Layout within the dummy collapsible button
        scansLayout = qt.QVBoxLayout(scansCollapsibleButton)

        # Patient name
        patientNameLayout = qt.QHBoxLayout()
        patientNameLayout.addWidget(qt.QLabel("Patient Name:"))
        self.patientNameLabel = qt.QLabel("")
        patientNameLayout.addWidget(self.patientNameLabel)

        scansLayout.addLayout(patientNameLayout)

        # Scans
        scansLayout.addWidget(self.scansWidget)

        self.t2VolumeSelector = self.logic.getChild(self.scansWidget,
                                                    't2VolumeSelector')
        self.t2VolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.t2ScanDateLabel = self.logic.getChild(self.scansWidget,
                                                   't2ScanDateLabel')

        self.t1VolumeSelector = self.logic.getChild(self.scansWidget,
                                                    't1VolumeSelector')
        self.t1VolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.t1ScanDateLabel = self.logic.getChild(self.scansWidget,
                                                   't1ScanDateLabel')

        self.dwiVolumeSelector = self.logic.getChild(self.scansWidget,
                                                     'dwiVolumeSelector')
        self.dwiVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.dwiScanDateLabel = self.logic.getChild(self.scansWidget,
                                                    'dwiScanDateLabel')

        self.adcVolumeSelector = self.logic.getChild(self.scansWidget,
                                                     'adcVolumeSelector')
        self.adcVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.adcScanDateLabel = self.logic.getChild(self.scansWidget,
                                                    'adcScanDateLabel')

        self.dceVolumeSelector = self.logic.getChild(self.scansWidget,
                                                     'dceVolumeSelector')
        self.dceVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.dceScanDateLabel = self.logic.getChild(self.scansWidget,
                                                    'dceScanDateLabel')

        #
        # Lesions Area
        #
        lesionsCollapsibleButton = ctk.ctkCollapsibleButton()
        lesionsCollapsibleButton.text = "Lesions"
        self.layout.addWidget(lesionsCollapsibleButton)

        # Layout within the dummy collapsible button
        lesionsLayout = qt.QVBoxLayout(lesionsCollapsibleButton)

        # Sector map
        sectorMapLabel = qt.QLabel()
        sectorMapLabel.setText("Prostate sector:")
        lesionsLayout.addWidget(sectorMapLabel)
        lesionsLayout.addWidget(self.sectorMapWidget)

        # Lesion target list
        if 0:
            self.targetListSelector = slicer.qMRMLNodeComboBox()
            self.targetListSelector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"]
            self.targetListSelector.selectNodeUponCreation = True
            self.targetListSelector.addEnabled = True
            self.targetListSelector.removeEnabled = False
            self.targetListSelector.noneEnabled = False
            self.targetListSelector.showHidden = False
            self.targetListSelector.showChildNodeTypes = False
            self.targetListSelector.setMRMLScene(slicer.mrmlScene)
            self.targetListSelector.setToolTip(
                "Pick the list of target lesion fiducials.")
            lesionsLayout.addWidget(self.targetListSelector)

        # Add a lesion, will create a list if necessary. Will name it according
        # to sector selection
        self.addLesionButton = qt.QPushButton()
        self.addLesionButton.text = 'Add Lesion'
        lesionsLayout.addWidget(self.addLesionButton)

        # show the lesions in a table
        self.targetTableWidget = slicer.qSlicerSimpleMarkupsWidget()
        self.targetTableWidget.setMRMLScene(slicer.mrmlScene)
        lesionsLayout.addWidget(self.targetTableWidget)
        self.targetListSelector = self.logic.getChild(
            self.targetTableWidget, "MarkupsFiducialNodeComboBox")
        # hide the place button as want to rename fids when adding
        placeWidget = self.logic.getChild(self.targetTableWidget,
                                          "PlaceButton")
        placeWidget.hide()

        #
        # Assessment Area
        #
        assessmentCollapsibleButton = ctk.ctkCollapsibleButton()
        assessmentCollapsibleButton.text = "Assessment"
        self.layout.addWidget(assessmentCollapsibleButton)

        # Layout within the dummy collapsible button
        assessmentLayout = qt.QVBoxLayout(assessmentCollapsibleButton)

        assessmentLayout.addWidget(self.assessmentWidget)
        self.assessmentComboBox = self.logic.getChild(self.assessmentWidget,
                                                      "assessmentComboBox")

        #
        # Report Area
        #
        self.reportButton = qt.QPushButton()
        self.reportButton.setText("Report")
        self.layout.addWidget(self.reportButton)

        # get the report widgets need to fill in
        self.reportPatientName = self.logic.getChild(self.reportWidget,
                                                     "patientNameLabel")
        self.reportScans = self.logic.getChild(self.reportWidget,
                                               "patientScansTextEdit")
        self.reportLesions = self.logic.getChild(self.reportWidget,
                                                 "patientLesionsTextEdit")
        self.reportAssessment = self.logic.getChild(
            self.reportWidget, "patientAssessmentTextEdit")
        self.reportNotes = self.logic.getChild(self.reportWidget,
                                               "patientNotesTextEdit")
        self.reportSave = self.logic.getChild(self.reportWidget,
                                              "savePushButton")
        self.reportCancel = self.logic.getChild(self.reportWidget,
                                                "cancelPushButton")
        #
        # Set up Connections
        #
        # Volumes
        self.t2VolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                      self.onSelectT2)
        self.t1VolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                      self.onSelectT1)
        self.dwiVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onSelectDWI)
        self.adcVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onSelectADC)
        self.dceVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onSelectDCE)

        # Lesions
        self.targetListSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                        self.onSelectTargets)

        # Sector map
        self.LRComboBox.connect("currentIndexChanged(int)",
                                self.onSectorLRChanged)
        self.ZoneComboBox.connect("currentIndexChanged(int)",
                                  self.onSectorZoneChanged)
        self.GlandComboBox.connect("currentIndexChanged(int)",
                                   self.onSectorGlandChanged)
        self.APComboBox.connect("currentIndexChanged(int)",
                                self.onSectorAPChanged)

        self.addLesionButton.connect('clicked(bool)', self.onAddLesion)

        # Report
        self.reportButton.connect('clicked(bool)', self.onReportButton)
        self.reportSave.connect('clicked(bool)', self.onReportSave)
        self.reportCancel.connect('clicked(bool)', self.onReportCancel)

        # Add vertical spacer
        self.layout.addStretch(1)
Beispiel #17
0
  def __init__(self, parent, developerMode=False, widgetClass=None):
    VTKObservationMixin.__init__(self)
    # Set up main frame
    self.parent = parent
    self.parent.setLayout(qt.QHBoxLayout())

    self.layout = self.parent.layout()
    self.layout.setMargin(0)
    self.layout.setSpacing(0)

    self.sliceletPanel = qt.QFrame(self.parent)
    self.sliceletPanelLayout = qt.QVBoxLayout(self.sliceletPanel)
    self.sliceletPanelLayout.setMargin(4)
    self.sliceletPanelLayout.setSpacing(0)
    self.layout.addWidget(self.sliceletPanel,1)

    #Set Advanced Parameters Collapsible Button
    self.parametersCollapsibleButton = ctk.ctkCollapsibleButton()
    self.parametersCollapsibleButton.text = "Set Advanced Segmentation Parameters"
    self.parametersCollapsibleButton.collapsed = True
    self.sliceletPanelLayout.addWidget(self.parametersCollapsibleButton)
    # Layout within the collapsible button
    self.parametersLayout = qt.QFormLayout(self.parametersCollapsibleButton)
    # Set Minimum Threshold of Percentage Increase to First Post-Contrast Image
    self.inputMinimumThreshold = qt.QLabel("Minimum Threshold of Increase", self.parametersCollapsibleButton)
    self.inputMinimumThreshold.setToolTip('Minimum Threshold of Percentage Increase (Pre- to First Post-contrast (Range: 10% to 150%)')
    self.inputSelectorMinimumThreshold = qt.QDoubleSpinBox(self.parametersCollapsibleButton)
    self.inputSelectorMinimumThreshold.setSuffix("%")
    self.inputSelectorMinimumThreshold.singleStep = (1)
    self.inputSelectorMinimumThreshold.minimum = (10)
    self.inputSelectorMinimumThreshold.maximum = (150)
    self.inputSelectorMinimumThreshold.value = (75)
    self.inputSelectorMinimumThreshold.setToolTip('Minimum Threshold of Percentage Increase (Pre- to First Post-contrast (Range: 10% to 150%)')
    self.parametersLayout.addRow(self.inputMinimumThreshold, self.inputSelectorMinimumThreshold)
    # Curve 1 Type Parameters (Slopes from First to Fourth Post-Contrast Images)
    self.inputCurve1 = qt.QLabel("Type 1 (Persistent) Curve Minimum Slope", self.parametersCollapsibleButton)
    self.inputCurve1.setToolTip('Minimum Slope of Delayed Curve to classify as Persistent (Range: 0.02 to 0.3)')
    self.inputSelectorCurve1 = qt.QDoubleSpinBox(self.parametersCollapsibleButton)
    self.inputSelectorCurve1.singleStep = (0.02)
    self.inputSelectorCurve1.minimum = (0.02)
    self.inputSelectorCurve1.maximum = (0.30)
    self.inputSelectorCurve1.value = (0.20)
    self.inputSelectorCurve1.setToolTip('Minimum Slope of Delayed Curve to classify as Persistent (Range: 0.02 to 0.3)')
    self.parametersLayout.addRow(self.inputCurve1, self.inputSelectorCurve1)
    # Curve 3 Type Parameters (Slopes from First to Fourth Post-Contrast Images)
    self.inputCurve3 = qt.QLabel("Type 3 (Washout) Curve Maximum Slope", self.parametersCollapsibleButton)
    self.inputCurve3.setToolTip('Maximum Slope of Delayed Curve to classify as Washout (Range: -0.02 to -0.3)')
    self.inputSelectorCurve3 = qt.QDoubleSpinBox(self.parametersCollapsibleButton)
    self.inputSelectorCurve3.singleStep = (0.02)
    self.inputSelectorCurve3.setPrefix("-")
    self.inputSelectorCurve3.minimum = (0.02)
    self.inputSelectorCurve3.maximum = (0.30)
    self.inputSelectorCurve3.value = (0.20)
    self.inputSelectorCurve3.setToolTip('Maximum Slope of Delayed Curve to classify as Washout (Range: -0.02 to -0.3)')
    self.parametersLayout.addRow(self.inputCurve3, self.inputSelectorCurve3)

    # Path input for dicom data to analyze
    self.inputPath = qt.QFileDialog()
    self.inputPath.setFileMode(qt.QFileDialog.Directory)
    self.sliceletPanelLayout.addWidget(self.inputPath)
    self.inputPath.connect('accepted()', self.createLogic)


    ##############
    self.layoutWidget = slicer.qMRMLLayoutWidget()
    self.layoutWidget.setMRMLScene(slicer.mrmlScene)
    self.layoutWidget.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUp3DView)
    self.layout.addWidget(self.layoutWidget,2)


    if widgetClass:
      self.widget = widgetClass(self.parent)
    self.parent.show()
Beispiel #18
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        self.logic = NeoGuidanceLogic()

        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        self.layout.addWidget(parametersCollapsibleButton)
        self.layout.setContentsMargins(8, 8, 8, 8)

        # Layout within the collapsible button
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)
        parametersFormLayout.setContentsMargins(8, 8, 8, 8)

        frame = qt.QWidget()
        layout = qt.QHBoxLayout(frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addStretch()
        layout.addWidget(qt.QLabel("Transforms"))
        layout.addStretch()
        parametersFormLayout.addRow(frame)

        #
        # 6DOF transform selector
        #
        self.sixDOFTransformSelector = slicer.qMRMLNodeComboBox()
        self.sixDOFTransformSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
        self.sixDOFTransformSelector.selectNodeUponCreation = True
        self.sixDOFTransformSelector.addEnabled = False
        self.sixDOFTransformSelector.removeEnabled = False
        self.sixDOFTransformSelector.noneEnabled = True
        self.sixDOFTransformSelector.showHidden = False
        self.sixDOFTransformSelector.showChildNodeTypes = False
        self.sixDOFTransformSelector.setMRMLScene(slicer.mrmlScene)
        self.sixDOFTransformSelector.setToolTip(
            "Pick the transform describing the 6DOF sensor.")
        parametersFormLayout.addRow("6DOF Transform: ",
                                    self.sixDOFTransformSelector)

        #
        # 6DOFModel to 6DOF transform selector
        #
        self.sixDOFModelTo6DOFTransformSelector = slicer.qMRMLNodeComboBox()
        self.sixDOFModelTo6DOFTransformSelector.nodeTypes = [
            "vtkMRMLLinearTransformNode"
        ]
        self.sixDOFModelTo6DOFTransformSelector.selectNodeUponCreation = True
        self.sixDOFModelTo6DOFTransformSelector.addEnabled = False
        self.sixDOFModelTo6DOFTransformSelector.removeEnabled = False
        self.sixDOFModelTo6DOFTransformSelector.noneEnabled = True
        self.sixDOFModelTo6DOFTransformSelector.showHidden = False
        self.sixDOFModelTo6DOFTransformSelector.showChildNodeTypes = False
        self.sixDOFModelTo6DOFTransformSelector.setMRMLScene(slicer.mrmlScene)
        self.sixDOFModelTo6DOFTransformSelector.setToolTip(
            "Pick the transform describing the 6DOF model offset.")
        parametersFormLayout.addRow("6DOF Model Transform: ",
                                    self.sixDOFModelTo6DOFTransformSelector)

        #
        # 5DOF transform selector
        #
        self.fiveDOFTransformSelector = slicer.qMRMLNodeComboBox()
        self.fiveDOFTransformSelector.nodeTypes = [
            "vtkMRMLLinearTransformNode"
        ]
        self.fiveDOFTransformSelector.selectNodeUponCreation = True
        self.fiveDOFTransformSelector.addEnabled = False
        self.fiveDOFTransformSelector.removeEnabled = False
        self.fiveDOFTransformSelector.noneEnabled = True
        self.fiveDOFTransformSelector.showHidden = False
        self.fiveDOFTransformSelector.showChildNodeTypes = False
        self.fiveDOFTransformSelector.setMRMLScene(slicer.mrmlScene)
        self.fiveDOFTransformSelector.setToolTip(
            "Pick the transform describing the 5DOF sensor.")
        parametersFormLayout.addRow("5DOF Transform: ",
                                    self.fiveDOFTransformSelector)

        #
        # 5DOFModel to 5DOFCalculated transform selector
        #
        self.fiveDOFModelTo5DOFCalculatedTransformSelector = slicer.qMRMLNodeComboBox(
        )
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.nodeTypes = [
            "vtkMRMLLinearTransformNode"
        ]
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.selectNodeUponCreation = True
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.addEnabled = False
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.removeEnabled = False
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.noneEnabled = True
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.showHidden = False
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.showChildNodeTypes = False
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.setMRMLScene(
            slicer.mrmlScene)
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.setToolTip(
            "Pick the transform describing the 5DOF model offset.")
        parametersFormLayout.addRow(
            "5DOF Model Transform: ",
            self.fiveDOFModelTo5DOFCalculatedTransformSelector)

        # Separator
        frame = qt.QWidget()
        layout = qt.QHBoxLayout(frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addStretch()
        layout.addWidget(qt.QLabel("Images"))
        layout.addStretch()
        parametersFormLayout.addRow(frame)

        #
        # ICE volume selector
        #
        self.iceVolumeSelector = slicer.qMRMLNodeComboBox()
        self.iceVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.iceVolumeSelector.selectNodeUponCreation = True
        self.iceVolumeSelector.addEnabled = False
        self.iceVolumeSelector.removeEnabled = False
        self.iceVolumeSelector.noneEnabled = True
        self.iceVolumeSelector.showHidden = False
        self.iceVolumeSelector.showChildNodeTypes = False
        self.iceVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.iceVolumeSelector.setToolTip(
            "Pick the volume from the ICE transducer.")
        parametersFormLayout.addRow("ICE Image: ", self.iceVolumeSelector)

        #
        # mask volume selector
        #
        self.maskVolumeSelector = slicer.qMRMLNodeComboBox()
        self.maskVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.maskVolumeSelector.selectNodeUponCreation = True
        self.maskVolumeSelector.addEnabled = False
        self.maskVolumeSelector.removeEnabled = False
        self.maskVolumeSelector.noneEnabled = True
        self.maskVolumeSelector.showHidden = False
        self.maskVolumeSelector.showChildNodeTypes = False
        self.maskVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.maskVolumeSelector.setToolTip(
            "Pick the volume with the mask image for the ICE transducer.")
        parametersFormLayout.addRow("ICE Mask: ", self.maskVolumeSelector)

        #
        # TEE volume selector
        #
        self.teeVolumeSelector = slicer.qMRMLNodeComboBox()
        self.teeVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.teeVolumeSelector.selectNodeUponCreation = True
        self.teeVolumeSelector.addEnabled = False
        self.teeVolumeSelector.removeEnabled = False
        self.teeVolumeSelector.noneEnabled = True
        self.teeVolumeSelector.showHidden = False
        self.teeVolumeSelector.showChildNodeTypes = False
        self.teeVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.teeVolumeSelector.setToolTip(
            "Pick the volume from the TEE transducer.")
        parametersFormLayout.addRow("TEE Image: ", self.teeVolumeSelector)

        #
        # output volume selector
        #
        self.maskedICEVolumeSelector = slicer.qMRMLNodeComboBox()
        self.maskedICEVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.maskedICEVolumeSelector.selectNodeUponCreation = True
        self.maskedICEVolumeSelector.addEnabled = True
        self.maskedICEVolumeSelector.renameEnabled = True
        self.maskedICEVolumeSelector.removeEnabled = False
        self.maskedICEVolumeSelector.noneEnabled = True
        self.maskedICEVolumeSelector.showHidden = False
        self.maskedICEVolumeSelector.showChildNodeTypes = False
        self.maskedICEVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.maskedICEVolumeSelector.setToolTip(
            "Pick the volume for the masked output.")
        parametersFormLayout.addRow("Masked Output: ",
                                    self.maskedICEVolumeSelector)

        # Separator
        frame = qt.QWidget()
        layout = qt.QHBoxLayout(frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addStretch()
        layout.addWidget(qt.QLabel("Models"))
        layout.addStretch()
        parametersFormLayout.addRow(frame)

        #
        # nose model selector
        #
        self.noseModelSelector = slicer.qMRMLNodeComboBox()
        self.noseModelSelector.nodeTypes = ["vtkMRMLModelNode"]
        self.noseModelSelector.selectNodeUponCreation = True
        self.noseModelSelector.addEnabled = False
        self.noseModelSelector.renameEnabled = False
        self.noseModelSelector.removeEnabled = False
        self.noseModelSelector.noneEnabled = True
        self.noseModelSelector.showHidden = False
        self.noseModelSelector.showChildNodeTypes = False
        self.noseModelSelector.setMRMLScene(slicer.mrmlScene)
        self.noseModelSelector.setToolTip("Select the nose model.")
        parametersFormLayout.addRow("Nose Model: ", self.noseModelSelector)

        #
        # jaw model selector
        #
        self.jawModelSelector = slicer.qMRMLNodeComboBox()
        self.jawModelSelector.nodeTypes = ["vtkMRMLModelNode"]
        self.jawModelSelector.selectNodeUponCreation = True
        self.jawModelSelector.addEnabled = False
        self.jawModelSelector.renameEnabled = False
        self.jawModelSelector.removeEnabled = False
        self.jawModelSelector.noneEnabled = True
        self.jawModelSelector.showHidden = False
        self.jawModelSelector.showChildNodeTypes = False
        self.jawModelSelector.setMRMLScene(slicer.mrmlScene)
        self.jawModelSelector.setToolTip("Select the jaw model.")
        parametersFormLayout.addRow("Jaw Model: ", self.jawModelSelector)

        #
        # Actions Area
        #
        actionsCollapsibleButton = ctk.ctkCollapsibleButton()
        actionsCollapsibleButton.text = "Actions"
        self.layout.addWidget(actionsCollapsibleButton)

        # Layout within the collapsible button
        actionsFormLayout = qt.QFormLayout(actionsCollapsibleButton)
        actionsFormLayout.setContentsMargins(8, 8, 8, 8)

        #
        # Zero Button
        #
        self.zeroButton = qt.QPushButton("Zero")
        self.zeroButton.toolTip = "Calibrate the jaws to the home position."
        self.zeroButton.enabled = False

        frame = qt.QWidget()
        layout = qt.QHBoxLayout(frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(qt.QLabel("Zero Jaws:"))
        layout.addStretch()
        layout.addWidget(self.zeroButton)
        actionsFormLayout.addRow(frame)

        #
        # UI Buttons
        #
        self.minUIButton = qt.QPushButton("Minimal UI")
        self.minUIButton.toolTip = "Show minimal UI."

        self.normalUIButton = qt.QPushButton("Normal UI")
        self.normalUIButton.toolTip = "Show normal UI."

        frame = qt.QWidget()
        layout = qt.QHBoxLayout(frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addStretch()
        layout.addWidget(self.minUIButton)
        layout.addWidget(self.normalUIButton)
        actionsFormLayout.addRow(frame)

        #
        # On/Off Button
        #
        self.onOffButton = qt.QPushButton("Turn On")
        self.onOffButton.toolTip = "Toggle guidance."
        self.onOffButton.enabled = False
        self.onOffButton.icon = self._loadPixmap("off")

        frame = qt.QWidget()
        layout = qt.QHBoxLayout(frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(qt.QLabel("Guidance:"))
        layout.addStretch()
        layout.addWidget(self.onOffButton)
        actionsFormLayout.addRow(frame)

        # connections
        self.zeroButton.connect('clicked(bool)', self.onZeroButtonClicked)
        self.onOffButton.connect('clicked(bool)',
                                 self.onOffToggleButtonClicked)
        self.minUIButton.connect('clicked(bool)', self.onMinUIButtonClicked)
        self.normalUIButton.connect('clicked(bool)',
                                    self.onNormUIButtonClicked)
        self.sixDOFTransformSelector.connect(
            "currentNodeChanged(vtkMRMLNode*)", self.onSixDOFSelectorChanged)
        self.fiveDOFTransformSelector.connect(
            "currentNodeChanged(vtkMRMLNode*)", self.onFiveDOFSelectorChanged)
        self.maskVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                        self.onMaskSelectorChanged)
        self.teeVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onTEEVolumeSelectorChanged)
        self.iceVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onICESelectorChanged)
        self.maskedICEVolumeSelector.connect(
            "currentNodeChanged(vtkMRMLNode*)",
            self.onMaskedICEVolumeSelectorChanged)
        self.jawModelSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                      self.onJawModelSelectorChanged)
        self.noseModelSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onNoseModelSelectorChanged)
        self.sixDOFModelTo6DOFTransformSelector.connect(
            "currentNodeChanged(vtkMRMLNode*)",
            self.on6DOFModelTo6DOFSelectorChanged)
        self.fiveDOFModelTo5DOFCalculatedTransformSelector.connect(
            "currentNodeChanged(vtkMRMLNode*)",
            self.on5DOFModelTo5DOFCalculatedSelectorChanged)

        # Add vertical spacer
        self.layout.addStretch(1)

        # Refresh button state
        self.onSelect()
    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=None):
            if family is None:
                family = qt.QFontDatabase.systemFont(
                    qt.QFontDatabase.FixedFont).family()
            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()
Beispiel #20
0
    def __init__(self, *args):
        BlissWidget.__init__(self, *args)

        self.camera       = None
        self.update_disabled = False
        self.__cameraName = None

        self.__zoomList = [1.5,2,2.5,3,3.5,4]
        self.__initZoom = 2

        self.__fixWidth  = -1
        self.__fixHeight = -1

        self.__swapRgb = True
                        ####### PRINT #######
        self.__printWidget = QubPrintPreview(self)
        self.__printWidget.resize(400,500)
        printer = qt.QPrinter()
        printer.setOutputToFile(1)
        printer.setOutputFileName('/tmp/print_file.ps')
        self.__printWidget.setPrinter(printer)
        self.__printWidget.update()

        self.__beamAction    = None
        self.__scaleAction   = None
        self.__chosenActions = {}
        self.__wholeActions  = []
        self.__measureDialog = None

        ####### PRINT ACTION #######
        printAction = QubPrintPreviewAction(name="print",group="admin",withVectorMenu=True)
        printAction.previewConnect(self.__printWidget)
        self.__wholeActions.append(printAction)

        ####### SAVE IMAGE #######
        self.__saveAction = QubSaveImageAction(parent=self, label='Save falcon image',
                                               name="save", group="admin")
        self.__saveAction.setConnectCallBack(self._save_dialog_new)
        self.__wholeActions.append(self.__saveAction)
        self.__defaultSavePath = '/tmp'

        ####### UPDATE #######
        update = QubToggleAction(name="update",group="image",initState=True)
        self.connect(update,qt.PYSIGNAL("StateChanged"),self.__cameraUpdate)
        self.__wholeActions.append(update)

        ####### Start Camera ######
        startCamera = QubToggleAction(name="startCamera", group="image", iconName = 'bright-cont', initState=True)
        self.connect(startCamera, qt.PYSIGNAL("StateChanged"), self.__cameraStart)
        self.__wholeActions.append(startCamera)


        ####### BRIGHTNESS/CONTRAST #######
        self.__brightcount = QubOpenDialogAction(name="bright-cont",
                                                 iconName = 'bright-cont', group="image")
        self.__brightcount.setDialog(QubBrightnessContrastDialog(self))
        self.__wholeActions.append(self.__brightcount)

        ###### Grid TOOL ######
        self.__gridToolAction = QubOpenDialogAction(parent=self, name='grid_tool',
                                                    iconName='rectangle', label='Grid tool',
                                                    group="Tools") #place="contextmenu")
        self.__gridDialog = GridDialog(self, "Grid Dialog", flags = qt.Qt.WStyle_StaysOnTop)
        self.__gridToolAction.setConnectCallBack(self._grid_dialog_connect_hdlr)
        self.__wholeActions.append(self.__gridToolAction)

        self.__previous_pos_dict = {}
        self.__beamWidth = 0
        self.__beamHeight = 0

        ####### BEAM ACTION #######
        self.__beamAction = QubBeamAction(name="beam", group="Tools")
        self.__wholeActions.append(self.__beamAction)
        self.connect(self.__beamAction,qt.PYSIGNAL("BeamSelected"),
                     self.beamSelection)

        ####### SCALE #######
        self.__scaleAction = QubScaleAction(name='scale',group='Tools')
        self.__wholeActions.append(self.__scaleAction)
        self.__wholeActions.extend(self.__creatStdActions())

        ####### ACTION INFO #######
        actionInfo = QubInfoAction(name="actionInfo", group="image",place="statusbar")
        self.__wholeActions.append(actionInfo)

        ####### CHANGE FOREGROUND COLOR #######
        self.__fcoloraction = QubForegroundColorAction(name="color", group="image")
        self.__wholeActions.append(self.__fcoloraction)

        ####### MEASURE #######
        self.__measureAction = QubOpenDialogAction(parent=self, name='measure',
                                            iconName='measure', label='Measure',
                                            group="Tools")
        self.__measureAction.setConnectCallBack(self._measure_dialog_new)
        self.__wholeActions.append(self.__measureAction)

        # ###### POSITION TOOL ######
        # self.__posToolAction = QubOpenDialogAction(parent=self, name='pos_tool',
        #                                            iconName='circle', label='Position tool',
        #                                            group="Tools")
        # self.__posToolAction.setConnectCallBack(self._line_dialog_new)
        # self.__wholeActions.append(self.__posToolAction)

        ####### ZOOM LIST #######
        zoomActionList = QubZoomListAction(place = "toolbar",
                                           initZoom = 1,zoomValList = [0.1,0.25,0.5,0.75,1,1.5,2],
                                           show = 1,group = "zoom")
        self.__wholeActions.append(zoomActionList)

        ####### ZOOM Action #######
        self.__zoomFitOrFill = QubZoomAction(place = "toolbar",group = "zoom")
        self.__wholeActions.append(self.__zoomFitOrFill)

        ####### LINK ZOOM ACTION #######
        self.__zoomFitOrFill.setList(zoomActionList)
        zoomActionList.setActionZoomMode(self.__zoomFitOrFill)

        ####### ZOOM WINDOW #######
        self.__zoomAction = QubZoomRectangle(label='Zoom Crop',place="toolbar", show=1, group="zoom")
        self.connect(self.__zoomAction,qt.PYSIGNAL("Actif"),self.__hide_show_zoom)
        self.__wholeActions.append(self.__zoomAction)

        self.__splitter = qt.QSplitter(qt.Qt.Horizontal,self)
        self.__splitter.show()

        self.__mainVideo = QubPixmapDisplayView(self.__splitter)
        self.__mainVideo.show()
        self.__mainVideo.setScrollbarMode('Auto')
        self.__mainPlug = _MainVideoPlug(self.__mainVideo,self.__zoomAction)

        actions = self.__creatStdActions()

        ####### ZOOM LIST #######
        self.__zoomActionList = QubZoomListAction(place = "toolbar",keepROI = True,
                                                  initZoom = self.__initZoom,zoomValList = self.__zoomList,
                                                  show = 1,group = "zoom")
        actions.insert(0,self.__zoomActionList)

        ####### ZOOM Action #######
        zoomFitOrFill = QubZoomAction(place = "toolbar",keepROI = True,group = "zoom")
        zoomFitOrFill.setList(self.__zoomActionList)
        self.__zoomActionList.setActionZoomMode(zoomFitOrFill)
        actions.append(zoomFitOrFill)

        self.__zoomVideo = QubPixmapDisplayView(self.__splitter,None,actions)
        self.__zoomVideo.hide()
        self.__zoomPlug = _ZoomPlug(self.__zoomVideo)
        self.__zoomPlug.zoom().setZoom(2,2)
        self.__cbk = _rectangleZoom(self.__zoomAction,self.__zoomPlug)

        layout = qt.QHBoxLayout(self,0,0,"layout")
        layout.addWidget(self.__splitter)

        self.__image2Pixmap = QubImage2Pixmap()
        self.__image2Pixmap.plug(self.__mainPlug)
        self.__zoomPlug.setPoller(self.__image2Pixmap)

        self.__jpegDecompress = QubStdData2Image()
        self.__jpegDecompress.setSwapRGB(True)
        self.__jpeg2image = None

        ####### PROPERTY #######
        self.addProperty('camera','string','')
        self.addProperty('zoom list','string',','.join([str(x) for x in self.__zoomList]))
        self.addProperty('init zoom','integer',self.__initZoom)
        self.addProperty('swap rgb','boolean',True)

        self.addProperty('fix : width','integer',-1)
        self.addProperty('fix : height','integer',-1)

        self.addProperty('action : print','boolean',True)
        self.addProperty('action : save image','boolean',True)
        self.addProperty('action : update','boolean',True)
        self.addProperty('action : startCamera','boolean',True)
        self.addProperty('action : brightness contrast','boolean',True)
        self.addProperty('action : beam','boolean',True)
        self.addProperty('action : scale','boolean',True)
        self.addProperty('action : change foreground color','boolean',True)
        self.addProperty('action : measure','boolean',True)
        self.addProperty('action : measure (place)', 'combo', ('toolbar','contextmenu'),'toolbar')
        self.addProperty('action : zoom window','boolean',True)
        self.addProperty('action : zoom fit or fill','boolean',True)
        self.addProperty('action : zoom list','boolean',True)
        self.addProperty('action : x,y coordinates','boolean',True)
        self.addProperty('action : default color','combo',('black','red','green'),'black')

        self.addProperty('action : save image (place)',"combo",('toolbar','contextmenu'),'toolbar')
        self.addProperty('action : save image (default path)',"string",'/tmp')
        self.addProperty('action : save image (show always configure)',"boolean",True)

        self.addProperty("diffractometer", "string", "")
        self.diffractometerHwobj = None


        ####### SIGNAL #######
        self.defineSignal("BeamPositionChanged", ())

        ####### SLOT #######
        self.defineSlot("changeBeamPosition", ())
        self.defineSlot("changePixelScale",())
        self.defineSlot('getView',())
        self.defineSlot('getImage',())

        ####### LINK VIEW AND SUB VIEW #######
        mainView = self.__mainVideo.view()
        zoomView = self.__zoomVideo.view()
        mainView.addEventMgrLink(zoomView,
                                 mainView.canvas(),zoomView.canvas(),
                                 mainView.matrix(),zoomView.matrix())

        self.imageReceivedConnected = None
    def setup(self):
        # Message suggesting using Segment Editor
        self.createSegmentEditorMessage()

        #
        # Editor Volumes
        #
        # only if showing volumes
        if self.showVolumesFrame:
            self.volumes = ctk.ctkCollapsibleButton(self.parent)
            self.volumes.objectName = 'VolumeCollapsibleButton'
            self.volumes.setLayout(qt.QVBoxLayout())
            self.volumes.setText("Create and Select Label Maps")
            self.layout.addWidget(self.volumes)
        else:
            self.volumes = None

        # create the helper box - note this isn't a Qt widget
        #  but a helper class that creates Qt widgets in the given parent
        if self.showVolumesFrame:
            self.helper = EditorLib.HelperBox(self.volumes)
        else:
            self.helper = None

        #
        # Tool Frame
        #

        # (we already have self.parent for the parent widget, and self.layout for the layout)
        # create the frames for the EditColor, toolsOptionsFrame and EditBox

        # create collapsible button for entire "edit label maps" section
        self.editLabelMapsFrame = ctk.ctkCollapsibleButton(self.parent)
        self.editLabelMapsFrame.objectName = 'EditLabelMapsFrame'
        self.editLabelMapsFrame.setLayout(qt.QVBoxLayout())
        self.editLabelMapsFrame.setText("Edit Selected Label Map")
        self.layout.addWidget(self.editLabelMapsFrame)
        self.editLabelMapsFrame.collapsed = True

        # create frame holding both the effect options and edit box:
        self.effectsToolsFrame = qt.QFrame(self.editLabelMapsFrame)
        self.effectsToolsFrame.objectName = 'EffectsToolsFrame'
        self.effectsToolsFrame.setLayout(qt.QHBoxLayout())
        self.editLabelMapsFrame.layout().addStretch(1)
        self.editLabelMapsFrame.layout().addWidget(self.effectsToolsFrame)

        # create frame for effect options
        self.createEffectOptionsFrame()

        # create and add frame for EditBox
        self.createEditBox()

        # create and add EditColor directly to "edit label map" section
        self.toolsColor = EditorLib.EditColor(self.editLabelMapsFrame)

        # put the tool options below the color selector
        self.editLabelMapsFrame.layout().addWidget(self.effectOptionsFrame)

        if self.helper:
            # add a callback to collapse/open the frame based on the validity of the label volume
            self.helper.mergeValidCommand = self.updateLabelFrame
            # add a callback to reset the tool when a new volume is selected
            self.helper.selectCommand = self.toolsBox.defaultEffect

        # Add spacer to layout
        self.layout.addStretch(1)
Beispiel #22
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()
  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)
Beispiel #24
0
    def setupOptionsFrame(self):

        self.methodSelectorComboBox = qt.QComboBox()
        self.methodSelectorComboBox.addItem("Median", MEDIAN)
        self.methodSelectorComboBox.addItem("Opening (remove extrusions)",
                                            MORPHOLOGICAL_OPENING)
        self.methodSelectorComboBox.addItem("Closing (fill holes)",
                                            MORPHOLOGICAL_CLOSING)
        self.methodSelectorComboBox.addItem("Gaussian", GAUSSIAN)
        self.methodSelectorComboBox.addItem("Joint smoothing", JOINT_TAUBIN)
        self.scriptedEffect.addLabeledOptionsWidget(
            "Smoothing method:", self.methodSelectorComboBox)

        self.kernelSizeMmSpinBox = slicer.qMRMLSpinBox()
        self.kernelSizeMmSpinBox.setMRMLScene(slicer.mrmlScene)
        self.kernelSizeMmSpinBox.setToolTip(
            "Diameter of the neighborhood that will be considered around each voxel. Higher value makes smoothing stronger (more details are suppressed)."
        )
        self.kernelSizeMmSpinBox.quantity = "length"
        self.kernelSizeMmSpinBox.minimum = 0.0
        self.kernelSizeMmSpinBox.value = 3.0
        self.kernelSizeMmSpinBox.singleStep = 1.0

        self.kernelSizePixel = qt.QLabel()
        self.kernelSizePixel.setToolTip(
            "Diameter of the neighborhood in pixels. Computed from the segment's spacing and the specified kernel size."
        )

        kernelSizeFrame = qt.QHBoxLayout()
        kernelSizeFrame.addWidget(self.kernelSizeMmSpinBox)
        kernelSizeFrame.addWidget(self.kernelSizePixel)
        self.kernelSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget(
            "Kernel size:", kernelSizeFrame)

        self.gaussianStandardDeviationMmSpinBox = slicer.qMRMLSpinBox()
        self.gaussianStandardDeviationMmSpinBox.setMRMLScene(slicer.mrmlScene)
        self.gaussianStandardDeviationMmSpinBox.setToolTip(
            "Standard deviation of the Gaussian smoothing filter coefficients. Higher value makes smoothing stronger (more details are suppressed)."
        )
        self.gaussianStandardDeviationMmSpinBox.quantity = "length"
        self.gaussianStandardDeviationMmSpinBox.value = 3.0
        self.gaussianStandardDeviationMmSpinBox.singleStep = 1.0
        self.gaussianStandardDeviationMmLabel = self.scriptedEffect.addLabeledOptionsWidget(
            "Standard deviation:", self.gaussianStandardDeviationMmSpinBox)

        self.jointTaubinSmoothingFactorSlider = ctk.ctkSliderWidget()
        self.jointTaubinSmoothingFactorSlider.setToolTip(
            "Higher value means stronger smoothing.")
        self.jointTaubinSmoothingFactorSlider.minimum = 0.01
        self.jointTaubinSmoothingFactorSlider.maximum = 1.0
        self.jointTaubinSmoothingFactorSlider.value = 0.5
        self.jointTaubinSmoothingFactorSlider.singleStep = 0.01
        self.jointTaubinSmoothingFactorSlider.pageStep = 0.1
        self.jointTaubinSmoothingFactorLabel = self.scriptedEffect.addLabeledOptionsWidget(
            "Smoothing factor:", self.jointTaubinSmoothingFactorSlider)

        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.objectName = self.__class__.__name__ + 'Apply'
        self.applyButton.setToolTip("Apply smoothing to selected segment")
        self.scriptedEffect.addOptionsWidget(self.applyButton)

        self.methodSelectorComboBox.connect("currentIndexChanged(int)",
                                            self.updateMRMLFromGUI)
        self.kernelSizeMmSpinBox.connect("valueChanged(double)",
                                         self.updateMRMLFromGUI)
        self.gaussianStandardDeviationMmSpinBox.connect(
            "valueChanged(double)", self.updateMRMLFromGUI)
        self.jointTaubinSmoothingFactorSlider.connect("valueChanged(double)",
                                                      self.updateMRMLFromGUI)
        self.applyButton.connect('clicked()', self.onApply)
Beispiel #25
0
 def createHLayout(elements):
     rowLayout = qt.QHBoxLayout()
     for element in elements:
         rowLayout.addWidget(element)
     return rowLayout
    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)
Beispiel #27
0
    def setupOptionsFrame(self):
        self.interpolationRadioButtons = []

        # Fiducial Placement widget
        self.fiducialPlacementToggle = slicer.qSlicerMarkupsPlaceWidget()
        self.fiducialPlacementToggle.setMRMLScene(slicer.mrmlScene)
        self.fiducialPlacementToggle.placeMultipleMarkups = self.fiducialPlacementToggle.ForcePlaceMultipleMarkups
        self.fiducialPlacementToggle.buttonsVisible = False
        self.fiducialPlacementToggle.show()
        self.fiducialPlacementToggle.placeButton().show()
        self.fiducialPlacementToggle.deleteButton().show()

        # Edit surface button
        self.editButton = qt.QPushButton("Edit")
        self.editButton.objectName = self.__class__.__name__ + 'Edit'
        self.editButton.setToolTip(
            "Edit the previously placed group of fiducials.")

        fiducialActionLayout = qt.QHBoxLayout()
        fiducialActionLayout.addWidget(self.fiducialPlacementToggle)
        fiducialActionLayout.addWidget(self.editButton)
        self.scriptedEffect.addLabeledOptionsWidget("Fiducial Placement: ",
                                                    fiducialActionLayout)

        # Radius spinbox
        self.radiusSpinBox = slicer.qMRMLSpinBox()
        self.radiusSpinBox.value = self.logic.radius
        self.radiusSpinBox.quantity = 'length'
        self.radiusSpinBox.unitAwareProperties = slicer.qMRMLSpinBox.MaximumValue | slicer.qMRMLSpinBox.Precision | slicer.qMRMLSpinBox.Prefix | slicer.qMRMLSpinBox.Suffix
        self.scriptedEffect.addLabeledOptionsWidget("Radius: ",
                                                    self.radiusSpinBox)

        # Interpolation buttons
        self.piecewiseLinearButton = qt.QRadioButton("Piecewise linear")
        self.interpolationRadioButtons.append(self.piecewiseLinearButton)
        self.buttonToInterpolationTypeMap[
            self.piecewiseLinearButton] = "LINEAR"

        self.cardinalSplineButton = qt.QRadioButton("Cardinal spline")
        self.interpolationRadioButtons.append(self.cardinalSplineButton)
        self.buttonToInterpolationTypeMap[
            self.cardinalSplineButton] = "CARDINAL_SPLINE"

        self.kochanekSplineButton = qt.QRadioButton("Kochanek spline")
        self.interpolationRadioButtons.append(self.kochanekSplineButton)
        self.buttonToInterpolationTypeMap[
            self.kochanekSplineButton] = "KOCHANEK_SPLINE"

        self.globalPolynomialButton = qt.QRadioButton("Global polynomial")
        self.interpolationRadioButtons.append(self.globalPolynomialButton)
        self.buttonToInterpolationTypeMap[
            self.globalPolynomialButton] = "GLOBAL_POLYNOMIAL"

        self.movingPolynomialButton = qt.QRadioButton("Moving polynomial")
        self.interpolationRadioButtons.append(self.movingPolynomialButton)
        self.buttonToInterpolationTypeMap[
            self.movingPolynomialButton] = "MOVING_POLYNOMIAL"

        # Segments per point spinbox
        self.numberOfLineSegmentsSpinBox = qt.QSpinBox()
        self.numberOfLineSegmentsSpinBox.value = 15
        # To keep GUI simple, we do not show numberOfLineSegmentsSpinBox.
        # Default value should work for most cases and modules can programmatically change this value, if needed.
        # If user feedback confirms that this parameter must be exposed then the next line can be uncommented.
        # self.scriptedEffect.addLabeledOptionsWidget("Segments between points: ", self.numberOfLineSegmentsSpinBox)

        # Interpolation buttons layout
        interpolationLayout = qt.QGridLayout()
        interpolationLayout.addWidget(self.piecewiseLinearButton, 0, 0)
        interpolationLayout.addWidget(self.cardinalSplineButton, 1, 0)
        interpolationLayout.addWidget(self.kochanekSplineButton, 0, 1)
        interpolationLayout.addWidget(self.globalPolynomialButton, 1, 1)
        interpolationLayout.addWidget(self.movingPolynomialButton, 0, 2)

        self.scriptedEffect.addLabeledOptionsWidget("Interpolation:",
                                                    interpolationLayout)

        # Apply button
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.objectName = self.__class__.__name__ + 'Apply'
        self.applyButton.setToolTip("Generate tube from markup fiducials.")
        self.scriptedEffect.addOptionsWidget(self.applyButton)

        # Cancel button
        self.cancelButton = qt.QPushButton("Cancel")
        self.cancelButton.objectName = self.__class__.__name__ + 'Cancel'
        self.cancelButton.setToolTip("Clear fiducials and remove from scene.")

        # Finish action buttons
        finishAction = qt.QHBoxLayout()
        finishAction.addWidget(self.cancelButton)
        finishAction.addWidget(self.applyButton)
        self.scriptedEffect.addOptionsWidget(finishAction)

        # Connections
        for button in self.interpolationRadioButtons:
            button.connect('toggled(bool)',
                           lambda toggle, widget=self.
                           buttonToInterpolationTypeMap[button]: self.
                           onInterpolationSelectionChanged(widget, toggle))
        self.applyButton.connect('clicked()', self.onApply)
        self.cancelButton.connect('clicked()', self.onCancel)
        self.editButton.connect('clicked()', self.onEdit)
        self.fiducialPlacementToggle.placeButton().clicked.connect(
            self.onFiducialPlacementToggleChanged)
        self.radiusSpinBox.connect('valueChanged(double)',
                                   self.onRadiusChanged)
        self.numberOfLineSegmentsSpinBox.connect(
            'valueChanged(int)', self.onNumberOfLineSegmentsChanged)
Beispiel #28
0
    def __init__(self,
                 parent=None,
                 name="data_collect",
                 selection_changed=None):
        qt.QWidget.__init__(self, parent, name)

        # Internal members
        self.collecting = False
        self.centring_method = 0
        self.queue_hwobj = None
        self.queue_model_hwobj = None
        self.beamline_setup_hwobj = None
        self.sample_centring_result = gevent.event.AsyncResult()

        # HW-Object set by TreeBrick
        self.sample_changer_hwobj = None
        self.plate_manipulator_hwobj = None
        self.hl_motor_hwobj = None
        self.tree_brick = self.parent()

        self.sample_item_list = []
        self.collect_tree_task = None
        self.user_stopped = False
        self.plate_sample_to_mount = None

        # Callbacks TODO:Document better
        self.selection_changed_cb = None
        self.collect_stop_cb = None
        #self.clear_centred_positions_cb = None
        self.run_cb = None

        # Layout
        self.setCaption("Data collect")

        self.confirm_dialog = ConfirmDialog(self, 'Confirm Dialog')
        self.confirm_dialog.setModal(True)

        self.pin_pixmap = Icons.load("sample_axis.png")
        self.task_pixmap = Icons.load("task.png")
        self.play_pixmap = Icons.load("VCRPlay.png")
        self.stop_pixmap = Icons.load("Stop.png")
        self.up_pixmap = Icons.load("Up2.png")
        self.down_pixmap = Icons.load("Down2.png")
        self.delete_pixmap = Icons.load("bin_small.png")
        self.ispyb_pixmap = Icons.load("SampleChanger2.png")
        self.caution_pixmap = Icons.load("Caution2.png")

        self.up_button = qt.QPushButton(self, "up_button")
        self.up_button.setPixmap(self.up_pixmap)
        self.up_button.setFixedHeight(25)

        self.delete_button = qt.QPushButton(self, "delete_button")
        self.delete_button.setPixmap(self.delete_pixmap)
        self.delete_button.setDisabled(True)
        qt.QToolTip.add(self.delete_button, "Delete highlighted queue entries")

        self.down_button = qt.QPushButton(self, "down_button")
        self.down_button.setPixmap(self.down_pixmap)
        self.down_button.setFixedHeight(25)

        self.collect_button = qt.QPushButton(self, "collect_button")
        self.collect_button.setText("Collect Queue")
        self.collect_button.setFixedWidth(125)
        self.collect_button.setIconSet(qt.QIconSet(self.play_pixmap))
        self.collect_button.setPaletteBackgroundColor(
            widget_colors.LIGHT_GREEN)

        self.continue_button = qt.QPushButton(self, "ok_button")
        self.continue_button.setText('Pause')
        self.continue_button.setEnabled(True)
        self.continue_button.setFixedWidth(75)
        qt.QToolTip.add(self.continue_button,
                        "Pause after current data collection")

        self.sample_list_view = qt.QListView(self, "sample_list_view")
        self.sample_list_view.setSelectionMode(qt.QListView.Extended)

        self.setSizePolicy(
            qt.QSizePolicy(qt.QSizePolicy.Fixed, qt.QSizePolicy.Expanding))
        self.sample_list_view.setSizePolicy(
            qt.QSizePolicy(qt.QSizePolicy.Fixed, qt.QSizePolicy.Expanding))

        self.sample_list_view.setSorting(-1)
        self.sample_list_view.addColumn("", 280)
        self.sample_list_view.addColumn("", 130)
        self.sample_list_view.header().hide()

        self.sample_list_view.header().hide()
        self.sample_list_view.setFrameShape(qt.QListView.StyledPanel)
        self.sample_list_view.setFrameShadow(qt.QListView.Sunken)
        self.sample_list_view.setRootIsDecorated(1)
        self.sample_list_view.setSelected(self.sample_list_view.firstChild(),
                                          True)

        layout = qt.QVBoxLayout(self, 0, 0, 'main_layout')
        button_layout = qt.QHBoxLayout(None, 0, 0, 'button_layout')
        button_layout.addWidget(self.up_button)
        button_layout.addWidget(self.down_button)
        layout.setSpacing(10)
        layout.addWidget(self.sample_list_view)
        self.buttons_grid_layout = qt.QGridLayout(2, 5)
        layout.addLayout(self.buttons_grid_layout)
        self.buttons_grid_layout.addLayout(button_layout, 0, 0)
        self.buttons_grid_layout.addWidget(self.delete_button, 0, 4)
        self.buttons_grid_layout.addWidget(self.collect_button, 1, 0)
        self.buttons_grid_layout.addWidget(self.continue_button, 1, 4)

        self.clearWState(qt.Qt.WState_Polished)

        qt.QObject.connect(self.up_button, qt.SIGNAL("clicked()"),
                           self.up_click)
        qt.QObject.connect(self.down_button, qt.SIGNAL("clicked()"),
                           self.down_click)
        qt.QObject.connect(self.delete_button, qt.SIGNAL("clicked()"),
                           self.delete_click)
        qt.QObject.connect(self.collect_button, qt.SIGNAL("clicked()"),
                           self.collect_stop_toggle)

        qt.QObject.connect(self.sample_list_view,
                           qt.SIGNAL("selectionChanged()"),
                           self.sample_list_view_selection)

        qt.QObject.connect(
            self.sample_list_view,
            qt.SIGNAL(
                "contextMenuRequested(QListViewItem *, const QPoint& , int)"),
            self.show_context_menu)

        qt.QObject.connect(
            self.sample_list_view,
            qt.SIGNAL("itemRenamed(QListViewItem *, int , const QString& )"),
            self.item_renamed)

        qt.QObject.connect(
            self.sample_list_view,
            qt.SIGNAL("doubleClicked(QListViewItem *, const QPoint &, int)"),
            self.item_double_click)

        qt.QObject.connect(
            self.sample_list_view,
            qt.SIGNAL(
                "mouseButtonClicked(int, QListViewItem *, const QPoint &, int)"
            ), self.item_click)

        qt.QObject.connect(self.confirm_dialog,
                           qt.PYSIGNAL("continue_clicked"), self.collect_items)

        qt.QObject.connect(self.continue_button, qt.SIGNAL("clicked()"),
                           self.continue_button_click)

        self.sample_list_view.viewport().installEventFilter(self)
        self.setFixedWidth(415)

        self.collect_button.setDisabled(True)
Beispiel #29
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()
Beispiel #30
0
  def setupOptionsFrame(self):
    self.operationRadioButtons = []

    #Fiducial Placement widget
    self.fiducialPlacementToggle = slicer.qSlicerMarkupsPlaceWidget()
    self.fiducialPlacementToggle.setMRMLScene(slicer.mrmlScene)
    self.fiducialPlacementToggle.placeMultipleMarkups = self.fiducialPlacementToggle.ForcePlaceMultipleMarkups
    self.fiducialPlacementToggle.buttonsVisible = False
    self.fiducialPlacementToggle.show()
    self.fiducialPlacementToggle.placeButton().show()
    self.fiducialPlacementToggle.deleteButton().show()

    # Edit surface button
    self.editButton = qt.QPushButton("Edit")
    self.editButton.objectName = self.__class__.__name__ + 'Edit'
    self.editButton.setToolTip("Edit the previously placed group of fiducials.")

    fiducialAction = qt.QHBoxLayout()
    fiducialAction.addWidget(self.fiducialPlacementToggle)
    fiducialAction.addWidget(self.editButton)
    self.scriptedEffect.addLabeledOptionsWidget("Fiducial Placement: ", fiducialAction)

    #Operation buttons
    self.eraseInsideButton = qt.QRadioButton("Erase inside")
    self.operationRadioButtons.append(self.eraseInsideButton)
    self.buttonToOperationNameMap[self.eraseInsideButton] = 'ERASE_INSIDE'

    self.eraseOutsideButton = qt.QRadioButton("Erase outside")
    self.operationRadioButtons.append(self.eraseOutsideButton)
    self.buttonToOperationNameMap[self.eraseOutsideButton] = 'ERASE_OUTSIDE'

    self.fillInsideButton = qt.QRadioButton("Fill inside")
    self.operationRadioButtons.append(self.fillInsideButton)
    self.buttonToOperationNameMap[self.fillInsideButton] = 'FILL_INSIDE'

    self.fillOutsideButton = qt.QRadioButton("Fill outside")
    self.operationRadioButtons.append(self.fillOutsideButton)
    self.buttonToOperationNameMap[self.fillOutsideButton] = 'FILL_OUTSIDE'

    self.setButton = qt.QRadioButton("Set")
    self.operationRadioButtons.append(self.setButton)
    self.buttonToOperationNameMap[self.setButton] = 'SET'

    #Operation buttons layout
    operationLayout = qt.QGridLayout()
    operationLayout.addWidget(self.eraseInsideButton, 0, 0)
    operationLayout.addWidget(self.eraseOutsideButton, 1, 0)
    operationLayout.addWidget(self.fillInsideButton, 0, 1)
    operationLayout.addWidget(self.fillOutsideButton, 1, 1)
    operationLayout.addWidget(self.setButton, 0, 2)

    self.scriptedEffect.addLabeledOptionsWidget("Operation:", operationLayout)

    # Apply button
    self.applyButton = qt.QPushButton("Apply")
    self.applyButton.objectName = self.__class__.__name__ + 'Apply'
    self.applyButton.setToolTip("Generate surface from markup fiducials.")
    self.scriptedEffect.addOptionsWidget(self.applyButton)

    # Cancel button
    self.cancelButton = qt.QPushButton("Cancel")
    self.cancelButton.objectName = self.__class__.__name__ + 'Cancel'
    self.cancelButton.setToolTip("Clear fiducials and remove from scene.")

    #Finish action buttons
    finishAction = qt.QHBoxLayout()
    finishAction.addWidget(self.cancelButton)
    finishAction.addWidget(self.applyButton)
    self.scriptedEffect.addOptionsWidget(finishAction)

    # connections
    for button in self.operationRadioButtons:
      button.connect('toggled(bool)',
      lambda toggle, widget=self.buttonToOperationNameMap[button]: self.onOperationSelectionChanged(widget, toggle))
    self.applyButton.connect('clicked()', self.onApply)
    self.cancelButton.connect('clicked()', self.onCancel)
    self.editButton.connect('clicked()', self.onEdit)
    self.fiducialPlacementToggle.placeButton().clicked.connect(self.onFiducialPlacementToggleChanged)