Ejemplo n.º 1
0
  def setup(self):
    self.setLayout(qt.QVBoxLayout())

    self.measurementTree = slicer.qMRMLSubjectHierarchyTreeView()
    self.measurementTree.setMRMLScene(slicer.mrmlScene)
    qSize = qt.QSizePolicy()
    qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding)
    qSize.setVerticalPolicy(qt.QSizePolicy.MinimumExpanding)
    qSize.setVerticalStretch(1)
    self.measurementTree.setSizePolicy(qSize)
    # self.measurementTree.editMenuActionVisible = True
    self.measurementTree.setColumnHidden(self.measurementTree.model().idColumn, True)
    self.measurementTree.setColumnHidden(self.measurementTree.model().transformColumn, True)
    self.layout().addWidget(self.measurementTree)
Ejemplo n.º 2
0
    def __init__(self):

        self.view = slicer.qMRMLSubjectHierarchyTreeView(
            slicer.util.mainWindow())
        self.view.setMRMLScene(slicer.mrmlScene)
        self.view.contextMenuEnabled = False
        self.view.setEditTriggers(0)  # disable double click to edit
        self.view.nodeTypes = ('vtkMRMLModelNode', 'vtkMRMLFolderDisplayNode')
        self.view.attributeNameFilter = ('atlas')
        for key in ['idColumn', 'transformColumn', 'descriptionColumn']:
            self.view.setColumnHidden(eval('self.view.model().' + key), True)

        self.view.doubleClicked.connect(self.onDoubleClick)

        super().__init__()

        self.addButton.setText('Atlas')
        self.addButton.setToolTip('Add atlas')

        self.buttonsFrame.layout().addStretch(2)

        self.updateTable()
