def setupOutputSection(self): self.outputCollapsibleButton = ctk.ctkCollapsibleButton() self.outputCollapsibleButton.objectName = "Output" self.outputCollapsibleButton.text = "Output" self.layout.addWidget(self.outputCollapsibleButton) self.outputCollapsibleButton.connect( 'toggled(bool)', lambda toggle: self.onWorkflowStepChanged( self.outputCollapsibleButton, toggle)) outputFormLayout = qt.QFormLayout(self.outputCollapsibleButton) self.computeStatusTextEdit = qt.QPlainTextEdit() self.computeStatusTextEdit.setTextInteractionFlags( qt.Qt.TextSelectableByMouse) self.computeStatusTextEdit.maximumHeight = 75 outputFormLayout.addRow(self.computeStatusTextEdit) self.measurementTree = slicer.qMRMLSubjectHierarchyTreeView() self.measurementTree.setMRMLScene(slicer.mrmlScene) qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.MinimumExpanding) qSize.setVerticalPolicy(qt.QSizePolicy.MinimumExpanding) qSize.setVerticalStretch(1) self.measurementTree.setSizePolicy(qSize) self.measurementTree.setColumnHidden( self.measurementTree.model().idColumn, True) self.measurementTree.setColumnHidden( self.measurementTree.model().transformColumn, True) outputFormLayout.addRow(self.measurementTree)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) self.inputDirSelector = ctk.ctkPathLineEdit() self.inputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.inputDirSelector.settingKey = 'Philips4dUsDicomPatcherInputDir' parametersFormLayout.addRow("Input DICOM directory:", self.inputDirSelector) self.outputDirSelector = ctk.ctkPathLineEdit() self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.outputDirSelector.settingKey = 'Philips4dUsDicomPatcherOutputDir' parametersFormLayout.addRow("Output DICOM directory:", self.outputDirSelector) self.enableDicomOutputCheckBox = qt.QCheckBox() self.enableDicomOutputCheckBox.checked = True self.enableDicomOutputCheckBox.setToolTip( "If checked, patched 4D US DICOM files will be saved as DICOM files" ) parametersFormLayout.addRow("Export to DICOM files", self.enableDicomOutputCheckBox) self.anonymizeDicomCheckBox = qt.QCheckBox() self.anonymizeDicomCheckBox.checked = False self.anonymizeDicomCheckBox.setToolTip( "If checked, then patient identifiable information will be removed from the patched DICOM files" ) parametersFormLayout.addRow(" Anonymize DICOM files", self.anonymizeDicomCheckBox) self.enableNrrdOutputCheckBox = qt.QCheckBox() self.enableNrrdOutputCheckBox.checked = False self.enableNrrdOutputCheckBox.setToolTip( "If checked, 4D US DICOM files will be saved as NRRD files") parametersFormLayout.addRow("Export to NRRD files", self.enableNrrdOutputCheckBox) # # Patch Button # self.patchButton = qt.QPushButton("Patch") self.patchButton.toolTip = "Fix and optionally anonymize DICOM files" parametersFormLayout.addRow(self.patchButton) # connections self.patchButton.connect('clicked(bool)', self.onPatchButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) parametersFormLayout.addRow(self.statusLabel) # Add vertical spacer self.layout.addStretch(1) self.logic = Philips4dUsDicomPatcherLogic() self.logic.logCallback = self.addLog
def setup(self): # Instantiate and connect widgets # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "PlusRemote Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # reload and test button # (use this during development, but remove it when delivering # your module to users) self.reloadAndTestButton = qt.QPushButton("Reload and Test") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." #reloadFormLayout.addWidget(self.reloadAndTestButton) #self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # Module requires openigtlinkremote try: slicer.modules.openigtlinkremote except: self.errorLabel = qt.QLabel( "Could not find OpenIGTLink Remote module") self.layout.addWidget(self.errorLabel) return # IGTLink Connector connectorCollapsibleButton = ctk.ctkCollapsibleButton() connectorCollapsibleButton.text = "OpenIGTLink Connector" self.layout.addWidget(connectorCollapsibleButton) connectorLayout = qt.QFormLayout(connectorCollapsibleButton) self.linkInputSelector = slicer.qMRMLNodeComboBox() self.linkInputSelector.nodeTypes = (("vtkMRMLIGTLConnectorNode"), "") self.linkInputSelector.selectNodeUponCreation = True self.linkInputSelector.addEnabled = False self.linkInputSelector.removeEnabled = True self.linkInputSelector.noneEnabled = False self.linkInputSelector.showHidden = False self.linkInputSelector.showChildNodeTypes = False self.linkInputSelector.setMRMLScene(slicer.mrmlScene) self.linkInputSelector.setToolTip("Pick connector node") connectorLayout.addRow("OpenIGTLinkConnector: ", self.linkInputSelector) # Recording recordingCollapsibleButton = ctk.ctkCollapsibleButton() recordingCollapsibleButton.text = "Recording" self.layout.addWidget(recordingCollapsibleButton) recordingLayout = qt.QFormLayout(recordingCollapsibleButton) self.captureIDBox = qt.QLineEdit() recordingLayout.addRow("Capture Device ID: ", self.captureIDBox) self.fileNameBox = qt.QLineEdit() recordingLayout.addRow("Filename: ", self.fileNameBox) # Move to the same row, use grid layout recordingControlsLayout = qt.QGridLayout() self.startRecordingButton = qt.QPushButton("Start Recording") recordingControlsLayout.addWidget(self.startRecordingButton, 0, 0) self.stopRecordingButton = qt.QPushButton("Stop Recording") recordingControlsLayout.addWidget(self.stopRecordingButton, 0, 1) recordingLayout.addRow(recordingControlsLayout) # Reconstruction reconstructionCollapsibleButton = ctk.ctkCollapsibleButton() reconstructionCollapsibleButton.text = "Reconstruction" self.layout.addWidget(reconstructionCollapsibleButton) reconstructionLayout = qt.QFormLayout(reconstructionCollapsibleButton) liveReconstructionLayout = qt.QGridLayout() self.startReconstuctionButton = qt.QPushButton( "Start Live Reconstruction") liveReconstructionLayout.addWidget(self.startReconstuctionButton, 0, 0) self.stopReconstructionButton = qt.QPushButton( "Stop Live Reconstruction") liveReconstructionLayout.addWidget(self.stopReconstructionButton, 0, 1) reconstructionLayout.addRow(liveReconstructionLayout) self.reconstructVolumeButton = qt.QPushButton( "Reconstruct Recorded Volume") reconstructionLayout.addRow(self.reconstructVolumeButton) # Transform Update transformUpdateCollapsibleButton = ctk.ctkCollapsibleButton() transformUpdateCollapsibleButton.text = "Transform Update" self.layout.addWidget(transformUpdateCollapsibleButton) transformUpdateLayout = qt.QFormLayout( transformUpdateCollapsibleButton) self.transformUpdateInputSelector = slicer.qMRMLNodeComboBox() self.transformUpdateInputSelector.nodeTypes = (( "vtkMRMLLinearTransformNode"), "") self.transformUpdateInputSelector.selectNodeUponCreation = True self.transformUpdateInputSelector.addEnabled = False self.transformUpdateInputSelector.removeEnabled = True self.transformUpdateInputSelector.renameEnabled = True self.transformUpdateInputSelector.noneEnabled = False self.transformUpdateInputSelector.showHidden = False self.transformUpdateInputSelector.showChildNodeTypes = False self.transformUpdateInputSelector.setMRMLScene(slicer.mrmlScene) self.transformUpdateInputSelector.setToolTip("Pick transform node") transformUpdateLayout.addRow("Transform node: ", self.transformUpdateInputSelector) self.updateTransformButton = qt.QPushButton("Update") transformUpdateLayout.addRow(self.updateTransformButton) self.configFileNameBox = qt.QLineEdit() transformUpdateLayout.addRow("Filename: ", self.configFileNameBox) self.saveTransformButton = qt.QPushButton("Save Config") transformUpdateLayout.addRow(self.saveTransformButton) replyUpdateCollapsibleButton = ctk.ctkCollapsibleButton() replyUpdateCollapsibleButton.text = "Reply" self.layout.addWidget(replyUpdateCollapsibleButton) replyLayout = qt.QFormLayout(replyUpdateCollapsibleButton) self.replyBox = qt.QPlainTextEdit() self.replyBox.setReadOnly(True) replyLayout.addRow(self.replyBox) # connections self.startRecordingButton.connect('clicked(bool)', self.onStartRecording) self.stopRecordingButton.connect('clicked(bool)', self.onStopRecording) self.startReconstuctionButton.connect('clicked(bool)', self.onStartReconstruction) self.stopReconstructionButton.connect('clicked(bool)', self.onStopReconstruction) self.reconstructVolumeButton.connect('clicked(bool)', self.onReconstVolume) self.updateTransformButton.connect('clicked(bool)', self.onUpdateTransform) self.saveTransformButton.connect('clicked(bool)', self.onSaveTransform) 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) self.inputDirSelector = ctk.ctkPathLineEdit() self.inputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.inputDirSelector.settingKey = 'DICOMPatcherInputDir' parametersFormLayout.addRow("Input DICOM directory:", self.inputDirSelector) self.outputDirSelector = ctk.ctkPathLineEdit() self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.outputDirSelector.settingKey = 'DICOMPatcherOutputDir' parametersFormLayout.addRow("Output DICOM directory:", self.outputDirSelector) self.normalizeFileNamesCheckBox = qt.QCheckBox() self.normalizeFileNamesCheckBox.checked = True self.normalizeFileNamesCheckBox.setToolTip("Replace file and folder names with automatically generated names." " Fixes errors caused by file path containins special characters or being too long.") parametersFormLayout.addRow("Normalize file names", self.normalizeFileNamesCheckBox) self.forceSamePatientNameIdInEachDirectoryCheckBox = qt.QCheckBox() self.forceSamePatientNameIdInEachDirectoryCheckBox.checked = False self.forceSamePatientNameIdInEachDirectoryCheckBox.setToolTip("Generate patient name and ID from the first file in a directory" " and force all other files in the same directory to have the same patient name and ID." " Enable this option if a separate patient directory is created for each patched file.") parametersFormLayout.addRow("Force same patient name and ID in each directory", self.forceSamePatientNameIdInEachDirectoryCheckBox) self.generateMissingIdsCheckBox = qt.QCheckBox() self.generateMissingIdsCheckBox.checked = True self.generateMissingIdsCheckBox.setToolTip("Generate missing patient, study, series IDs. It is assumed that" " all files in a directory belong to the same series. Fixes error caused by too aggressive anonymization" " or incorrect DICOM image converters.") parametersFormLayout.addRow("Generate missing patient/study/series IDs", self.generateMissingIdsCheckBox) self.generateImagePositionFromSliceThicknessCheckBox = qt.QCheckBox() self.generateImagePositionFromSliceThicknessCheckBox.checked = True self.generateImagePositionFromSliceThicknessCheckBox.setToolTip("Generate 'image position sequence' for" " multi-frame files that only have 'SliceThickness' field. Fixes error in Dolphin 3D CBCT scanners.") parametersFormLayout.addRow("Generate slice position for multi-frame volumes", self.generateImagePositionFromSliceThicknessCheckBox) self.anonymizeDicomCheckBox = qt.QCheckBox() self.anonymizeDicomCheckBox.checked = False self.anonymizeDicomCheckBox.setToolTip("If checked, then some patient identifiable information will be removed" " from the patched DICOM files. There are many fields that can identify a patient, this function does not remove all of them.") parametersFormLayout.addRow("Partially anonymize", self.anonymizeDicomCheckBox) # # Patch Button # self.patchButton = qt.QPushButton("Patch") self.patchButton.toolTip = "Fix DICOM files in input directory and write them to output directory" parametersFormLayout.addRow(self.patchButton) # # Import Button # self.importButton = qt.QPushButton("Import") self.importButton.toolTip = "Import DICOM files in output directory into Slicer DICOM database" parametersFormLayout.addRow(self.importButton) # # Switch to DICOM module Button # self.switchToDICOMModuleButton = qt.QPushButton("Go to DICOM module") self.switchToDICOMModuleButton.toolTip = "Open DICOM module where imported data can be loaded into the scene" parametersFormLayout.addRow(self.switchToDICOMModuleButton) # connections self.patchButton.connect('clicked(bool)', self.onPatchButton) self.importButton.connect('clicked(bool)', self.onImportButton) self.switchToDICOMModuleButton.connect('clicked(bool)', self.onSwitchToDICOMModuleButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) parametersFormLayout.addRow(self.statusLabel) # Add vertical spacer self.layout.addStretch(1) self.logic = DICOMPatcherLogic() self.logic.logCallback = self.addLog
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) self.inputDirSelector = ctk.ctkPathLineEdit() self.inputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.inputDirSelector.settingKey = 'DicomPatcherInputDir' parametersFormLayout.addRow("Input DICOM directory:", self.inputDirSelector) self.outputDirSelector = ctk.ctkPathLineEdit() self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.outputDirSelector.settingKey = 'DicomPatcherOutputDir' parametersFormLayout.addRow("Output DICOM directory:", self.outputDirSelector) self.generateMissingIdsCheckBox = qt.QCheckBox() self.generateMissingIdsCheckBox.checked = True self.generateMissingIdsCheckBox.setToolTip( "If checked, then missing patient, study, series IDs are generated. It is assumed that all files in a directory belong to the same series. Fixes error caused by too aggressive anonymization or incorrect DICOM image converters." ) parametersFormLayout.addRow("Generate missing IDs", self.generateMissingIdsCheckBox) self.generateImagePositionFromSliceThicknessCheckBox = qt.QCheckBox() self.generateImagePositionFromSliceThicknessCheckBox.checked = True self.generateImagePositionFromSliceThicknessCheckBox.setToolTip( "If checked, then image position sequence is generated for multi-frame files that only have SliceThickness field. Fixes error in Dolphin 3D CBCT scanners." ) parametersFormLayout.addRow( "Generate slice position for multi-frame volumes", self.generateImagePositionFromSliceThicknessCheckBox) self.anonymizeDicomCheckBox = qt.QCheckBox() self.anonymizeDicomCheckBox.checked = False self.anonymizeDicomCheckBox.setToolTip( "If checked, then some patient identifiable information will be removed from the patched DICOM files. There are many fields that can identify a patient, this function does not remove all of them." ) parametersFormLayout.addRow("Anonymize DICOM files", self.anonymizeDicomCheckBox) # # Patch Button # self.patchButton = qt.QPushButton("Patch") self.patchButton.toolTip = "Fix and optionally anonymize DICOM files" parametersFormLayout.addRow(self.patchButton) # connections self.patchButton.connect('clicked(bool)', self.onPatchButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) parametersFormLayout.addRow(self.statusLabel) # Add vertical spacer self.layout.addStretch(1) self.logic = DicomPatcherLogic() self.logic.logCallback = self.addLog