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)
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()
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)
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)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # 3D view set up tab self.meshSelect = slicer.qMRMLNodeComboBox() self.meshSelect.nodeTypes = (("vtkMRMLModelNode"), "") self.meshSelect.selectNodeUponCreation = False self.meshSelect.addEnabled = False self.meshSelect.removeEnabled = False self.meshSelect.noneEnabled = True self.meshSelect.showHidden = False self.meshSelect.setMRMLScene(slicer.mrmlScene) self.meshSelect.connect("currentNodeChanged(vtkMRMLNode*)", self.onMeshSelect) parametersFormLayout.addRow("Model: ", self.meshSelect) self.meshSelect.setToolTip("Select model node for semilandmarking") self.LMSelect = slicer.qMRMLNodeComboBox() self.LMSelect.nodeTypes = (('vtkMRMLMarkupsFiducialNode'), "") self.LMSelect.selectNodeUponCreation = False self.LMSelect.addEnabled = False self.LMSelect.removeEnabled = False self.LMSelect.noneEnabled = True self.LMSelect.showHidden = False self.LMSelect.showChildNodeTypes = False self.LMSelect.setMRMLScene(slicer.mrmlScene) self.LMSelect.connect("currentNodeChanged(vtkMRMLNode*)", self.onLMSelect) parametersFormLayout.addRow("Landmark set: ", self.LMSelect) self.LMSelect.setToolTip( "Select the landmark set that corresponds to the model") # # input landmark numbers for grid # gridPointsLayout = qt.QGridLayout() self.landmarkGridPoint1 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint1.minimum = 0 self.landmarkGridPoint1.singleStep = 1 self.landmarkGridPoint1.setDecimals(0) self.landmarkGridPoint1.setToolTip( "Input the landmark numbers to create grid") self.landmarkGridPoint2 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint2.minimum = 0 self.landmarkGridPoint2.singleStep = 1 self.landmarkGridPoint2.setDecimals(0) self.landmarkGridPoint2.setToolTip( "Input the landmark numbers to create grid") self.landmarkGridPoint3 = ctk.ctkDoubleSpinBox() self.landmarkGridPoint3.minimum = 0 self.landmarkGridPoint3.singleStep = 1 self.landmarkGridPoint3.setDecimals(0) self.landmarkGridPoint3.setToolTip( "Input the landmark numbers to create grid") gridPointsLayout.addWidget(self.landmarkGridPoint1, 1, 2) gridPointsLayout.addWidget(self.landmarkGridPoint2, 1, 3) gridPointsLayout.addWidget(self.landmarkGridPoint3, 1, 4) parametersFormLayout.addRow("Semi-landmark grid points:", gridPointsLayout) # # set number of sample points in each triangle # self.gridSamplingRate = ctk.ctkDoubleSpinBox() self.gridSamplingRate.minimum = 3 self.gridSamplingRate.maximum = 50 self.gridSamplingRate.singleStep = 1 self.gridSamplingRate.setDecimals(0) self.gridSamplingRate.value = 10 self.gridSamplingRate.setToolTip( "Input the landmark numbers to create grid") parametersFormLayout.addRow( "Select number of rows/columns in resampled grid:", self.gridSamplingRate) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Advanced menu # advancedCollapsibleButton = ctk.ctkCollapsibleButton() advancedCollapsibleButton.text = "Advanced" advancedCollapsibleButton.collapsed = True parametersFormLayout.addRow(advancedCollapsibleButton) # Layout within the dummy collapsible button advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton) # # Maximum projection slider # self.projectionDistanceSlider = ctk.ctkSliderWidget() self.projectionDistanceSlider.singleStep = 1 self.projectionDistanceSlider.minimum = 0 self.projectionDistanceSlider.maximum = 100 self.projectionDistanceSlider.value = 25 self.projectionDistanceSlider.setToolTip( "Set maximum projection distance as a percentage of image size") advancedFormLayout.addRow("Set maximum projection distance: ", self.projectionDistanceSlider) # # Normal smoothing slider # self.smoothingSlider = ctk.ctkSliderWidget() self.smoothingSlider.singleStep = 1 self.smoothingSlider.minimum = 0 self.smoothingSlider.maximum = 100 self.smoothingSlider.value = 0 self.smoothingSlider.setToolTip( "Set smothing of normal vectors for projection") advancedFormLayout.addRow("Set smoothing of projection vectors: ", self.smoothingSlider) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Generate semilandmarks." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # # Fiducials view # self.fiducialView = slicer.qMRMLSubjectHierarchyTreeView() self.fiducialView.setMRMLScene(slicer.mrmlScene) self.fiducialView.setMultiSelection(True) self.fiducialView.setAlternatingRowColors(True) self.fiducialView.setDragDropMode(True) self.fiducialView.setColumnHidden( self.fiducialView.model().transformColumn, True) self.fiducialView.sortFilterProxyModel().setNodeTypes( ["vtkMRMLMarkupsFiducialNode"]) parametersFormLayout.addRow(self.fiducialView) # # Apply Button # self.mergeButton = qt.QPushButton("Merge highlighted nodes") self.mergeButton.toolTip = "Generate a single merged landmark file from the selected nodes" self.mergeButton.enabled = False parametersFormLayout.addRow(self.mergeButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.mergeButton.connect('clicked(bool)', self.onMergeButton) self.fiducialView.connect('currentItemChanged(vtkIdType)', self.updateMergeButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): self.detailsPopup = None self.setDetailsPopup(self.getSavedDICOMDetailsWidgetType()()) # XXX Slicer 4.5 - Remove these. Here only for backward compatibility. self.dicomBrowser = self.detailsPopup.dicomBrowser self.tables = self.detailsPopup.tables layoutManager = slicer.app.layoutManager() if layoutManager is not None: layoutManager.layoutChanged.connect(self.onLayoutChanged) # connect to the 'Show DICOM Browser' button self.showBrowserButton = qt.QPushButton('Show DICOM database browser') self.showBrowserButton.setCheckable(True) self.layout.addWidget(self.showBrowserButton) self.showBrowserButton.setStyleSheet("font:Bold;" "font-size:12px") self.showBrowserButton.connect('clicked()', self.toggleDetailsPopup) self.loadedDataLabel = qt.QLabel("Loaded data") self.loadedDataLabel.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed) self.layout.addWidget(self.loadedDataLabel) font = qt.QFont() font.setBold(True) font.setPointSize(12) self.loadedDataLabel.setFont(font) self.layout.addWidget(self.loadedDataLabel) self.subjectHierarchyTree = slicer.qMRMLSubjectHierarchyTreeView() self.layout.addWidget(self.subjectHierarchyTree) self.subjectHierarchyTree.setMRMLScene(slicer.mrmlScene) self.subjectHierarchyTree.currentItemChanged.connect( self.onCurrentItemChanged) self.subjectHierarchyTree.currentItemModified.connect( self.onCurrentItemModified) self.subjectHierarchyCurrentVisibility = False self.subjectHierarchyTree.setColumnHidden( self.subjectHierarchyTree.model().idColumn, True) self.browserSettingsWidget = ctk.ctkCollapsibleGroupBox() self.browserSettingsWidget.title = "Browser settings" self.layout.addWidget(self.browserSettingsWidget) self.browserSettingsWidget.collapsed = True self.browserSettingsWidget.setLayout(qt.QFormLayout()) self.directoryButton = ctk.ctkDirectoryButton() self.browserSettingsWidget.layout().addRow("Local database:", self.directoryButton) self.directoryButton.directoryChanged.connect( self.onDatabaseDirectoryButtonChanged) self.onDatabaseDirectoryDetailsPopupChanged( self.detailsPopup.dicomBrowser.databaseDirectory) self.tableDensityComboBox = qt.QComboBox() self.browserSettingsWidget.layout().addRow("Table density:", self.tableDensityComboBox) self.tableDensityComboBox.currentIndexChanged.connect( self.onTableDensityChanged) self.updateTableDensityComboBox() self.horizontalCheckBox = qt.QCheckBox() self.horizontalCheckBox.checked = settingsValue( 'DICOM/horizontalTables', 0, converter=int) self.horizontalCheckBox.stateChanged.connect( self.onHorizontalStateChanged) self.browserSettingsWidget.layout().addRow("Horizontal:", self.horizontalCheckBox) self.browserPersistentCheckBox = qt.QCheckBox() self.browserPersistentCheckBox.checked = settingsValue( 'DICOM/BrowserPersistent', False, converter=toBool) self.browserPersistentCheckBox.stateChanged.connect( self.onBrowserPersistentStateChanged) self.browserSettingsWidget.layout().addRow( "Browser persistent:", self.browserPersistentCheckBox) self.additionalSettingsLayout = qt.QHBoxLayout() # # servers # # testing server - not exposed (used for development) self.localFrame = ctk.ctkCollapsibleButton(self.parent) self.localFrame.setLayout(qt.QVBoxLayout()) self.localFrame.setText("Servers") self.layout.addWidget(self.localFrame) self.localFrame.collapsed = True self.toggleServer = qt.QPushButton("Start Testing Server") self.localFrame.layout().addWidget(self.toggleServer) self.toggleServer.connect('clicked()', self.onToggleServer) self.verboseServer = qt.QCheckBox("Verbose") self.localFrame.layout().addWidget(self.verboseServer) # advanced options - not exposed to end users # developers can uncomment these lines to access testing server self.toggleServer.hide() self.verboseServer.hide() # Listener settings = qt.QSettings() self.toggleListener = qt.QPushButton() self.toggleListener.checkable = True if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect( 'stateChanged(QProcess::ProcessState)', self.onListenerStateChanged) else: self.toggleListener.text = "Start Listener" self.localFrame.layout().addWidget(self.toggleListener) self.toggleListener.connect('clicked()', self.onToggleListener) self.runListenerAtStart = qt.QCheckBox( "Start Listener when Slicer Starts") self.localFrame.layout().addWidget(self.runListenerAtStart) self.runListenerAtStart.checked = settingsValue( 'DICOM/RunListenerAtStart', False, converter=toBool) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # connect to the main window's dicom button mw = slicer.util.mainWindow() if mw: try: action = slicer.util.findChildren(mw, name='LoadDICOMAction')[0] action.connect('triggered()', self.onOpenDetailsPopup) except IndexError: logging.error( 'Could not connect to the main window DICOM button') if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) # the recent activity frame self.activityFrame = ctk.ctkCollapsibleButton(self.parent) self.activityFrame.collapsed = True self.activityFrame.setLayout(qt.QVBoxLayout()) self.activityFrame.setText("Recent DICOM Activity") self.layout.addWidget(self.activityFrame) self.recentActivity = DICOMLib.DICOMRecentActivityWidget( self.activityFrame, detailsPopup=self.detailsPopup) self.activityFrame.layout().addWidget(self.recentActivity) self.requestUpdateRecentActivity()
def __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()
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)