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() 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) # 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.detailsPopup = self.getSavedDICOMDetailsWidgetType()() # XXX Slicer 4.5 - Remove these. Here only for backward compatibility. self.dicomBrowser = self.detailsPopup.dicomBrowser self.tables = self.detailsPopup.tables # connect to the 'Show DICOM Browser' button self.showBrowserButton = qt.QPushButton('Show DICOM Browser') self.dicomFrame.layout().addWidget(self.showBrowserButton) self.showBrowserButton.connect('clicked()', self.onOpenDetailsPopup) # 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.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() # 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() self.toggleListener.checkable = True 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') == 'true') 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.dicomBrowser = ctk.ctkDICOMBrowser() DICOM.setDatabasePrecacheTags(self.dicomBrowser) self.detailsPopup = DICOMLib.DICOMDetailsPopup(self.dicomBrowser) self.tables = self.detailsPopup.tables self.showBrowser = qt.QPushButton('Show DICOM Browser') self.dicomFrame.layout().addWidget(self.showBrowser) self.showBrowser.connect('clicked()', self.detailsPopup.open) # connect to the main window's dicom button mw = slicer.util.mainWindow() try: action = slicer.util.findChildren(mw,name='LoadDICOMAction')[0] action.connect('triggered()',self.detailsPopup.open) except IndexError: print('Could not connect to the main window DICOM button') # connect to our menu file entry so it raises the browser fileMenu = slicer.util.lookupTopLevelWidget('FileMenu') if fileMenu: for action in fileMenu.actions(): if action.text == 'DICOM': action.connect('triggered()',self.detailsPopup.open) # make the tables view a bit bigger self.tables.setMinimumHeight(250) if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile # TODO: populate context menu self.contextMenu = qt.QMenu(self.tables) self.deleteAction = qt.QAction("Delete", self.contextMenu) self.contextMenu.addAction(self.deleteAction) self.deleteAction.enabled = False self.contextMenu.connect('triggered(QAction*)', self.onContextMenuTriggered) slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) self.dicomBrowser.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged) self.tables.connect('seriesSelectionChanged(QStringList)', self.onSeriesSelected) self.tables.setContextMenuPolicy(3) self.tables.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.dicomBrowser, 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 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): 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()