Ejemplo n.º 3
0
    def section_AttributeFilters(self):
        self.delayDisplay("Attribute filters", self.delayMs)

        import SampleData
        sceneFile = SampleData.downloadFromURL(
            fileNames=self.attributeFilterTestSceneFileName,
            uris=self.attributeFilterTestSceneFileUrl,
            # loadFiles=True,
            checksums=self.attributeFilterTestSceneChecksum)[0]
        if not os.path.exists(sceneFile):
            logging.error(
                'Failed to download attribute filter test scene to path ' +
                str(sceneFile))
        self.assertTrue(os.path.exists(sceneFile))

        slicer.mrmlScene.Clear()
        ioManager = slicer.app.ioManager()
        ioManager.loadFile(sceneFile)

        # The loaded scene contains the following items and data nodes
        #
        # Scene
        #  +----- NewFolder
        #  |       +----------- MarkupsAngle (DataNode:vtkMRMLMarkupsAngleNode1)
        #  |       |             (ItemAttributes: ItemAttribute1:'1')
        #  |       |             (NodeAttributes: Markups.MovingInSliceView:'Red', Markups.MovingMarkupIndex:'1')
        #  |       +----------- MarkupsAngle_1 (DataNode:vtkMRMLMarkupsAngleNode2)
        #  |       |             (NodeAttributes: Markups.MovingInSliceView:'Red', Markups.MovingMarkupIndex:'1')
        #  |       +----------- MarkupsAngle_2 (DataNode:vtkMRMLMarkupsAngleNode3)
        #  |                     (NodeAttributes: Markups.MovingInSliceView:'Red', Markups.MovingMarkupIndex:'1', ParentAttribute:'')
        #  |                     +----------- MarkupsAngle_2 (DataNode:vtkMRMLMarkupsAngleNode3)
        #  |                                   (NodeAttributes: Markups.MovingInSliceView:'Red', Markups.MovingMarkupIndex:'1', ChildAttribute:'')
        #  +----- NewFolder_1
        #  |       (ItemAttributes: FolderAttribute1:'1')
        #  |       +----------- MarkupsCurve_1 (DataNode:vtkMRMLMarkupsCurveNode2)
        #  |       |             (NodeAttributes: Markups.MovingMarkupIndex:'3', Sajt:'Green')
        #  |       +----------- MarkupsCurve (DataNode:vtkMRMLMarkupsCurveNode1)
        #  |                     (ItemAttributes: ItemAttribute2:'2')
        #  |                     (NodeAttributes: Markups.MovingMarkupIndex:'2', Sajt:'Green')
        #  +----- MarkupsCurve_2 (DataNode:vtkMRMLMarkupsCurveNode1)
        #          (NodeAttributes: Markups.MovingMarkupIndex:'3', Sajt:'Green')

        shNode = slicer.mrmlScene.GetSubjectHierarchyNode()

        # Check scene validity
        self.assertEqual(9, shNode.GetNumberOfItems())
        self.assertEqual(
            slicer.mrmlScene.GetNumberOfNodesByClass('vtkMRMLMarkupsNode'), 7)

        # Create test SH tree view
        shTreeView = slicer.qMRMLSubjectHierarchyTreeView()
        shTreeView.setMRMLScene(slicer.mrmlScene)
        shTreeView.show()

        shProxyModel = shTreeView.sortFilterProxyModel()

        def testAttributeFilters(filteredObject, proxyModel):
            # Check include node attribute name filter
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            filteredObject.includeNodeAttributeNamesFilter = [
                'Markups.MovingInSliceView'
            ]
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 5)
            filteredObject.addNodeAttributeFilter('Sajt')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            filteredObject.includeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            # Check attribute value filter
            filteredObject.addNodeAttributeFilter('Markups.MovingMarkupIndex',
                                                  3)
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 3)
            filteredObject.includeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            filteredObject.addNodeAttributeFilter('Markups.MovingMarkupIndex',
                                                  '3')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 3)
            filteredObject.includeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)

            # Check exclude node attribute name filter (overrides include node attribute name filter)
            filteredObject.excludeNodeAttributeNamesFilter = [
                'Markups.MovingInSliceView'
            ]
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 5)
            filteredObject.excludeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            # Check if exclude indeed overrides include node attribute name filter
            filteredObject.includeNodeAttributeNamesFilter = [
                'Markups.MovingMarkupIndex'
            ]
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            filteredObject.excludeNodeAttributeNamesFilter = [
                'Markups.MovingInSliceView'
            ]
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 4)
            filteredObject.includeNodeAttributeNamesFilter = []
            filteredObject.excludeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)

            # Check include item attribute name filter
            filteredObject.includeItemAttributeNamesFilter = ['ItemAttribute1']
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 2)
            filteredObject.includeItemAttributeNamesFilter = [
                'ItemAttribute1', 'FolderAttribute1'
            ]
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 3)
            filteredObject.addItemAttributeFilter('ItemAttribute2')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 4)
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 4)
            filteredObject.includeItemAttributeNamesFilter = [
                'ItemAttribute1', 'ItemAttribute2'
            ]
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 4)
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 4)
            filteredObject.includeItemAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)

            # Check legacy (item) attribute value filter
            filteredObject.attributeNameFilter = 'ItemAttribute1'
            filteredObject.attributeValueFilter = '1'
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 2)
            filteredObject.attributeNameFilter = ''
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)

            # Check exclude item attribute name filter (overrides include item attribute filter)
            filteredObject.excludeItemAttributeNamesFilter = ['ItemAttribute1']
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 8)
            filteredObject.excludeItemAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            # Check if exclude indeed overrides include item attribute filter
            filteredObject.includeItemAttributeNamesFilter = ['ItemAttribute1']
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 2)
            filteredObject.excludeItemAttributeNamesFilter = ['ItemAttribute1']
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 0)
            filteredObject.includeItemAttributeNamesFilter = []
            filteredObject.excludeItemAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            filteredObject.excludeItemAttributeNamesFilter = [
                'FolderAttribute1'
            ]
            # Note: Shown only 6 because accepted children of rejected parents are not shown
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 8)
            filteredObject.excludeItemAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)

            # Check attribute filtering with class name and attribute value
            filteredObject.addNodeAttributeFilter('Markups.MovingMarkupIndex',
                                                  3, True,
                                                  'vtkMRMLMarkupsCurveNode')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 3)
            filteredObject.addNodeAttributeFilter('ParentAttribute', '', True,
                                                  'vtkMRMLMarkupsAngleNode')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 5)
            filteredObject.addNodeAttributeFilter('ChildAttribute', '', True,
                                                  'vtkMRMLMarkupsAngleNode')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 6)
            filteredObject.includeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)
            # Check with empty attribute value
            filteredObject.addNodeAttributeFilter('Markups.MovingMarkupIndex',
                                                  '', True,
                                                  'vtkMRMLMarkupsCurveNode')
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 4)
            filteredObject.includeNodeAttributeNamesFilter = []
            self.assertEqual(
                shProxyModel.acceptedItemCount(shNode.GetSceneItemID()), 9)

        logging.info('Test attribute filters on proxy model directly')
        testAttributeFilters(shProxyModel, shProxyModel)
        logging.info('Test attribute filters on tree view')
        testAttributeFilters(shTreeView, shProxyModel)
