def makeAddAPIDialog (self): self.apiNameLineEdit.clear() self.apiKeyLineEdit.clear() saveButton = qt.QPushButton("OK") cancelButton = qt.QPushButton("Cancel") currLayout = qt.QFormLayout() currLayout.addRow("API Name:", self.apiNameLineEdit) currLayout.addRow("API Key:", self.apiKeyLineEdit) buttonLayout = qt.QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(cancelButton) buttonLayout.addWidget(saveButton) masterForm = qt.QFormLayout() masterForm.addRow(currLayout) masterForm.addRow(buttonLayout) addApiDialog = qt.QDialog(self.addAPIButton) addApiDialog.setWindowTitle("Add API") addApiDialog.setFixedWidth(300) addApiDialog.setLayout(masterForm) addApiDialog.setWindowModality(1) cancelButton.connect("clicked()", addApiDialog.hide) saveButton.connect("clicked()", self.saveApi) return addApiDialog
def colorSelectDialog(self): """color table dialog""" if not self.colorSelect: self.colorSelect = qt.QDialog(slicer.util.mainWindow()) self.colorSelect.objectName = 'EditorColorSelectDialog' self.colorSelect.setLayout( qt.QVBoxLayout() ) self.colorPromptLabel = qt.QLabel() self.colorSelect.layout().addWidget( self.colorPromptLabel ) self.colorSelectorFrame = qt.QFrame() self.colorSelectorFrame.objectName = 'ColorSelectorFrame' self.colorSelectorFrame.setLayout( qt.QHBoxLayout() ) self.colorSelect.layout().addWidget( self.colorSelectorFrame ) self.colorSelectorLabel = qt.QLabel() self.colorPromptLabel.setText( "Color Table: " ) self.colorSelectorFrame.layout().addWidget( self.colorSelectorLabel ) self.colorSelector = slicer.qMRMLColorTableComboBox() # TODO self.colorSelector.nodeTypes = ("vtkMRMLColorNode", "") self.colorSelector.hideChildNodeTypes = ("vtkMRMLDiffusionTensorDisplayPropertiesNode", "") self.colorSelector.addEnabled = False self.colorSelector.removeEnabled = False self.colorSelector.noneEnabled = False self.colorSelector.selectNodeUponCreation = True self.colorSelector.showHidden = True self.colorSelector.showChildNodeTypes = True self.colorSelector.setMRMLScene( slicer.mrmlScene ) self.colorSelector.setToolTip( "Pick the table of structures you wish to edit" ) self.colorSelect.layout().addWidget( self.colorSelector ) # pick the default editor LUT for the user defaultID = self.colorLogic.GetDefaultEditorColorNodeID() defaultNode = slicer.mrmlScene.GetNodeByID(defaultID) if defaultNode: self.colorSelector.setCurrentNode( defaultNode ) self.colorButtonFrame = qt.QFrame() self.colorButtonFrame.objectName = 'ColorButtonFrame' self.colorButtonFrame.setLayout( qt.QHBoxLayout() ) self.colorSelect.layout().addWidget( self.colorButtonFrame ) self.colorDialogApply = qt.QPushButton("Apply", self.colorButtonFrame) self.colorDialogApply.objectName = 'ColorDialogApply' self.colorDialogApply.setToolTip( "Use currently selected color node." ) self.colorButtonFrame.layout().addWidget(self.colorDialogApply) self.colorDialogCancel = qt.QPushButton("Cancel", self.colorButtonFrame) self.colorDialogCancel.objectName = 'ColorDialogCancel' self.colorDialogCancel.setToolTip( "Cancel current operation." ) self.colorButtonFrame.layout().addWidget(self.colorDialogCancel) self.colorDialogApply.connect("clicked()", self.onColorDialogApply) self.colorDialogCancel.connect("clicked()", self.colorSelect.hide) self.colorPromptLabel.setText( "Create a merge label map for selected master volume %s.\nNew volume will be %s.\nSelect the color table node will be used for segmentation labels." %(self.master.GetName(), self.master.GetName()+"-label")) self.colorSelect.show()
def __init__(self, parent): self.dialog = qt.QDialog(parent) self.ui = _ui_LoadModulesDialog(self.dialog) self.ui.buttonBox.connect("accepted()", self.dialog, "accept()") self.ui.buttonBox.connect("rejected()", self.dialog, "reject()") self.ui.moduleList.connect("itemChanged(QListWidgetItem*)", self.validate)
def open(self): # main dialog self.dialog = qt.QDialog(slicer.util.mainWindow()) self.dialog.setWindowTitle('Send DICOM Study') self.dialog.setWindowModality(1) layout = qt.QVBoxLayout() self.dialog.setLayout(layout) self.studyLabel = qt.QLabel('Send %d items to destination' % len(self.files)) layout.addWidget(self.studyLabel) # Send Parameters self.dicomFrame = qt.QFrame(self.dialog) self.dicomFormLayout = qt.QFormLayout() self.dicomFrame.setLayout(self.dicomFormLayout) self.dicomEntries = {} self.dicomParameters = { "Destination Address": self.sendAddress, "Destination Port": self.sendPort } for label in self.dicomParameters.keys(): self.dicomEntries[label] = qt.QLineEdit() self.dicomEntries[label].text = self.dicomParameters[label] self.dicomFormLayout.addRow(label+": ", self.dicomEntries[label]) layout.addWidget(self.dicomFrame) # button box bbox = qt.QDialogButtonBox(self.dialog) bbox.addButton(bbox.Ok) bbox.addButton(bbox.Cancel) bbox.connect('accepted()', self.onOk) bbox.connect('rejected()', self.onCancel) layout.addWidget(bbox) self.dialog.open()
def makeDeleteApiDialoge(self): okButton = qt.QPushButton("OK") cancelButton = qt.QPushButton("Cancel") messageLabel = qt.QTextEdit() messageLabel.setReadOnly(True) messageLabel.insertPlainText("Are you sure you want to delete the selected API?") messageLabel.setFontWeight(100) messageLabel.setFixedHeight(40) messageLabel.setFrameShape(0) currLayout = qt.QVBoxLayout() currLayout.addWidget(messageLabel) #currLayout.addStretch(1) buttonLayout = qt.QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(cancelButton) buttonLayout.addWidget(okButton) masterForm = qt.QFormLayout() masterForm.addRow(currLayout) masterForm.addRow(buttonLayout) deleteApiDialog = qt.QDialog(self.apiTable) deleteApiDialog.setWindowTitle("Delete API") deleteApiDialog.setLayout(masterForm) deleteApiDialog.setWindowModality(1) cancelButton.connect("clicked()", deleteApiDialog.hide) okButton.connect("clicked()", self.deleteApi) return deleteApiDialog
def __init__(self, parent=None, studyDescription="", petDescriptions=[], ctDescriptions=[], petSelection=0, ctSelection=0): self.studyDescription = studyDescription self.petDescriptions = petDescriptions self.ctDescriptions = ctDescriptions self.petSelection = petSelection self.ctSelection = ctSelection if not parent: self.parent = qt.QDialog() self.parent.setModal(True) self.parent.setLayout(qt.QGridLayout()) self.layout = self.parent.layout() self.setup() self.parent.show() else: self.parent = parent self.layout = parent.layout()
def __init__(self, componenttype, parent): self.dialog = qt.QDialog(parent) self.ui = _ui_CreateComponentDialog(self.dialog) self.ui.buttonBox.connect("accepted()", self.accept) self.ui.buttonBox.connect("rejected()", self.dialog, "reject()") self._typelc = componenttype.lower() self._typetc = componenttype.title()
def delayDisplay(self, message, msec=1000): print(message) self.info = qt.QDialog() self.infoLayout = qt.QVBoxLayout() self.info.setLayout(self.infoLayout) self.label = qt.QLabel(message, self.info) self.infoLayout.addWidget(self.label) qt.QTimer.singleShot(msec, self.info.close) self.info.exec_()
def plotDistribution(self): ''' ''' self.__d = qt.QDialog() self.__graphWidget = PythonQt.qSlicerEMSegmentModuleWidgets.qSlicerEMSegmentGraphWidget( self.__d) self.__graphWidget.setMRMLManager(self.mrmlManager()) self.__d.setModal(True) self.__d.show()
def plotDistribution( self ): ''' ''' self.__d = qt.QDialog() self.__dLayout = qt.QHBoxLayout( self.__d ) self.__graphWidget = slicer.modulewidget.qSlicerEMSegmentGraphWidget() self.__graphWidget.setMRMLManager( self.mrmlManager() ) self.__dLayout.addWidget( self.__graphWidget ) self.__d.setModal( True ) self.__d.show()
def logicDelayDisplay(self,message,msec=1000): """This utility method displays a small dialog and waits. """ print(message) self.info = qt.QDialog() self.infoLayout = qt.QVBoxLayout() self.info.setLayout(self.infoLayout) self.label = qt.QLabel(message,self.info) self.infoLayout.addWidget(self.label) qt.QTimer.singleShot(msec, self.info.close) self.info.exec_()
def delayDisplay(self, message, msec=1000): """This utility method displays a small dialog and waits. This does two things: 1) it lets the event loop catch up to the state of the test so that rendering and widget updates have all taken place before the test continues and 2) it shows the user/developer/tester the state of the test so that we'll know when it breaks. """ print(message) self.info = qt.QDialog() self.infoLayout = qt.QVBoxLayout() self.info.setLayout(self.infoLayout) self.label = qt.QLabel(message, self.info) self.infoLayout.addWidget(self.label) qt.QTimer.singleShot(msec, self.info.close) self.info.exec_()
def connect(self): self.updatePydevdPath() import pydevd # Return if already connected if pydevd.connected: qt.QMessageBox.warning( slicer.util.mainWindow(), "Connect to PyDev remote debug server", 'You are already connected to the remote debugger. If the connection is broken (e.g., because the server terminated the connection) then you need to restart Slicer to be able to connect again.' ) return # Show a dialog that explains that Slicer will hang self.info = qt.QDialog() self.info.setModal(False) self.infoLayout = qt.QVBoxLayout() self.info.setLayout(self.infoLayout) self.label = qt.QLabel( "Connecting to remote debug server at port {0}...\nSlicer is paused until {1} accepts the connection." .format(self.portNumber, self.getDebugger()), self.info) self.infoLayout.addWidget(self.label) self.info.show() self.info.repaint() qt.QTimer.singleShot(2000, self.onConnectionComplete) # Connect to the debugger try: pydevd.settrace('localhost', port=self.portNumber, stdoutToServer=True, stderrToServer=True, suspend=False) except Exception, e: self.info.hide() import traceback traceback.print_exc() qt.QMessageBox.warning( slicer.util.mainWindow(), "Connect to PyDev remote debug server", 'An error occurred while trying to connect to PyDev remote debugger. Make sure he pydev server is started.\n\n' + str(e)) if self.connectionCompleteCallback: self.connectionCompleteCallback(False) return
def __init__(self): settings = qt.QSettings() directory = settings.value('DatabaseDirectory') self.db = qt.QSqlDatabase.addDatabase("QSQLITE") self.db.setDatabaseName('%s/ctkDICOM.sql' % directory) self.db.open() self.dialog = qt.QDialog() self.dialog.setWindowTitle('Study Browser') self.dialog.setLayout(qt.QVBoxLayout()) self.studyTable = DICOMStudyTable(self.dialog,self.db) self.dialog.layout().addWidget(self.studyTable.view) self.seriesTable = DICOMSeriesTable(self.dialog,self.db) self.dialog.layout().addWidget(self.seriesTable.view) self.studyTable.view.connect('clicked(QModelIndex)',self.onStudyClicked) self.dialog.show()
def delayDisplay(message,autoCloseMsec=1000): """Display an information message in a popup window for a short time. If autoCloseMsec>0 then the window is closed after waiting for autoCloseMsec milliseconds If autoCloseMsec=0 then the window is not closed until the user clicks on it. """ from __main__ import qt, slicer import logging logging.info(message) messagePopup = qt.QDialog() layout = qt.QVBoxLayout() messagePopup.setLayout(layout) label = qt.QLabel(message,messagePopup) layout.addWidget(label) if autoCloseMsec>0: qt.QTimer.singleShot(autoCloseMsec, messagePopup.close) else: okButton = qt.QPushButton("OK") layout.addWidget(okButton) okButton.connect('clicked()', messagePopup.close) messagePopup.exec_()
def createBusyProgressBarDialog(text): dialog = qt.QDialog() dialog.setModal(True) vbl = qt.QVBoxLayout(dialog) lbl = qt.QLabel(text, dialog) lbl.setAlignment(qt.Qt.AlignCenter) pb = qt.QProgressBar(dialog) pb.setMinimum(0) pb.setMaximum(0) pb.setTextVisible(False) pb.setMinimumWidth(lbl.sizeHint.width()) vbl.addWidget(lbl) vbl.addWidget(pb) return dialog
def onTaskSelected( self ): ''' ''' index = self.__taskComboBox.currentIndex taskName = self.__taskComboBox.currentText # re-enable the simple and advanced buttons self.__buttonBox.enabled = True if taskName == self.__newTaskString: # create new task was selected # disable the simple and advanced buttons self.__buttonBox.enabled = False # create new dialog self.__d = qt.QDialog() dLayout = qt.QFormLayout( self.__d ) self.__nameEdit = qt.QLineEdit() dLayout.addRow( 'New Task Name:', self.__nameEdit ) self.__preprocessingComboBox = qt.QComboBox() list = self.__preprocessingTasksList.keys() list.sort( lambda x, y: cmp( x.lower(), y.lower() ) ) self.__preprocessingComboBox.addItems( list ) # also, add None self.__preprocessingComboBox.addItem( 'None' ) dLayout.addRow( 'Pre-processing:', self.__preprocessingComboBox ) buttonBox = qt.QDialogButtonBox() #cancelButton = buttonBox.addButton(buttonBox.Discard) #cancelButton.text = 'Cancel' okButton = buttonBox.addButton( buttonBox.Apply ) okButton.setIcon( qt.QIcon() ) okButton.text = 'Apply' okButton.connect( 'clicked()', self.createNewTask ) dLayout.addWidget( buttonBox ) self.__d.setModal( True ) self.__d.show()
def runGenerateMask(self, basalVolumeNode, ictalVolumeNode, threshold, zmax): ''' This method executes the method generateMask() in a new thread. Also shows a message while generateMask() is running :param basalVolumeNode: Parameter used by generateMask() :param ictalVolumeNode: Parameter used by generateMask() :param threshold: Parameter used by generateMask() :param zmax: Parameter used by generateMask() ''' self.userMessage = "Generating mask. Please wait..." self.info = qt.QDialog() self.infoLayout = qt.QVBoxLayout() self.info.setLayout(self.infoLayout) self.label = qt.QLabel(self.userMessage, self.info) self.infoLayout.addWidget(self.label) l = threading.Thread(target=self.generateMask, args=(basalVolumeNode, ictalVolumeNode, threshold, zmax,)) l.start() self.info.show() while (self.IsBasalIctalMaskComputed == False): slicer.app.processEvents() self.info.hide()
def dialogBoxFunction(self): self.deleteAllMsgBox = qt.QDialog(slicer.util.mainWindow()) #self.deleteAllMsgBox.setWindowTitle("Delete All Fiducials?") self.deleteAllMsgBox.setFixedSize(200, 100) self.deleteAllMsgBox.show() self.deleteAllMsgBox.setLayout(qt.QVBoxLayout()) messageLabel = qt.QLabel("Delete All Fiducials?") font = qt.QFont() font.setPointSize(10) messageLabel.setFont(font) self.deleteAllMsgBox.layout().addWidget(messageLabel, 0, 4) yesNoBox = qt.QFrame() yesNoBox.setLayout(qt.QHBoxLayout()) self.deleteAllMsgBox.layout().addWidget(yesNoBox, 0, 4) # # OK button # okButton = qt.QPushButton() okButton.setText("YES") okButton.enabled = True okIcon = qt.QIcon(":/Icons/AnnotationOkDone.png") okButton.setIcon(okIcon) yesNoBox.layout().addWidget(okButton) # # NO button # noButton = qt.QPushButton() noButton.setText("NO") noButton.enabled = True noIcon = qt.QIcon(":/Icons/AnnotationCancel.png") noButton.setIcon(noIcon) yesNoBox.layout().addWidget(noButton) # Connections okButton.connect("clicked()", self.onDeleteAllButton) noButton.connect("clicked()", self.deleteAllMsgBox.hide)
def makeAddHostModal(hostEditor): """ As stated. """ #-------------------- # Clear shared object lines #-------------------- hostEditor.nameLine.clear() hostEditor.urlLine.clear() #-------------------- # Buttons #-------------------- saveButton = qt.QPushButton("OK") cancelButton = qt.QPushButton("Cancel") #-------------------- # Create for line editors #-------------------- currLayout = qt.QFormLayout() currLayout.addRow("Name:", hostEditor.nameLine) currLayout.addRow("URL:", hostEditor.urlLine) currLayout.addRow(hostEditor.setDefault) #-------------------- # Create layout for buttons #-------------------- buttonLayout = qt.QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(cancelButton) buttonLayout.addWidget(saveButton) #-------------------- # Combine both layouts #-------------------- masterForm = qt.QFormLayout() masterForm.addRow(currLayout) masterForm.addRow(buttonLayout) #-------------------- # Make window #-------------------- addHostModal = qt.QDialog(hostEditor.addButton) addHostModal.setWindowTitle("Add Host") addHostModal.setFixedWidth(300) addHostModal.setLayout(masterForm) addHostModal.setWindowModality(2) #-------------------- # Clear previous host #-------------------- hostEditor.prevName = None #-------------------- # Button Connectors #-------------------- cancelButton.connect("clicked()", addHostModal.close) saveButton.connect("clicked()", hostEditor.writeHost) return addHostModal
def __init__(self, parent): self.dialog = qt.QDialog(parent) self.ui = _ui_EditExtensionMetadataDialog(self.dialog) self.ui.buttonBox.connect("accepted()", self.accept) self.ui.buttonBox.connect("rejected()", self.dialog, "reject()")
def open(self): # main dialog self.dialog = qt.QDialog(slicer.util.mainWindow()) self.dialog.setWindowTitle('Export to DICOM Study') self.dialog.setWindowModality(1) layout = qt.QVBoxLayout() self.dialog.setLayout(layout) self.studyLabel = qt.QLabel('Attach Data to Study: %s' % self.studyUID) layout.addWidget(self.studyLabel) # scene or volume option self.selectFrame = qt.QFrame(self.dialog) layout.addWidget(self.selectFrame) self.selectLayout = qt.QGridLayout() self.selectFrame.setLayout(self.selectLayout) self.exportScene = qt.QRadioButton("Export Entire Scene", self.selectFrame) self.exportScene.setToolTip( "Create a Slicer Data Bundle in a DICOM Private Creator\n(Only compatible with Slicer)" ) self.exportVolume = qt.QRadioButton("Export Selected Volume", self.selectFrame) self.exportVolume.setToolTip( "Create a compatible DICOM series of slice images") self.exportVolume.checked = True self.selectLayout.addWidget(self.exportScene, 0, 0) self.selectLayout.addWidget(self.exportVolume, 1, 0) self.exportScene.connect('toggled(bool)', self.onExportRadio) self.exportVolume.connect('toggled(bool)', self.onExportRadio) # select volume self.volumeSelector = slicer.qMRMLNodeComboBox(self.dialog) self.volumeSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "") self.volumeSelector.selectNodeUponCreation = False self.volumeSelector.addEnabled = False self.volumeSelector.noneEnabled = False self.volumeSelector.removeEnabled = False self.volumeSelector.showHidden = False self.volumeSelector.showChildNodeTypes = False self.volumeSelector.setMRMLScene(slicer.mrmlScene) self.volumeSelector.setToolTip("Pick the label map to edit") self.selectLayout.addWidget(self.volumeSelector, 1, 1) # DICOM Parameters self.dicomFrame = qt.QFrame(self.dialog) self.dicomFormLayout = qt.QFormLayout() self.dicomFrame.setLayout(self.dicomFormLayout) self.dicomEntries = {} exporter = DICOMLib.DICOMExporter(self.studyUID) self.dicomParameters = exporter.parametersFromStudy() self.dicomParameters['Series Description'] = '3D Slicer Export' for label in self.dicomParameters.keys(): self.dicomEntries[label] = qt.QLineEdit() self.dicomEntries[label].text = self.dicomParameters[label] self.dicomFormLayout.addRow(label + ": ", self.dicomEntries[label]) layout.addWidget(self.dicomFrame) # button box bbox = qt.QDialogButtonBox(self.dialog) bbox.addButton(bbox.Ok) bbox.addButton(bbox.Cancel) bbox.connect('accepted()', self.onOk) bbox.connect('rejected()', self.onCancel) layout.addWidget(bbox) self.dialog.open()
def create(self, widgetType='window', showHeader=False, showPreview=False): """ main window is a frame with widgets from the app widget repacked into it along with slicer-specific extra widgets """ # find internals of widget for reference and repacking self.toolBar = slicer.util.findChildren(self.dicomApp, 'ToolBar')[0] self.databaseNameLabel = slicer.util.findChildren( self.dicomApp, 'DatabaseNameLabel')[0] self.databaseDirectoryButton = slicer.util.findChildren( self.dicomApp, 'DirectoryButton')[0] self.tree = slicer.util.findChildren(self.dicomApp, 'TreeView')[0] self.userFrame = slicer.util.findChildren(self.dicomApp, 'UserFrame')[0] self.thumbs = slicer.util.findChildren(self.dicomApp, 'ThumbnailsWidget')[0] self.widthSlider = slicer.util.findChildren(self.dicomApp, 'ThumbnailWidthSlider')[0] self.preview = slicer.util.findChildren(self.dicomApp, 'PreviewFrame')[0] self.widgetType = widgetType if widgetType == 'dialog': self.window = qt.QDialog(self.dicomApp) elif widgetType == 'window': self.window = qt.QWidget() elif widgetType == 'popup': self.window = ctk.ctkPopupWidget(self.dicomApp) self.window.orientation = 1 self.window.horizontalDirection = 0 self.window.alignment = 0x82 elif widgetType == 'dock': self.dock = qt.QDockWidget(slicer.util.mainWindow()) self.dock.setFeatures(qt.QDockWidget.DockWidgetFloatable | qt.QDockWidget.DockWidgetMovable | qt.QDockWidget.DockWidgetClosable) slicer.util.mainWindow().addDockWidget(0x15, self.dock) self.window = qt.QFrame() self.dock.setWidget(self.window) else: raise "Unknown widget type - should be dialog, window, dock or popup" self.window.setWindowTitle('DICOM Details') self.layout = qt.QGridLayout() self.window.setLayout(self.layout) # overall layout - tree on top, preview and selection below toolRow = 0 treeRow = 1 selectionRow = 2 # tool row at top, with commands and database self.toolLayout = qt.QHBoxLayout() self.layout.addLayout(self.toolLayout, toolRow, 0, 1, 2) self.toolLayout.addWidget(self.toolBar) self.toolLayout.addWidget(self.databaseNameLabel) self.toolLayout.addWidget(self.databaseDirectoryButton) # tree goes next, spread across 1 row, 2 columns self.layout.addWidget(self.tree, treeRow, 0, 1, 2) # # preview related column # self.previewLayout = qt.QVBoxLayout() self.layout.addLayout(self.previewLayout, selectionRow, 0) self.previewLayout.addWidget(self.thumbs) self.previewLayout.addWidget(self.widthSlider) if showPreview: self.previewLayout.addWidget(self.preview) else: self.preview.hide() # # action related column (interacting with slicer) # self.actionLayout = qt.QVBoxLayout() self.layout.addLayout(self.actionLayout, selectionRow, 1) self.actionLayout.addWidget(self.userFrame) tableWidth = 350 if showHeader else 700 self.loadableTable = DICOMLoadableTable(self.userFrame, width=tableWidth) self.actionLayout.addWidget(self.loadableTable.widget) # # button row for action column # self.actionButtonLayout = qt.QHBoxLayout() self.actionLayout.addLayout(self.actionButtonLayout) self.uncheckAllButton = qt.QPushButton('Uncheck All') self.actionButtonLayout.addWidget(self.uncheckAllButton) self.uncheckAllButton.connect('clicked()', self.uncheckAllLoadables) self.loadButton = qt.QPushButton('Load Selection to Slicer') self.loadButton.enabled = False self.actionButtonLayout.addWidget(self.loadButton) self.loadButton.connect('clicked()', self.loadCheckedLoadables) self.closeButton = qt.QPushButton('Close') self.actionButtonLayout.addWidget(self.closeButton) self.closeButton.connect('clicked()', self.close) if self.setBrowserPersistence: self.browserPersistentButton = qt.QCheckBox( 'Make DICOM Browser Persistent') self.browserPersistentButton.toolTip = 'When enabled, DICOM Broswer remains open and usable after leaving DICOM module' self.actionLayout.addWidget(self.browserPersistentButton) self.browserPersistentButton.connect('stateChanged(int)', self.setBrowserPersistence) # # header related column (more details about the selected file) # if showHeader: self.headerLayout = qt.QVBoxLayout() self.layout.addLayout(self.headerLayout, selectionRow, 2) self.header = DICOMHeaderWidget(self.window) self.headerLayout.addWidget(self.header.widget)
def genericHostEditor(_Settings_Hosts, saveCallback, linePrefix=''): """ @param _Settings_Hosts: The widget that is the parent of the modal. @type _Settings_Hosts: Settings_Hosts @param saveCallback: The save button callback. @type saveCallback: function @param linePrefix: The to prefix to append to the line edit labels. @type linePrefix: str """ if len(linePrefix) > 0: linePrefix += ' ' #-------------------- # Create for line editors #-------------------- currLayout = qt.QFormLayout() currLayout.addRow(linePrefix + "Name:", _Settings_Hosts.lineEdits['hostname']) currLayout.addRow('', _Settings_Hosts.errorLines['hostname']) currLayout.addRow(linePrefix + 'URL:', _Settings_Hosts.lineEdits['url']) currLayout.addRow('', _Settings_Hosts.errorLines['url']) currLayout.addRow(_Settings_Hosts.checkBoxes['setdefault']) spaceLabel = qt.QLabel("") unmLabel = qt.QLabel("Stored Username:"******"OK") cancelButton = qt.QPushButton("Cancel") _Settings_Hosts.saveButtons = {} _Settings_Hosts.saveButtons[linePrefix] = saveButton _Settings_Hosts.cancelButtons = {} _Settings_Hosts.cancelButtons[linePrefix] = cancelButton #-------------------- # Create layout for buttons #-------------------- buttonLayout = qt.QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(cancelButton) buttonLayout.addWidget(saveButton) #-------------------- # Combine both layouts #-------------------- masterForm = qt.QFormLayout() masterForm.addRow(currLayout) masterForm.addRow(buttonLayout) #-------------------- # Make window #-------------------- modal = qt.QDialog(_Settings_Hosts) modal.setWindowTitle("Add Host") modal.setFixedWidth(300) modal.setLayout(masterForm) modal.setWindowModality(1) #-------------------- # Clear previous host #-------------------- _Settings_Hosts.prevName = None #-------------------- # Button Connectors #-------------------- cancelButton.connect("clicked()", modal.close) saveButton.connect("clicked()", saveCallback) return modal
def connect(self): # Return if already connected if self.isConnected(): qt.QMessageBox.warning( slicer.util.mainWindow(), "Connect to PyDev remote debug server", 'You are already connected to the remote debugger. If the connection is broken (e.g., because the server terminated the connection) then you need to restart Slicer to be able to connect again.' ) return False # Show a dialog that explains that Slicer will hang self.info = qt.QDialog() self.info.setModal(False) self.infoLayout = qt.QVBoxLayout() self.info.setLayout(self.infoLayout) if self.getDebugger() == "VisualStudio" or self.getDebugger( ) == "VisualStudio 2013/2015": connectionHelp = ( "Waiting for VisualStudio 2013/2015 debugger attachment...\n\n" + "To attach debugger:\n" + "- In VisualStudio, open menu: Debug / Attach to process\n" + "- Select Transport: 'Python remote (ptvsd)\n" + "- Set Qualifier: 'tcp://{1}@localhost:{0}'\n" + "- Click Refresh\n" + "- Click Attach").format( self.getPortNumber(), self.getSecret()) elif self.getDebugger() == "VisualStudio 2017": connectionHelp = ( "Waiting for VisualStudio 2017 debugger attachment...\n\n" + "To attach debugger:\n" + "- In VisualStudio, open menu: Debug / Attach to process\n" + "- Select Connection type: 'Python remote (ptvsd)\n" + "- Set Connection target: 'tcp://{1}@localhost:{0}'\n" + "- Click Refresh\n" + "- Click Attach").format( self.getPortNumber(), self.getSecret()) elif self.getDebugger() == "VisualStudio Code": connectionHelp = ( "Waiting for VisualStudio Code debugger attachment...\n\n" + "\n" + "Make sure you have configured `Python: Attach` debugging configuration:\n" + '"port": {0}\n' + "\n" + "To attach debugger:\n" + "- In VisualStudio Code, choose debugging configuration 'Python: Attach'\n" + "- Click Start Debugging").format(self.getPortNumber()) else: connectionHelp = "Connecting to remote debug server at port {0}...\nSlicer is paused until {1} accepts the connection.".format( self.getPortNumber(), self.getDebugger()) self.label = qt.QLabel(connectionHelp) self.infoLayout.addWidget(self.label) self.info.show() self.info.repaint() slicer.app.processEvents() qt.QTimer.singleShot(2000, self.onConnectionComplete) # Connect to the debugger if self.isDebuggerVisualStudio(): self.addPtvsdToPath() import ptvsd if not self.isCorrectVisualStudioDebuggerVersion(): slicer.util.errorDisplay( "Slicer must be restarted after switching between VisualStudio debugger versions." ) return False if self.getDebugger() == "VisualStudio Code": # no secret for VisualStudio Code debugger ptvsd.enable_attach(address=('0.0.0.0', self.getPortNumber())) else: ptvsd.enable_attach(address=('0.0.0.0', self.getPortNumber()), secret=self.getSecret()) ptvsd.wait_for_attach() else: try: import pydevd pydevd.settrace('localhost', port=self.getPortNumber(), stdoutToServer=True, stderrToServer=True, suspend=False) except (Exception, SystemExit) as e: self.info.hide() import traceback traceback.print_exc() qt.QMessageBox.warning( slicer.util.mainWindow(), "Connect to PyDev remote debug server", 'An error occurred while trying to connect to PyDev remote debugger. Make sure pydev server is started.\n\n' + str(e)) if self.connectionCompleteCallback: self.connectionCompleteCallback(False) return False logging.debug("Connected to remote debug server") return True
def run(self): """ Run the actual algorithm """ print('Running test of the Neurosurgical Planning tutorial') # # first load the data # import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting Baseline volume") baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume( ) print("Getting DTI volume") dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume() # # link the viewers # sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # baseline in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(baselineVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # # adjust window level on baseline # mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('Volumes') baselineVolume.GetDisplayNode().SetWindow(2600) baselineVolume.GetDisplayNode().SetLevel(1206) # # switch to red slice only # lm = slicer.app.layoutManager() lm.setLayout(6) # # skip segmentation of tumour # # # switch to conventional layout # lm.setLayout(2) # # skip tractography label map seeding # # # tractography fiducial seeding # mainWindow.moduleSelector().selectModule( 'TractographyInteractiveSeeding') # DTI in background sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(dtiVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # place a fiducial displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) r = 28.338526 a = 34.064367 s = 58.74121 fidNode.AddFiducial(r, a, s) # make it active selectionNode = slicer.mrmlScene.GetNodeByID( "vtkMRMLSelectionNodeSingleton") if (selectionNode != None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) # set up the arguments wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation( ) wr.setDiffusionTensorVolumeNode(dtiVolume) # fiber bundle is created automatically wr.setSeedingNode(fidNode) wr.setMinimumPath(10) wr.setStoppingValue(0.15) print("Moving the fiducial") for y in range(-20, 100, 5): msg = "Moving the fiducial to y = " + str(y) print msg moveMsg = qt.QDialog() moveMsg.setLayout(qt.QVBoxLayout()) moveMsg.layout().addWidget(qt.QLabel(msg)) qt.QTimer.singleShot(250, moveMsg.close) moveMsg.exec_() fidNode.SetNthFiducialPosition(0, r, y, s) return True
def create(self, widgetType='window', showHeader=False, showPreview=False): """ main window is a frame with widgets from the app widget repacked into it along with slicer-specific extra widgets """ # find internals of widget for reference and repacking self.toolBar = slicer.util.findChildren(self.dicomBrowser, 'ToolBar')[0] self.databaseNameLabel = slicer.util.findChildren( self.dicomBrowser, 'DatabaseNameLabel')[0] self.databaseDirectoryButton = slicer.util.findChildren( self.dicomBrowser, 'DirectoryButton')[0] #self.tables = self.dicomBrowser.tableManager self.tables = slicer.util.findChildren(self.dicomBrowser, 'dicomTableManager')[0] #self.userFrame = slicer.util.findChildren(self.dicomBrowser, 'UserFrame')[0] self.userFrame = qt.QWidget() #self.thumbs = slicer.util.findChildren(self.dicomBrowser, 'ThumbnailsWidget')[0] #self.widthSlider = slicer.util.findChildren(self.dicomBrowser, 'ThumbnailWidthSlider')[0] self.preview = qt.QWidget() self.widgetType = widgetType if widgetType == 'dialog': self.window = qt.QDialog(self.dicomBrowser) elif widgetType == 'window': self.window = qt.QWidget() elif widgetType == 'popup': self.window = ctk.ctkPopupWidget(self.dicomBrowser) self.window.orientation = 1 self.window.horizontalDirection = 0 self.window.alignment = 0x82 elif widgetType == 'dock': self.dock = qt.QDockWidget(slicer.util.mainWindow()) self.dock.setFeatures(qt.QDockWidget.DockWidgetFloatable | qt.QDockWidget.DockWidgetMovable | qt.QDockWidget.DockWidgetClosable) slicer.util.mainWindow().addDockWidget(0x15, self.dock) self.window = qt.QFrame() self.dock.setWidget(self.window) else: raise "Unknown widget type - should be dialog, window, dock or popup" self.window.setWindowTitle('DICOM Browser') self.layout = qt.QVBoxLayout(self.window) # tool row at top, with commands and database self.toolFrame = qt.QWidget() self.toolFrame.setMaximumHeight(40) self.toolLayout = qt.QHBoxLayout(self.toolFrame) self.layout.addWidget(self.toolFrame) self.toolLayout.addWidget(self.toolBar) self.toolLayout.addWidget(self.databaseNameLabel) self.databaseNameLabel.visible = False self.toolLayout.addWidget(self.databaseDirectoryButton) self.databaseDirectoryButton.visible = False self.settingsButton = ctk.ctkExpandButton() self.toolBar.addWidget(self.settingsButton) self.settingsButton.connect('toggled(bool)', self.onSettingsButton) # tables goes next, spread across 1 row, 2 columns self.tables.tableOrientation = self.tableOrientation self.tables.dynamicTableLayout = False self.tablesExpandableWidget = ctk.ctkExpandableWidget() self.tablesLayout = qt.QVBoxLayout(self.tablesExpandableWidget) self.tablesLayout.addWidget(self.tables) self.tablesExpandableWidget.setMinimumHeight(400) self.layout.addWidget(self.tablesExpandableWidget) # # preview related column # self.previewLayout = qt.QVBoxLayout() #self.layout.addLayout(self.previewLayout,selectionRow,0) #self.previewLayout.addWidget(self.thumbs) #self.previewLayout.addWidget(self.widthSlider) if showPreview: self.previewLayout.addWidget(self.preview) else: self.preview.hide() # # action related column (interacting with slicer) # self.loadableTableFrame = qt.QWidget() self.loadableTableLayout = qt.QFormLayout(self.loadableTableFrame) self.layout.addWidget(self.loadableTableFrame) self.loadableTableLayout.addWidget(self.userFrame) self.userFrame.hide() tableWidth = 350 if showHeader else 600 self.loadableTable = DICOMLoadableTable(self.userFrame, width=tableWidth) #self.loadableTableLayout.addWidget(self.loadableTable.widget) #self.loadableTable.widget.hide() # # button row for action column # self.actionButtonsFrame = qt.QWidget() self.actionButtonsFrame.setMaximumHeight(40) self.layout.addWidget(self.actionButtonsFrame) #self.layout.addStretch(1) self.actionButtonLayout = qt.QHBoxLayout() self.actionButtonsFrame.setLayout(self.actionButtonLayout) self.loadButton = qt.QPushButton('Load') self.loadButton.enabled = True self.loadButton.toolTip = 'Load Selection to Slicer' self.actionButtonLayout.addWidget(self.loadButton) self.loadButton.connect('clicked()', self.loadCheckedLoadables) self.headerPopup = DICOMLib.DICOMHeaderPopup() self.viewMetadataButton = qt.QPushButton('Metadata') self.viewMetadataButton.toolTip = 'Display Metadata of the Selected Series' self.viewMetadataButton.enabled = False self.actionButtonLayout.addWidget(self.viewMetadataButton) self.viewMetadataButton.connect('clicked()', self.onViewHeaderButton) self.viewMetadataButton.connect('clicked()', self.headerPopup.open) self.actionButtonLayout.addStretch(1) self.examineButton = qt.QPushButton('Examine') self.actionButtonLayout.addWidget(self.examineButton) self.examineButton.enabled = False self.examineButton.connect('clicked()', self.examineForLoading) self.uncheckAllButton = qt.QPushButton('Uncheck All') self.actionButtonLayout.addWidget(self.uncheckAllButton) self.uncheckAllButton.connect('clicked()', self.uncheckAllLoadables) self.actionButtonLayout.addStretch(1) self.closeButton = qt.QPushButton('Close') #self.actionButtonLayout.addWidget(self.closeButton) self.closeButton.connect('clicked()', self.close) self.advancedViewButton = qt.QCheckBox('Advanced') self.actionButtonLayout.addWidget(self.advancedViewButton) self.advancedViewButton.enabled = True self.advancedViewButton.checked = self.advancedViewCheckState self.advancedViewButton.connect('clicked()', self.onAdvanedViewButton) self.horizontalViewCheckBox = qt.QCheckBox('Horizontal Tables') self.horizontalViewCheckBox.visible = False self.toolLayout.addWidget(self.horizontalViewCheckBox) self.horizontalViewCheckBox.enabled = True if self.tableOrientation == 1: self.horizontalViewCheckBox.checked = True self.horizontalViewCheckBox.connect('stateChanged(int)', self.onHorizontalViewCheckBox) if self.setBrowserPersistence: self.browserPersistentButton = qt.QCheckBox('Browser Persistent') self.browserPersistentButton.toolTip = 'When enabled, DICOM Broswer remains open and usable after leaving DICOM module' self.actionButtonLayout.addWidget(self.browserPersistentButton) self.browserPersistentButton.connect('stateChanged(int)', self.setBrowserPersistence) if self.advancedViewCheckState == True: self.loadableTableFrame.show() self.window.adjustSize() else: self.examineButton.hide() self.uncheckAllButton.hide() self.loadableTableFrame.hide() self.window.adjustSize() # # header related column (more details about the selected file) # if showHeader: self.headerLayout = qt.QVBoxLayout() self.layout.addLayout(self.headerLayout, selectionRow, 2) self.header = DICOMHeaderWidget(self.window) self.headerLayout.addWidget(self.header.widget) # # Plugin selection widget # self.pluginSelector = DICOMPluginSelector(self.window) self.loadableTableLayout.addRow(self.pluginSelector.widget, self.loadableTable.widget) self.checkBoxByPlugins = [] for pluginClass in slicer.modules.dicomPlugins: self.checkBox = self.pluginSelector.checkBoxByPlugin[pluginClass] self.checkBox.connect('stateChanged(int)', self.onPluginStateChanged) self.checkBoxByPlugins.append(self.checkBox)
def __init__(self, MODULE, saveWorkflow): """ Init function. """ #-------------------- # Call parent. #-------------------- super(XnatFileSaveDialog, self).__init__(MODULE, saveWorkflow) self.MODULE = MODULE #-------------------- # Determine filename. #-------------------- self.fileName = None #-------------------- # Dialog setup. #-------------------- self.inputIndex = 0 self.noticeLabel = qt.QLabel("") #-------------------- # Window setup. #-------------------- self.setNumDialogs(1, {'0':qt.QDialog(slicer.util.mainWindow())}) self.dialogs[0].setFixedWidth(600) self.dialogs[0].setWindowModality(1) #-------------------- # Label button and fileLine. #-------------------- self.saveButtonStr = "Save" fileLineLabel = qt.QLabel("File Name: ") #-------------------- # Set fileline text (where user enters the file # name) #-------------------- self.fileLine = qt.QLineEdit(self.MODULE.View.sessionManager.sessionArgs['fileName'].split(XnatSlicerGlobals.DEFAULT_SLICER_EXTENSION)[0]) #-------------------- # Create file name input layout. #-------------------- fileInputLayout = qt.QHBoxLayout() fileInputLayout.addWidget(fileLineLabel) fileInputLayout.addWidget(self.fileLine) dialogLayout = qt.QVBoxLayout() #-------------------- # Create the buttons. #-------------------- saveButton = qt.QPushButton() saveButton.setText(self.saveButtonStr) cancelButton = qt.QPushButton() cancelButton.setText("Cancel") buttonRow = qt.QDialogButtonBox() buttonRow.addButton(saveButton, 0) buttonRow.addButton(cancelButton, 2) #-------------------- # Put buttons in the bottom row. #-------------------- bottomRow = qt.QHBoxLayout() bottomRow.addWidget(buttonRow) #-------------------- # Add the layouts to the dialog. #-------------------- dialogLayout.addLayout(fileInputLayout) dialogLayout.addWidget(self.noticeLabel) dialogLayout.addLayout(bottomRow) self.dialogs[0].setLayout(dialogLayout) #-------------------- # Set onClick connections. #-------------------- buttonRow.connect('clicked(QAbstractButton*)', self.onButtonClicked)
def makeDeleteHostModal(hostEditor): """ As stated. """ #-------------------- # get selected strings from host list #-------------------- selHost = hostEditor.hostTable.currentRowItems #-------------------- # Buttons #-------------------- okButton = qt.QPushButton("OK") cancelButton = qt.QPushButton("Cancel") #-------------------- # Labels #-------------------- messageLabel = qt.QTextEdit() messageLabel.setReadOnly(True) messageLabel.insertPlainText("Are you sure you want to delete the host ") messageLabel.setFontItalic(True) messageLabel.setFontWeight(100) messageLabel.insertPlainText(selHost['name']) messageLabel.setFontWeight(0) messageLabel.insertPlainText(" ?") messageLabel.setFixedHeight(40) messageLabel.setFrameShape(0) #-------------------- # Layouts #-------------------- currLayout = qt.QVBoxLayout() currLayout.addWidget(messageLabel) currLayout.addStretch(1) buttonLayout = qt.QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(cancelButton) buttonLayout.addWidget(okButton) masterForm = qt.QFormLayout() masterForm.addRow(currLayout) masterForm.addRow(buttonLayout) #-------------------- # Window #-------------------- deleteHostModal = qt.QDialog(hostEditor.addButton) deleteHostModal.setWindowTitle("Delete Host") deleteHostModal.setLayout(masterForm) deleteHostModal.setWindowModality(2) #-------------------- # Button Connectors #-------------------- cancelButton.connect("clicked()", deleteHostModal.close) okButton.connect("clicked()", hostEditor.deleteHost) return deleteHostModal
def makeEditHostModal(hostEditor): """ As stated. """ #-------------------- # Get selected strings from host list. #-------------------- selHost = hostEditor.hostTable.currentRowItems #-------------------- # Populate the line edits from selecting strings. #-------------------- hostEditor.nameLine.setText(selHost['name']) hostEditor.urlLine.setText(selHost['url']) #-------------------- # Prevent editing of default host. #-------------------- if not hostEditor.MODULE.XnatSettingsFile.isModifiable(selHost['name']): hostEditor.nameLine.setReadOnly(True) hostEditor.nameLine.setFont(hostEditor.MODULE.GLOBALS.LABEL_FONT_ITALIC) hostEditor.nameLine.setEnabled(False) hostEditor.urlLine.setReadOnly(True) hostEditor.urlLine.setFont(hostEditor.MODULE.GLOBALS.LABEL_FONT_ITALIC) hostEditor.urlLine.setEnabled(False) #-------------------- # Otherwise, go ahead. #-------------------- else: hostEditor.nameLine.setEnabled(True) hostEditor.urlLine.setEnabled(True) #-------------------- # Buttons. #-------------------- cancelButton = qt.QPushButton("Cancel") saveButton = qt.QPushButton("OK") #-------------------- # Layouts. #-------------------- currLayout = qt.QFormLayout() hostEditor.prevName = hostEditor.nameLine.text currLayout.addRow("Edit Name:", hostEditor.nameLine) currLayout.addRow("Edit URL:", hostEditor.urlLine) #-------------------- # Default checkbox if default. #-------------------- if hostEditor.MODULE.XnatSettingsFile.isDefault(hostEditor.nameLine.text): hostEditor.setDefault.setCheckState(2) #-------------------- # Labels. #-------------------- spaceLabel = qt.QLabel("") unmLabel = qt.QLabel("Stored Username:"******"Edit Host") editHostModal.setFixedWidth(300) editHostModal.setLayout(masterForm) editHostModal.setWindowModality(2) #-------------------- # Button Connectors #-------------------- cancelButton.connect("clicked()", editHostModal.close) saveButton.connect("clicked()", hostEditor.rewriteHost) return editHostModal