def createUserInterface( self ): self.skip = 0 self.__layout = self.__parent.createUserInterface() baselineScanLabel = qt.QLabel( 'CT or MR scan:' ) self.__baselineVolumeSelector = slicer.qMRMLNodeComboBox() self.__baselineVolumeSelector.toolTip = "Choose the baseline scan" self.__baselineVolumeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__baselineVolumeSelector.setMRMLScene(slicer.mrmlScene) self.__baselineVolumeSelector.addEnabled = 0 # followupScanLabel = qt.QLabel( 'Followup scan:' ) # self.__followupVolumeSelector = slicer.qMRMLNodeComboBox() # self.__followupVolumeSelector.toolTip = "Choose the followup scan" # self.__followupVolumeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] # self.__followupVolumeSelector.setMRMLScene(slicer.mrmlScene) # self.__followupVolumeSelector.addEnabled = 0 #Load Template Button self.loadTemplateButton = qt.QPushButton('Load template') self.__layout.addRow(self.loadTemplateButton) self.loadTemplateButton.connect('clicked()', self.loadTemplate) #Load Scan Button self.__fileFrame = ctk.ctkCollapsibleButton() self.__fileFrame.text = "File Input" self.__fileFrame.collapsed = 1 fileFrame = qt.QFormLayout(self.__fileFrame) self.__layout.addRow(self.__fileFrame) loadDataButton = qt.QPushButton('Load Scan') loadDataButton.connect('clicked()', self.loadData) fileFrame.addRow(loadDataButton) fileFrame.addRow( baselineScanLabel, self.__baselineVolumeSelector ) # DICOM ToolBox self.__DICOMFrame = ctk.ctkCollapsibleButton() self.__DICOMFrame.text = "DICOM Input" self.__DICOMFrame.collapsed = 1 dicomFrame = qt.QFormLayout(self.__DICOMFrame) self.__layout.addRow(self.__DICOMFrame) voiGroupBox = qt.QGroupBox() voiGroupBox.setTitle( 'DICOM' ) dicomFrame.addRow( voiGroupBox ) voiGroupBoxLayout = qt.QFormLayout( voiGroupBox ) self.__roiWidget = ctk.ctkDICOMAppWidget() voiGroupBoxLayout.addRow( self.__roiWidget ) self.updateWidgetFromParameters(self.parameterNode())
def setup(self): self.localFrame = ctk.ctkCollapsibleButton(self.parent) self.localFrame.setLayout(qt.QVBoxLayout()) self.localFrame.setText("Local Testing Server") self.layout.addWidget(self.localFrame) self.localFrame.collapsed = True self.toggleServer = qt.QPushButton("Start Server") self.localFrame.layout().addWidget(self.toggleServer) self.toggleServer.connect('clicked()', self.onToggleServer) self.verboseServer = qt.QCheckBox("Verbose") self.localFrame.layout().addWidget(self.verboseServer) self.dicomFrame = ctk.ctkCollapsibleButton(self.parent) self.dicomFrame.setLayout(qt.QVBoxLayout()) self.dicomFrame.setText("DICOM Database and Networking") self.layout.addWidget(self.dicomFrame) self.dicomApp = ctk.ctkDICOMAppWidget() self.dicomFrame.layout().addWidget(self.dicomApp) # hide the search options - doesn't work yet and doesn't fit # well into the frame self.findChildren(self.dicomApp, 'searchOption')[0].hide() # make the tree a little smaller to fit in slicer tree = self.findChildren(self.dicomApp, 'treeView')[0] g = tree.geometry g.setHeight(100) self.onDatabaseDirectoryChanged(self.dicomApp.databaseDirectory) self.dicomApp.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged) tree.connect('clicked(const QModelIndex&)', self.onTreeClicked) userFrame = self.findChildren(self.dicomApp, 'userFrame')[0] userFrame.setLayout(qt.QVBoxLayout()) self.loadButton = qt.QPushButton('Load to Slicer') self.loadButton.enabled = False userFrame.layout().addWidget(self.loadButton) self.loadButton.connect('clicked()', self.onLoadButton) # Add spacer to layout self.layout.addStretch(1)
def setup(self): # # 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 = False 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() if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect('stateChanged(int)',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) if settings.contains('DICOM/RunListenerAtStart'): self.runListenerAtStart.checked = bool(settings.value('DICOM/RunListenerAtStart')) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # the Database frame (home of the ctkDICOM widget) self.dicomFrame = ctk.ctkCollapsibleButton(self.parent) self.dicomFrame.setLayout(qt.QVBoxLayout()) self.dicomFrame.setText("DICOM Database and Networking") self.layout.addWidget(self.dicomFrame) # initialize the dicomDatabase # - pick a default and let the user know if not slicer.dicomDatabase: self.promptForDatabaseDirectory() # # create and configure the app widget - this involves # reaching inside and manipulating the widget hierarchy # - TODO: this configurability should be exposed more natively # in the CTK code to avoid the findChildren calls # self.dicomApp = ctk.ctkDICOMAppWidget() DICOM.setDatabasePrecacheTags(self.dicomApp) if self.hideSearch: # hide the search options - doesn't work yet and doesn't fit # well into the frame slicer.util.findChildren(self.dicomApp, 'SearchOption')[0].hide() self.detailsPopup = DICOMLib.DICOMDetailsPopup(self.dicomApp,setBrowserPersistence=self.setBrowserPersistence) self.tree = self.detailsPopup.tree self.showBrowser = qt.QPushButton('Show DICOM Browser') self.dicomFrame.layout().addWidget(self.showBrowser) self.showBrowser.connect('clicked()', self.detailsPopup.open) # make the tree view a bit bigger self.tree.setMinimumHeight(250) if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile self.contextMenu = qt.QMenu(self.tree) self.exportAction = qt.QAction("Export to Study", self.contextMenu) self.contextMenu.addAction(self.exportAction) self.exportAction.enabled = False self.deleteAction = qt.QAction("Delete", self.contextMenu) self.contextMenu.addAction(self.deleteAction) self.contextMenu.connect('triggered(QAction*)', self.onContextMenuTriggered) slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) self.dicomApp.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged) selectionModel = self.tree.selectionModel() # TODO: can't use this because QList<QModelIndex> is not visible in PythonQt #selectionModel.connect('selectionChanged(QItemSelection, QItemSelection)', self.onTreeSelectionChanged) self.tree.connect('clicked(QModelIndex)', self.onTreeClicked) self.tree.setContextMenuPolicy(3) self.tree.connect('customContextMenuRequested(QPoint)', self.onTreeContextMenuRequested) # enable to the Send button of the app widget and take it over # for our purposes - TODO: fix this to enable it at the ctkDICOM level self.sendButton = slicer.util.findChildren(self.dicomApp, text='Send')[0] self.sendButton.enabled = False self.sendButton.connect('triggered()', self.onSendClicked) # the recent activity frame self.activityFrame = ctk.ctkCollapsibleButton(self.parent) 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.widget) self.requestUpdateRecentActivity() # Add spacer to layout self.layout.addStretch(1)
def onImportDicomButtonClicked(self): self.w = ctk.ctkDICOMAppWidget() self.w.show()
def setup(self): # # 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 = False 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() if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect('stateChanged(int)',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) if settings.contains('DICOM/RunListenerAtStart'): self.runListenerAtStart.checked = bool(settings.value('DICOM/RunListenerAtStart')) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # the Database frame (home of the ctkDICOM widget) self.dicomFrame = ctk.ctkCollapsibleButton(self.parent) self.dicomFrame.setLayout(qt.QVBoxLayout()) self.dicomFrame.setText("DICOM Database and Networking") self.layout.addWidget(self.dicomFrame) self.dicomApp = ctk.ctkDICOMAppWidget() self.dicomFrame.layout().addWidget(self.dicomApp) # hide the search options - doesn't work yet and doesn't fit # well into the frame self.findChildren(self.dicomApp, 'SearchOption')[0].hide() # make the tree a little smaller to fit in slicer self.tree = self.findChildren(self.dicomApp, 'TreeView')[0] g = self.tree.geometry g.setHeight(150) if self.dicomApp.databaseDirectory: self.onDatabaseDirectoryChanged(self.dicomApp.databaseDirectory) else: self.promptForDatabaseDirectory() if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile self.contextMenu = qt.QMenu(self.tree) self.deleteAction = qt.QAction("Delete", self.contextMenu) self.contextMenu.addAction(self.deleteAction) self.contextMenu.connect('triggered(QAction*)', self.onContextMenuTriggered) self.dicomApp.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged) self.tree.connect('clicked(const QModelIndex&)', self.onTreeClicked) self.tree.setContextMenuPolicy(3) self.tree.connect('customContextMenuRequested(QPoint)', self.onTreeContextMenuRequested) userFrame = self.findChildren(self.dicomApp, 'UserFrame')[0] userFrame.setLayout(qt.QVBoxLayout()) self.treeLabel = qt.QLabel('Selection: None') userFrame.layout().addWidget(self.treeLabel) self.loadButton = qt.QPushButton('Load to Slicer') self.loadButton.enabled = False userFrame.layout().addWidget(self.loadButton) self.loadButton.connect('clicked()', self.onLoadButton) self.exportButton = qt.QPushButton('Export Slicer Volume to Study...') self.exportButton.enabled = False userFrame.layout().addWidget(self.exportButton) self.exportButton.connect('clicked()', self.onExportButton) # Add spacer to layout self.layout.addStretch(1)
def setup(self): # # 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 = False 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() if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect('stateChanged(int)', 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) if settings.contains('DICOM/RunListenerAtStart'): self.runListenerAtStart.checked = bool( settings.value('DICOM/RunListenerAtStart')) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # the Database frame (home of the ctkDICOM widget) self.dicomFrame = ctk.ctkCollapsibleButton(self.parent) self.dicomFrame.setLayout(qt.QVBoxLayout()) self.dicomFrame.setText("DICOM Database and Networking") self.layout.addWidget(self.dicomFrame) # initialize the dicomDatabase # - don't let the user escape without # picking a valid database directory while not slicer.dicomDatabase: self.promptForDatabaseDirectory() # # create and configure the app widget - this involves # reaching inside and manipulating the widget hierarchy # - TODO: this configurability should be exposed more natively # in the CTK code to avoid the findChildren calls # self.dicomApp = ctk.ctkDICOMAppWidget() if self.hideSearch: # hide the search options - doesn't work yet and doesn't fit # well into the frame slicer.util.findChildren(self.dicomApp, 'SearchOption')[0].hide() self.detailsPopup = DICOMLib.DICOMDetailsPopup( self.dicomApp, setBrowserPersistence=self.setBrowserPersistence) self.tree = self.detailsPopup.tree self.showBrowser = qt.QPushButton('Show DICOM Browser') self.dicomFrame.layout().addWidget(self.showBrowser) self.showBrowser.connect('clicked()', self.detailsPopup.open) # make the tree view a bit bigger self.tree.setMinimumHeight(250) if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile self.contextMenu = qt.QMenu(self.tree) self.exportAction = qt.QAction("Export to Study", self.contextMenu) self.contextMenu.addAction(self.exportAction) self.exportAction.enabled = False self.deleteAction = qt.QAction("Delete", self.contextMenu) self.contextMenu.addAction(self.deleteAction) self.contextMenu.connect('triggered(QAction*)', self.onContextMenuTriggered) slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) self.dicomApp.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged) selectionModel = self.tree.selectionModel() # TODO: can't use this because QList<QModelIndex> is not visible in PythonQt #selectionModel.connect('selectionChanged(QItemSelection, QItemSelection)', self.onTreeSelectionChanged) self.tree.connect('clicked(QModelIndex)', self.onTreeClicked) self.tree.setContextMenuPolicy(3) self.tree.connect('customContextMenuRequested(QPoint)', self.onTreeContextMenuRequested) # enable to the Send button of the app widget and take it over # for our purposes - TODO: fix this to enable it at the ctkDICOM level self.sendButton = slicer.util.findChildren(self.dicomApp, text='Send')[0] self.sendButton.enabled = False self.sendButton.connect('clicked()', self.onSendClicked) # the recent activity frame self.activityFrame = ctk.ctkCollapsibleButton(self.parent) 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.widget) self.requestUpdateRecentActivity() # Add spacer to layout self.layout.addStretch(1)
def setup(self): # # 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 = False 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() if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect('stateChanged(int)', 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) if settings.contains('DICOM/RunListenerAtStart'): self.runListenerAtStart.checked = bool( settings.value('DICOM/RunListenerAtStart')) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # the Database frame (home of the ctkDICOM widget) self.dicomFrame = ctk.ctkCollapsibleButton(self.parent) self.dicomFrame.setLayout(qt.QVBoxLayout()) self.dicomFrame.setText("DICOM Database and Networking") self.layout.addWidget(self.dicomFrame) self.dicomApp = ctk.ctkDICOMAppWidget() self.dicomFrame.layout().addWidget(self.dicomApp) # hide the search options - doesn't work yet and doesn't fit # well into the frame self.findChildren(self.dicomApp, 'SearchOption')[0].hide() # make the tree a little smaller to fit in slicer self.tree = self.findChildren(self.dicomApp, 'TreeView')[0] g = self.tree.geometry g.setHeight(150) if self.dicomApp.databaseDirectory: self.onDatabaseDirectoryChanged(self.dicomApp.databaseDirectory) else: self.promptForDatabaseDirectory() if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile self.contextMenu = qt.QMenu(self.tree) self.deleteAction = qt.QAction("Delete", self.contextMenu) self.contextMenu.addAction(self.deleteAction) self.contextMenu.connect('triggered(QAction*)', self.onContextMenuTriggered) self.dicomApp.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged) self.tree.connect('clicked(const QModelIndex&)', self.onTreeClicked) self.tree.setContextMenuPolicy(3) self.tree.connect('customContextMenuRequested(QPoint)', self.onTreeContextMenuRequested) userFrame = self.findChildren(self.dicomApp, 'UserFrame')[0] userFrame.setLayout(qt.QVBoxLayout()) self.treeLabel = qt.QLabel('Selection: None') userFrame.layout().addWidget(self.treeLabel) self.loadButton = qt.QPushButton('Load to Slicer') self.loadButton.enabled = False userFrame.layout().addWidget(self.loadButton) self.loadButton.connect('clicked()', self.onLoadButton) self.exportButton = qt.QPushButton('Export Slicer Data to Study...') self.exportButton.enabled = False userFrame.layout().addWidget(self.exportButton) self.exportButton.connect('clicked()', self.onExportClicked) # enable to the Send button of the app widget and take it over # for our purposes - TODO: fix this to enable it at the ctkDICOM level self.sendButton = slicer.util.findChildren(self.dicomApp, text='Send')[0] self.sendButton.enabled = False self.sendButton.connect('clicked()', self.onSendClicked) # Add spacer to layout self.layout.addStretch(1)