Ejemplo n.º 4
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        # Set up tabs to split workflow
        tabsWidget = qt.QTabWidget()
        curvesTab = qt.QWidget()
        curvesTabLayout = qt.QFormLayout(curvesTab)
        fiducialsTab = qt.QWidget()
        fiducialsTabLayout = qt.QFormLayout(fiducialsTab)
        batchTab = qt.QWidget()
        batchTabLayout = qt.QFormLayout(batchTab)

        tabsWidget.addTab(curvesTab, "Merge Curves")
        tabsWidget.addTab(fiducialsTab, "Merge Landmark Sets")
        tabsWidget.addTab(batchTab, "Batch Merge Landmark Sets")
        self.layout.addWidget(tabsWidget)
        ################## Curves Tab
        #
        # Parameters Area
        #
        parametersCurveCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCurveCollapsibleButton.text = "Curve Viewer"
        curvesTabLayout.addRow(parametersCurveCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersCurveFormLayout = qt.QFormLayout(
            parametersCurveCollapsibleButton)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.continuousCurvesCheckBox = qt.QCheckBox()
        self.continuousCurvesCheckBox.checked = 0
        self.continuousCurvesCheckBox.setToolTip(
            "If checked, redundant points will be removed on merging.")
        parametersCurveFormLayout.addRow("Contiuous curves",
                                         self.continuousCurvesCheckBox)

        #
        # markups view
        #
        self.markupsView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsView.setMRMLScene(slicer.mrmlScene)
        self.markupsView.setMultiSelection(True)
        self.markupsView.setAlternatingRowColors(True)
        self.markupsView.setDragDropMode(qt.QAbstractItemView().DragDrop)
        self.markupsView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsCurveNode"])
        parametersCurveFormLayout.addRow(self.markupsView)

        #
        # Merge Button
        #
        self.mergeButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeButton.enabled = False
        parametersCurveFormLayout.addRow(self.mergeButton)

        # connections
        self.mergeButton.connect('clicked(bool)', self.onMergeButton)
        self.markupsView.connect('currentItemChanged(vtkIdType)',
                                 self.updateMergeButton)

        ################ Landmark Set Tab
        #
        # Parameters Area
        #
        parametersLMCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersLMCollapsibleButton.text = "Landmark Viewer"
        fiducialsTabLayout.addRow(parametersLMCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersLMFormLayout = qt.QGridLayout(parametersLMCollapsibleButton)

        #
        # markups view
        #
        self.markupsFiducialView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsFiducialView.setMRMLScene(slicer.mrmlScene)
        self.markupsFiducialView.setMultiSelection(True)
        self.markupsFiducialView.setAlternatingRowColors(True)
        self.markupsFiducialView.setDragDropMode(
            qt.QAbstractItemView().DragDrop)
        self.markupsFiducialView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsFiducialView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsFiducialNode"])
        parametersLMFormLayout.addWidget(self.markupsFiducialView, 0, 0, 1, 3)

        #
        # Set landmark type menu
        #
        boxLabel = qt.QLabel("Select landmark type description to apply: ")
        self.LandmarkTypeSelection = qt.QComboBox()
        self.LandmarkTypeSelection.addItems(
            ["Select", "Fixed", "Semi", "No description"])
        parametersLMFormLayout.addWidget(boxLabel, 1, 0)
        parametersLMFormLayout.addWidget(self.LandmarkTypeSelection, 1, 1)

        #
        # Apply Landmark Type Button
        #
        self.ApplyLMButton = qt.QPushButton("Apply to highlighted nodes")
        self.ApplyLMButton.toolTip = "Apply the selected landmark type to points in the the selected nodes"
        self.ApplyLMButton.enabled = False
        parametersLMFormLayout.addWidget(self.ApplyLMButton, 1, 2)

        #
        # Merge Button
        #
        self.mergeLMButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeLMButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeLMButton.enabled = False
        parametersLMFormLayout.addWidget(self.mergeLMButton, 2, 0, 1, 3)

        # connections
        self.mergeLMButton.connect('clicked(bool)', self.onMergeLMButton)
        self.ApplyLMButton.connect('clicked(bool)', self.onApplyLMButton)
        self.markupsFiducialView.connect('currentItemChanged(vtkIdType)',
                                         self.updateMergeLMButton)
        self.LandmarkTypeSelection.connect('currentIndexChanged(int)',
                                           self.updateApplyLMButton)

        ################ Batch Run LM Merge Tab
        #
        # Fixed LM Area
        #
        fixedBatchCollapsibleButton = ctk.ctkCollapsibleButton()
        fixedBatchCollapsibleButton.text = "Fixed LM File Selection"
        batchTabLayout.addRow(fixedBatchCollapsibleButton)

        # Layout within the dummy collapsible button
        fixedBatchLayout = qt.QFormLayout(fixedBatchCollapsibleButton)

        #
        # Browse Fixed LM Button
        #
        self.browseFixedLMButton = qt.QPushButton("Select files...")
        self.browseFixedLMButton.toolTip = "Select one fixed landmark file for each subject"
        self.browseFixedLMButton.enabled = True
        fixedBatchLayout.addRow(self.browseFixedLMButton)

        #
        # File viewer box
        #
        self.fixedFileTable = qt.QTextEdit()
        fixedBatchLayout.addRow(self.fixedFileTable)

        #
        # Semi LM Area
        #
        semiBatchCollapsibleButton = ctk.ctkCollapsibleButton()
        semiBatchCollapsibleButton.text = "Semi LM File Selection"
        batchTabLayout.addRow(semiBatchCollapsibleButton)

        # Layout within the dummy collapsible button
        semiBatchLayout = qt.QFormLayout(semiBatchCollapsibleButton)

        #
        # Browse Fixed LM Button
        #
        self.browseSemiLMButton = qt.QPushButton("Select files...")
        self.browseSemiLMButton.toolTip = "Select one semi-landmark file for each subject, in the same order as the fixed landmarks"
        self.browseSemiLMButton.enabled = True
        semiBatchLayout.addRow(self.browseSemiLMButton)

        #
        # File viewer box
        #
        self.semiFileTable = qt.QTextEdit()
        semiBatchLayout.addRow(self.semiFileTable)

        #
        # Merge LM Area
        #
        batchMergeCollapsibleButton = ctk.ctkCollapsibleButton()
        batchMergeCollapsibleButton.text = "Run merge"
        batchTabLayout.addRow(batchMergeCollapsibleButton)

        # Layout within the dummy collapsible button
        batchMergeLayout = qt.QFormLayout(batchMergeCollapsibleButton)

        #
        # Select output landmark directory
        #
        self.outputDirectorySelector = ctk.ctkPathLineEdit()
        self.outputDirectorySelector.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectorySelector.toolTip = "Select the output directory where the merged landmark nodes will be saved"
        batchMergeLayout.addRow("Select output landmark directory: ",
                                self.outputDirectorySelector)

        #
        # Batch Merge Button
        #
        self.batchMergeButton = qt.QPushButton(
            "Merge fixed and semi-landmark nodes")
        self.batchMergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.batchMergeButton.enabled = False
        batchMergeLayout.addRow(self.batchMergeButton)

        #
        # Clear Button
        #
        self.clearButton = qt.QPushButton("Clear landmark file selections")
        self.clearButton.toolTip = "Clear the landmark files selected in the viewer boxes"
        self.clearButton.enabled = False
        batchMergeLayout.addRow(self.clearButton)

        # connections
        self.browseFixedLMButton.connect('clicked(bool)',
                                         self.addFixedByBrowsing)
        self.browseSemiLMButton.connect('clicked(bool)',
                                        self.addSemiByBrowsing)
        self.outputDirectorySelector.connect('validInputChanged(bool)',
                                             self.onSelectDirectory)
        self.batchMergeButton.connect('clicked(bool)', self.onBatchMergeButton)
        self.clearButton.connect('clicked(bool)', self.onClearButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Ejemplo n.º 5
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        # 3D view set up tab
        self.meshSelect = slicer.qMRMLNodeComboBox()
        self.meshSelect.nodeTypes = (("vtkMRMLModelNode"), "")
        self.meshSelect.selectNodeUponCreation = False
        self.meshSelect.addEnabled = False
        self.meshSelect.removeEnabled = False
        self.meshSelect.noneEnabled = True
        self.meshSelect.showHidden = False
        self.meshSelect.setMRMLScene(slicer.mrmlScene)
        self.meshSelect.connect("currentNodeChanged(vtkMRMLNode*)",
                                self.onMeshSelect)
        parametersFormLayout.addRow("Model: ", self.meshSelect)
        self.meshSelect.setToolTip("Select model node for semilandmarking")

        self.LMSelect = slicer.qMRMLNodeComboBox()
        self.LMSelect.nodeTypes = (('vtkMRMLMarkupsFiducialNode'), "")
        self.LMSelect.selectNodeUponCreation = False
        self.LMSelect.addEnabled = False
        self.LMSelect.removeEnabled = False
        self.LMSelect.noneEnabled = True
        self.LMSelect.showHidden = False
        self.LMSelect.showChildNodeTypes = False
        self.LMSelect.setMRMLScene(slicer.mrmlScene)
        self.LMSelect.connect("currentNodeChanged(vtkMRMLNode*)",
                              self.onLMSelect)
        parametersFormLayout.addRow("Landmark set: ", self.LMSelect)
        self.LMSelect.setToolTip(
            "Select the landmark set that corresponds to the model")

        #
        # input landmark numbers for grid
        #
        gridPointsLayout = qt.QGridLayout()
        self.landmarkGridPoint1 = ctk.ctkDoubleSpinBox()
        self.landmarkGridPoint1.minimum = 0
        self.landmarkGridPoint1.singleStep = 1
        self.landmarkGridPoint1.setDecimals(0)
        self.landmarkGridPoint1.setToolTip(
            "Input the landmark numbers to create grid")

        self.landmarkGridPoint2 = ctk.ctkDoubleSpinBox()
        self.landmarkGridPoint2.minimum = 0
        self.landmarkGridPoint2.singleStep = 1
        self.landmarkGridPoint2.setDecimals(0)
        self.landmarkGridPoint2.setToolTip(
            "Input the landmark numbers to create grid")

        self.landmarkGridPoint3 = ctk.ctkDoubleSpinBox()
        self.landmarkGridPoint3.minimum = 0
        self.landmarkGridPoint3.singleStep = 1
        self.landmarkGridPoint3.setDecimals(0)
        self.landmarkGridPoint3.setToolTip(
            "Input the landmark numbers to create grid")

        gridPointsLayout.addWidget(self.landmarkGridPoint1, 1, 2)
        gridPointsLayout.addWidget(self.landmarkGridPoint2, 1, 3)
        gridPointsLayout.addWidget(self.landmarkGridPoint3, 1, 4)

        parametersFormLayout.addRow("Semi-landmark grid points:",
                                    gridPointsLayout)

        #
        # set number of sample points in each triangle
        #
        self.gridSamplingRate = ctk.ctkDoubleSpinBox()
        self.gridSamplingRate.minimum = 3
        self.gridSamplingRate.maximum = 50
        self.gridSamplingRate.singleStep = 1
        self.gridSamplingRate.setDecimals(0)
        self.gridSamplingRate.value = 10
        self.gridSamplingRate.setToolTip(
            "Input the landmark numbers to create grid")
        parametersFormLayout.addRow(
            "Select number of rows/columns in resampled grid:",
            self.gridSamplingRate)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # Advanced menu
        #
        advancedCollapsibleButton = ctk.ctkCollapsibleButton()
        advancedCollapsibleButton.text = "Advanced"
        advancedCollapsibleButton.collapsed = True
        parametersFormLayout.addRow(advancedCollapsibleButton)

        # Layout within the dummy collapsible button
        advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton)

        #
        # Maximum projection slider
        #
        self.projectionDistanceSlider = ctk.ctkSliderWidget()
        self.projectionDistanceSlider.singleStep = 1
        self.projectionDistanceSlider.minimum = 0
        self.projectionDistanceSlider.maximum = 100
        self.projectionDistanceSlider.value = 25
        self.projectionDistanceSlider.setToolTip(
            "Set maximum projection distance as a percentage of image size")
        advancedFormLayout.addRow("Set maximum projection distance: ",
                                  self.projectionDistanceSlider)

        #
        # Normal smoothing slider
        #
        self.smoothingSlider = ctk.ctkSliderWidget()
        self.smoothingSlider.singleStep = 1
        self.smoothingSlider.minimum = 0
        self.smoothingSlider.maximum = 100
        self.smoothingSlider.value = 0
        self.smoothingSlider.setToolTip(
            "Set smothing of normal vectors for projection")
        advancedFormLayout.addRow("Set smoothing of projection vectors: ",
                                  self.smoothingSlider)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate semilandmarks."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        #
        # Fiducials view
        #
        self.fiducialView = slicer.qMRMLSubjectHierarchyTreeView()
        self.fiducialView.setMRMLScene(slicer.mrmlScene)
        self.fiducialView.setMultiSelection(True)
        self.fiducialView.setAlternatingRowColors(True)
        self.fiducialView.setDragDropMode(True)
        self.fiducialView.setColumnHidden(
            self.fiducialView.model().transformColumn, True)
        self.fiducialView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsFiducialNode"])
        parametersFormLayout.addRow(self.fiducialView)

        #
        # Apply Button
        #
        self.mergeButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeButton.toolTip = "Generate a single merged landmark file from the selected nodes"
        self.mergeButton.enabled = False
        parametersFormLayout.addRow(self.mergeButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.mergeButton.connect('clicked(bool)', self.onMergeButton)
        self.fiducialView.connect('currentItemChanged(vtkIdType)',
                                  self.updateMergeButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Ejemplo n.º 6
0
    def setup(self):

        self.detailsPopup = None
        self.setDetailsPopup(self.getSavedDICOMDetailsWidgetType()())

        # XXX Slicer 4.5 - Remove these. Here only for backward compatibility.
        self.dicomBrowser = self.detailsPopup.dicomBrowser
        self.tables = self.detailsPopup.tables

        layoutManager = slicer.app.layoutManager()
        if layoutManager is not None:
            layoutManager.layoutChanged.connect(self.onLayoutChanged)

        # connect to the 'Show DICOM Browser' button
        self.showBrowserButton = qt.QPushButton('Show DICOM database browser')
        self.showBrowserButton.setCheckable(True)
        self.layout.addWidget(self.showBrowserButton)
        self.showBrowserButton.setStyleSheet("font:Bold;" "font-size:12px")
        self.showBrowserButton.connect('clicked()', self.toggleDetailsPopup)

        self.loadedDataLabel = qt.QLabel("Loaded data")
        self.loadedDataLabel.setSizePolicy(qt.QSizePolicy.Expanding,
                                           qt.QSizePolicy.Fixed)
        self.layout.addWidget(self.loadedDataLabel)
        font = qt.QFont()
        font.setBold(True)
        font.setPointSize(12)
        self.loadedDataLabel.setFont(font)
        self.layout.addWidget(self.loadedDataLabel)

        self.subjectHierarchyTree = slicer.qMRMLSubjectHierarchyTreeView()
        self.layout.addWidget(self.subjectHierarchyTree)
        self.subjectHierarchyTree.setMRMLScene(slicer.mrmlScene)
        self.subjectHierarchyTree.currentItemChanged.connect(
            self.onCurrentItemChanged)
        self.subjectHierarchyTree.currentItemModified.connect(
            self.onCurrentItemModified)
        self.subjectHierarchyCurrentVisibility = False
        self.subjectHierarchyTree.setColumnHidden(
            self.subjectHierarchyTree.model().idColumn, True)

        self.browserSettingsWidget = ctk.ctkCollapsibleGroupBox()
        self.browserSettingsWidget.title = "Browser settings"
        self.layout.addWidget(self.browserSettingsWidget)
        self.browserSettingsWidget.collapsed = True
        self.browserSettingsWidget.setLayout(qt.QFormLayout())

        self.directoryButton = ctk.ctkDirectoryButton()
        self.browserSettingsWidget.layout().addRow("Local database:",
                                                   self.directoryButton)
        self.directoryButton.directoryChanged.connect(
            self.onDatabaseDirectoryButtonChanged)
        self.onDatabaseDirectoryDetailsPopupChanged(
            self.detailsPopup.dicomBrowser.databaseDirectory)

        self.tableDensityComboBox = qt.QComboBox()
        self.browserSettingsWidget.layout().addRow("Table density:",
                                                   self.tableDensityComboBox)
        self.tableDensityComboBox.currentIndexChanged.connect(
            self.onTableDensityChanged)
        self.updateTableDensityComboBox()

        self.horizontalCheckBox = qt.QCheckBox()
        self.horizontalCheckBox.checked = settingsValue(
            'DICOM/horizontalTables', 0, converter=int)
        self.horizontalCheckBox.stateChanged.connect(
            self.onHorizontalStateChanged)
        self.browserSettingsWidget.layout().addRow("Horizontal:",
                                                   self.horizontalCheckBox)

        self.browserPersistentCheckBox = qt.QCheckBox()
        self.browserPersistentCheckBox.checked = settingsValue(
            'DICOM/BrowserPersistent', False, converter=toBool)
        self.browserPersistentCheckBox.stateChanged.connect(
            self.onBrowserPersistentStateChanged)
        self.browserSettingsWidget.layout().addRow(
            "Browser persistent:", self.browserPersistentCheckBox)

        self.additionalSettingsLayout = qt.QHBoxLayout()

        #
        # servers
        #

        # testing server - not exposed (used for development)
        self.localFrame = ctk.ctkCollapsibleButton(self.parent)
        self.localFrame.setLayout(qt.QVBoxLayout())
        self.localFrame.setText("Servers")
        self.layout.addWidget(self.localFrame)
        self.localFrame.collapsed = True

        self.toggleServer = qt.QPushButton("Start Testing Server")
        self.localFrame.layout().addWidget(self.toggleServer)
        self.toggleServer.connect('clicked()', self.onToggleServer)

        self.verboseServer = qt.QCheckBox("Verbose")
        self.localFrame.layout().addWidget(self.verboseServer)

        # advanced options - not exposed to end users
        # developers can uncomment these lines to access testing server
        self.toggleServer.hide()
        self.verboseServer.hide()

        # Listener

        settings = qt.QSettings()
        self.toggleListener = qt.QPushButton()
        self.toggleListener.checkable = True
        if hasattr(slicer, 'dicomListener'):
            self.toggleListener.text = "Stop Listener"
            slicer.dicomListener.process.connect(
                'stateChanged(QProcess::ProcessState)',
                self.onListenerStateChanged)
        else:
            self.toggleListener.text = "Start Listener"
        self.localFrame.layout().addWidget(self.toggleListener)
        self.toggleListener.connect('clicked()', self.onToggleListener)

        self.runListenerAtStart = qt.QCheckBox(
            "Start Listener when Slicer Starts")
        self.localFrame.layout().addWidget(self.runListenerAtStart)
        self.runListenerAtStart.checked = settingsValue(
            'DICOM/RunListenerAtStart', False, converter=toBool)
        self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart)

        # connect to the main window's dicom button
        mw = slicer.util.mainWindow()
        if mw:
            try:
                action = slicer.util.findChildren(mw,
                                                  name='LoadDICOMAction')[0]
                action.connect('triggered()', self.onOpenDetailsPopup)
            except IndexError:
                logging.error(
                    'Could not connect to the main window DICOM button')

        if hasattr(slicer, 'dicomListener'):
            slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile
            slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile

        slicer.dicomDatabase.connect('databaseChanged()',
                                     self.onDatabaseChanged)

        # the recent activity frame
        self.activityFrame = ctk.ctkCollapsibleButton(self.parent)
        self.activityFrame.collapsed = True
        self.activityFrame.setLayout(qt.QVBoxLayout())
        self.activityFrame.setText("Recent DICOM Activity")
        self.layout.addWidget(self.activityFrame)

        self.recentActivity = DICOMLib.DICOMRecentActivityWidget(
            self.activityFrame, detailsPopup=self.detailsPopup)
        self.activityFrame.layout().addWidget(self.recentActivity)
        self.requestUpdateRecentActivity()
Ejemplo n.º 7
0
    def __init__(self):

        super().__init__()

        layout = qt.QGridLayout(self)

        # set up tree view
        self.treeView = slicer.qMRMLSubjectHierarchyTreeView(
            slicer.util.mainWindow())
        self.treeView.setMRMLScene(slicer.mrmlScene)
        self.treeView.contextMenuEnabled = False
        self.treeView.setEditTriggers(0)  # disable double click to edit

        # add
        addPixmap = qt.QPixmap(
            os.path.join(os.path.split(__file__)[0], 'Icons', 'Add.png'))
        addIcon = qt.QIcon(addPixmap)
        self.addButton = qt.QToolButton()
        self.addButton.setToolButtonStyle(qt.Qt.ToolButtonTextBesideIcon)
        self.addButton.setSizePolicy(qt.QSizePolicy.MinimumExpanding,
                                     qt.QSizePolicy.Maximum)
        self.addButton.setIcon(addIcon)
        self.addButton.setIconSize(addPixmap.rect().size())
        self.addButton.setToolTip('Add')
        # delete
        deletePixmap = qt.QPixmap(
            os.path.join(os.path.split(__file__)[0], 'Icons', 'Delete.png'))
        deleteIcon = qt.QIcon(deletePixmap)
        self.deleteButton = qt.QPushButton()
        self.deleteButton.setIcon(deleteIcon)
        self.deleteButton.setIconSize(deletePixmap.rect().size())
        self.deleteButton.setToolTip('Delete')
        # rename
        renamePixmap = qt.QPixmap(
            os.path.join(os.path.split(__file__)[0], 'Icons', 'Rename.png'))
        renameIcon = qt.QIcon(renamePixmap)
        self.renameButton = qt.QPushButton()
        self.renameButton.setIcon(renameIcon)
        self.renameButton.setIconSize(renamePixmap.rect().size())
        self.renameButton.setToolTip('Rename')

        # set up filters
        filters = [
            treeViewSavedWarpFilter(),
            treeViewAtlasFilter(),
            treeViewDrawingsFilter(),
            treeViewSceneFilter()
        ]
        self.radioButtons = []

        for filt, pos in zip(filters, [[0, 0], [0, 2], [1, 0], [1, 2]]):
            filterRadioButton = qt.QRadioButton(filt.name)
            filterRadioButton.setToolTip(filt.toolTip)
            filterRadioButton.clicked.connect(
                lambda b, f=filt: self.onFilterRadioButtonClicked(f))
            layout.addWidget(filterRadioButton, pos[0], pos[1], 1, 2)
            self.radioButtons.append(filterRadioButton)

        layout.addWidget(self.addButton, 0, 4, 1, 2)
        layout.addWidget(self.deleteButton, 1, 4, 1, 1)
        layout.addWidget(self.renameButton, 1, 5, 1, 1)
        layout.addWidget(self.treeView, 2, 0, 1, 6)

        # when adding fixed points while one of them is selected the new one is not set in the correct parent folder
        # this is overdoing, but fixes the problem
        self.treeView.model().rowsAboutToBeInserted.connect(
            lambda: self.treeView.setCurrentItem(0))

        # init
        self.radioButtons[3].animateClick()
Ejemplo n.º 8
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.continuousCurvesCheckBox = qt.QCheckBox()
        self.continuousCurvesCheckBox.checked = 0
        self.continuousCurvesCheckBox.setToolTip(
            "If checked, redundant points will be removed on merging.")
        parametersFormLayout.addRow("Contiuous curves",
                                    self.continuousCurvesCheckBox)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate semilandmarks."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        #
        # markups view
        #
        self.markupsView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsView.setMRMLScene(slicer.mrmlScene)
        self.markupsView.setMultiSelection(True)
        self.markupsView.setAlternatingRowColors(True)
        self.markupsView.setDragDropMode(qt.QAbstractItemView().DragDrop)
        self.markupsView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsCurveNode"])
        parametersFormLayout.addRow(self.markupsView)

        #
        # Merge Button
        #
        self.mergeButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeButton.enabled = False
        parametersFormLayout.addRow(self.mergeButton)

        # connections
        self.mergeButton.connect('clicked(bool)', self.onMergeButton)
        self.markupsView.connect('currentItemChanged(vtkIdType)',
                                 self.updateMergeButton)

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