def createProgressDialog(parent=None, value=0, maximum=100, labelText="", windowTitle="Processing...", windowFlags=None, **kwargs): """Display a modal QProgressDialog. Go to QProgressDialog documentation http://pyqt.sourceforge.net/Docs/PyQt4/qprogressdialog.html for more keyword arguments, that could be used. E.g. progressbar = createProgressIndicator(autoClose=False) if you don't want the progress dialog to automatically close. Updating progress value with progressbar.value = 50 Updating label text with progressbar.labelText = "processing XYZ" """ progressIndicator = qt.QProgressDialog( parent if parent else slicer.util.mainWindow(), windowFlags if windowFlags else qt.Qt.WindowStaysOnTopHint) progressIndicator.minimumDuration = 0 progressIndicator.maximum = maximum progressIndicator.value = value progressIndicator.windowTitle = windowTitle progressIndicator.labelText = labelText for key, value in kwargs.iteritems(): if hasattr(progressIndicator, key): setattr(progressIndicator, key, value) return progressIndicator
def makeProgressIndicator(maxVal=100, initialValue=0): progressIndicator = qt.QProgressDialog() progressIndicator.minimumDuration = 0 progressIndicator.modal = True progressIndicator.setMaximum(maxVal) progressIndicator.setValue(initialValue) progressIndicator.setWindowTitle("Processing...") progressIndicator.show() progressIndicator.autoClose = False return progressIndicator
def __init__(self, cachePath, icon): self.cachePath = cachePath self.window = qt.QWidget() self.window.setWindowTitle( 'Clinical Data (From cBioportal for Cancer Genomics)') self.window.setWindowIcon(icon) self.layout = qt.QVBoxLayout(self.window) self.setup() self.progress = qt.QProgressDialog(self.window) self.progress.setWindowTitle("Clinical Data")
def getLoadablesFromFileLists(self, fileLists): """Take list of file lists, return loadables by plugin dictionary """ loadablesByPlugin = {} allFileCount = missingFileCount = 0 for fileList in self.fileLists: for filePath in fileList: allFileCount += 1 if not os.path.exists(filePath): missingFileCount += 1 if missingFileCount > 0: qt.QMessageBox.warning(self.window, "DICOM", "Warning: %d of %d selected files listed in the database cannot be found on disk." % (missingFileCount, allFileCount)) if missingFileCount == allFileCount: return self.progress = qt.QProgressDialog(self.window) self.progress.modal = True self.progress.minimumDuration = 0 self.progress.show() self.progress.setValue(0) self.progress.setMaximum(len(slicer.modules.dicomPlugins)) step = 0 loadEnabled = False plugins = self.pluginSelector.selectedPlugins() for pluginClass in plugins: if not self.pluginInstances.has_key(pluginClass): self.pluginInstances[pluginClass] = slicer.modules.dicomPlugins[pluginClass]() plugin = self.pluginInstances[pluginClass] if self.progress.wasCanceled: break self.progress.labelText = '\nChecking %s' % pluginClass slicer.app.processEvents() self.progress.setValue(step) slicer.app.processEvents() try: loadablesByPlugin[plugin] = plugin.examineForImport(fileLists) # If regular method is not overridden (so returns empty list), try old function # Ensuring backwards compatibility: examineForImport used to be called examine if loadablesByPlugin[plugin] == []: loadablesByPlugin[plugin] = plugin.examine(fileLists) loadEnabled = loadEnabled or loadablesByPlugin[plugin] != [] except Exception,e: import traceback traceback.print_exc() qt.QMessageBox.warning(self.window, "DICOM", "Warning: Plugin failed: %s\n\nSee python console for error message." % pluginClass) print("DICOM Plugin failed: %s", str(e)) step +=1
def apply(self, xy, mode=0, forced_path=None, forced_point=None): # # get the parameters from MRML # # For sanity purposes, tool can always "paint" over existing labels. If we find some foreseeable reason why we might # not want this in all cases, we can re-add to the GUI. # # get the label and background volume nodes # labelLogic = self.sliceLogic.GetLabelLayer() labelNode = labelLogic.GetVolumeNode() backgroundLogic = self.sliceLogic.GetBackgroundLayer() backgroundNode = backgroundLogic.GetVolumeNode() ##### self.errorMessageFrame.textCursor().insertHtml('Error Detected!') ##### self.errorMessageFrame.setStyleSheet("QTextEdit {color:red}") # # get the ijk location of the clicked point # by projecting through patient space back into index # space of the volume. Result is sub-pixel, so round it # (note: bg and lb will be the same for volumes created # by the editor, but can be different if the use selected # different bg nodes, but that is not handled here). # xyToIJK = labelLogic.GetXYToIJKTransform() ijkFloat = xyToIJK.TransformDoublePoint(xy + (0, )) ijk = [] for element in ijkFloat: try: intElement = int(round(element)) except ValueError: intElement = 0 ijk.append(intElement) ijk.reverse() ijk = tuple(ijk) ### IJK ACTIVE HERE # # Get the numpy array for the bg and label # node = EditUtil.EditUtil().getParameterNode() offset = float(node.GetParameter("TraceAndSelect,offsetvalue")) if offset != 0 and mode == 0: self.progress = qt.QProgressDialog() self.progress.setLabelText("Processing Slices...") self.progress.setCancelButtonText("Abort Fill") self.progress.setMinimum(0) self.progress.setMaximum(abs(offset)) self.progress.setAutoClose(1) self.progress.open() return self.fill(ijk, [], mode, forced_path, forced_point)
def __init__(self): self.catalogMainUrl = qt.QUrl('http://perk-software.cs.queensu.ca/plus/doc/nightly/modelcatalog/') self.catalogName = 'Plus toolkit 3D model catalog' self.browser = qt.QWebView() # Change QWebView such that link clicks are not automatically acted on # When links are clicked, run the handleClick() function self.browser.page().setLinkDelegationPolicy(qt.QWebPage.DelegateAllLinks) self.browser.linkClicked.connect(self.handleClick) self.downloadProgressBar = qt.QProgressDialog() self.downloadProgressBar.setLabelText('Downloading File')
def onOk(self): address = self.dicomEntries['Destination Address'].text port = self.dicomEntries['Destination Port'].text settings = qt.QSettings() settings.setValue('DICOM.sendAddress', address) settings.setValue('DICOM.sendPort', port) self.progress = qt.QProgressDialog(slicer.util.mainWindow()) self.progress.minimumDuration = 0 self.progress.setMaximum(len(self.files)) self.progressValue = 0 try: DICOMLib.DICOMSender(self.files, address, port, progressCallback = self.onProgress) except Exception as result: qt.QMessageBox.warning(self.dialog, 'DICOM Send', 'Could not send data: %s' % result) self.progress.close() self.dialog.close()
def redrawTree(self, hosts): dialog = qt.QProgressDialog(self, "Loading workspace...", True) dialog.setCaption("Please wait") dialog.setLabelText("Loading workspace...") dialog.setTotalSteps(len(hosts) + 1) i = 1 for host in hosts: dialog.setProgress(i) category = host.getCurrentCategory() self._addCategory(category) self._addHostToCategory(host, category) i += 1 for ci in self._category_items.values(): ci.setOpen(True) self.createIndex() dialog.setProgress(i) self.filterTree(self._filter) # we need to make sure that the dialog is closed rem = dialog.totalSteps() - i if rem > 0: dialog.setProgress(i + rem)
def loadFiles(self, datasetname, files): pd = qt.QProgressDialog('Loading file(s) in Slicer...', 'Cancel', 0, len(files) + 2, slicer.util.mainWindow()) pd.setModal(True) #pd.setMinimumDuration(0) pd.show() slicer.app.processEvents() for f in files: if pd.wasCanceled: break pd.setValue(files.index(f) + 1) slicer.app.processEvents() remoteName = os.path.join(datasetname, f.replace('/', os.sep)) localName = os.path.join(self.localCashFolder, remoteName) if not os.path.exists(localName): continue try: print 'loading ' + localName self.loadFile(localName) except: print 'error loading file: ' print sys.exc_info()[0] pd.setValue(len(files) + 2) pd.hide()
def downloadFiles(self, datasetname, files, askForConfirmation=True): if askForConfirmation: filestats = self.listFilesForDataset(datasetname) filesToDownload = [f for f in filestats if f['name'] in files and \ not os.path.exists(os.path.join(self.localCashFolder,datasetname,f['name']))] if len(filesToDownload) == 0: return True s = 'Downloading '+str(len(filesToDownload))+' file(s) with '+\ self.hrSize(sum(f['size'] for f in filesToDownload))+'.'+\ ' This could take some time. Do you want to continue?' confirmDownload = qt.QMessageBox.question(self, 'Download?', s, qt.QMessageBox.Yes, qt.QMessageBox.No) if confirmDownload != qt.QMessageBox.Yes: return False pd = qt.QProgressDialog('Downloading file(s)...', 'Cancel', 0, len(files) + 2, slicer.util.mainWindow()) pd.setModal(True) pd.setMinimumDuration(0) pd.show() slicer.app.processEvents() for f in files: if pd.wasCanceled: break pd.setValue(files.index(f) + 1) slicer.app.processEvents() remoteName = os.path.join(datasetname, f.replace('/', os.sep)) localName = os.path.join(self.localCashFolder, remoteName) if not os.path.exists(localName): print 'downloading ' + remoteName try: SharedGDriveUtils(self.remoteFolderId).downloadFile( remoteName, localName) except: print 'error downloading file: ' print sys.exc_info()[0] pd.setValue(len(files) + 2) return True
def main(input_csv, out_dir, server_path): try: with open(Path(input_csv), 'r') as fh: reader = DictReader(fh) all_rows = [row for row in reader] except Exception as e: print('error reading the master dict file, return: {}'.format(e)) return out_csv_file = Path(input_csv.replace('.csv', '_eyelid.csv')) fieldnames = all_rows[0].keys() writeToCsv(out_csv_file, fieldnames) segmentation_node = None image_node = None slicer.progressWindow = qt.QProgressDialog( "Ploughing throug segmentations", "Abort Load", 0, len(all_rows), slicer.util.mainWindow()) slicer.progressWindow.setWindowModality(qt.Qt.WindowModal) def showProgress(value, text): if slicer.progressWindow.wasCanceled: raise Exception('Segmentation load aborted') slicer.progressWindow.show() slicer.progressWindow.activateWindow() slicer.progressWindow.setValue(value) slicer.progressWindow.setLabelText(text) slicer.app.processEvents() for num_id, row in enumerate(all_rows): imgpath = Path(server_path) / Path(row['image path']) segpath = Path(server_path) / Path(row['segmentation path']) showProgress(num_id, str(segpath)) if not segpath.exists() or not imgpath.exists(): print('Either {} or {} does not exists'.format(imgpath, segpath)) continue out_segmentation_path = Path(out_dir) / segpath.name try: if segmentation_node is not None: slicer.mrmlScene.RemoveNode(segmentation_node) segmentation_node = None if not out_segmentation_path.exists(): segmentation_node = slicer.util.loadSegmentation(str(segpath)) # Deal with segment names: current_segmentation = segmentation_node.GetSegmentation() number_of_segments = current_segmentation.GetNumberOfSegments() if number_of_segments < 3: createEyelidSegment(segmentation_node, imgpath, out_segmentation_path) current_segmentation = segmentation_node.GetSegmentation() number_of_segments = current_segmentation.GetNumberOfSegments( ) row['segmentation path'] = out_segmentation_path.relative_to( server_path) else: print('{} already exists, skipping processing'.format( out_segmentation_path)) row['segmentation path'] = out_segmentation_path.relative_to( server_path) writeToCsv(out_csv_file, fieldnames, row=row) except Exception as e: print("Couldn't load segmentation: {}\n ERROR: {}".format( segpath, e)) segmentation_node = None slicer.progressWindow.close()
def proceedWithReferencedLoadablesSelection(self): # each check box corresponds to a referenced loadable # that was selected by examine; if the user confirmed # that reference should be loaded, add it to the self.loadablesByPlugin # dictionary if self.referencesDialog: children = self.referencesDialog.children() loadableCnt = 0 for plugin in self.referencedLoadables: for loadable in self.referencedLoadables[plugin]: if loadable.selected: if children[loadableCnt+2].checked: self.loadablesByPlugin[plugin].append(loadable) self.referencesDialog.close() self.referencesDialog = None loadableCount = 0 for plugin in self.loadablesByPlugin: for loadable in self.loadablesByPlugin[plugin]: if loadable.selected: loadableCount += 1 self.progress = qt.QProgressDialog(self.window) self.progress.minimumDuration = 0 self.progress.show() self.progress.setValue(0) self.progress.setMaximum(loadableCount) step = 0 loadingResult = '' loadedNodeIDs = [] @vtk.calldata_type(vtk.VTK_OBJECT) def onNodeAdded(caller, event, calldata): node = calldata if isinstance(node, slicer.vtkMRMLVolumeNode): loadedNodeIDs.append(node.GetID()) self.addObserver(slicer.mrmlScene, slicer.vtkMRMLScene.NodeAddedEvent, onNodeAdded); for plugin in self.loadablesByPlugin: for loadable in self.loadablesByPlugin[plugin]: if self.progress.wasCanceled: break slicer.app.processEvents() self.progress.setValue(step) slicer.app.processEvents() if loadable.selected: self.progress.labelText = '\nLoading %s' % loadable.name slicer.app.processEvents() if not plugin.load(loadable): loadingResult = '%s\nCould not load: %s as a %s' % (loadingResult,loadable.name,plugin.loadType) step += 1 self.progress.setValue(step) slicer.app.processEvents() try: for derivedItem in loadable.derivedItems: indexer = ctk.ctkDICOMIndexer() self.progress.labelText = '\nIndexing %s' % derivedItem slicer.app.processEvents() indexer.addFile(slicer.dicomDatabase, derivedItem) except AttributeError: # no derived items or some other attribute error pass self.removeObserver(slicer.mrmlScene, slicer.vtkMRMLScene.NodeAddedEvent, onNodeAdded); loadedFileParameters = {} loadedFileParameters['nodeIDs'] = loadedNodeIDs slicer.app.ioManager().emitNewFileLoaded(loadedFileParameters) self.progress.close() self.progress = None if loadingResult: qt.QMessageBox.warning(slicer.util.mainWindow(), 'DICOM loading', loadingResult) if not self.browserPersistent: self.close() return
def onApplyButton(self): inputVolume = self.inputSelector.currentNode() outputVolume = self.segmentationSelector.currentNode() jsonFile = tempfile.NamedTemporaryFile().name normalizationFactor = 1.0 try: normalizationFactor = float(self.normalizationFactorLineEdit.text) except: pass cliParams = {'inputVolume': inputVolume.GetID(), \ 'normalizationFactor': normalizationFactor, \ 'measurementsData': jsonFile, } if outputVolume: cliParams['outputVolume'] = outputVolume.GetID() pd = qt.QProgressDialog('Running PET Cylinder Phantom Analysis...', 'Cancel', 0, 100, slicer.util.mainWindow()) pd.setModal(True) pd.setMinimumDuration(0) pd.show() pd.setValue(30) cliNode = None cliNode = slicer.cli.run(slicer.modules.petphantomanalysiscli, cliNode, cliParams, wait_for_completion=False) while cliNode.IsBusy(): slicer.app.processEvents() if pd.wasCanceled: cliNode.Cancel() pd.setValue(100) if pd.wasCanceled: return if cliNode.GetStatusString() != 'Completed': qt.QMessageBox().warning( None, "Warning", "Analysis of PET cylinder phantom was not successful.") return for i in range(cliNode.GetNumberOfParametersInGroup(1)): name = cliNode.GetParameterName(1, i) value = cliNode.GetParameterDefault(1, i) if name == 'Mean_s': self.meanValueLineEdit.setText(value) if name == 'Std_s': self.stdValueLineEdit.setText(value) if name == 'MaxRelDiff_s': self.maxRelDiffValueLineEdit.setText(value) if self.meanValueLineEdit.text == '--': qt.QMessageBox().warning( None, "Warning", "Analysis of PET cylinder phantom was not successful.") return try: measurements = json.load(open(jsonFile)) os.remove(jsonFile) except: qt.QMessageBox().warning( None, "Warning", "Analysis of PET cylinder phantom was not successful.") return # plot normalized slice measurements mean = measurements['CylinderMean'] sliceOffsets = measurements['SliceOffsets'] sliceMeasurements = measurements['SliceMeasurements'] normalizedSliceMeasurements = [v / mean for v in sliceMeasurements] self._createPlot(normalizedSliceMeasurements, sliceOffsets) # visualize matched cylinder self.cylinderModelNode.SetAndObserveMesh( self._createCylinderMesh(measurements['CylinderCenter'], measurements['CylinderDirection']))
def onDICOMDirectoryChanged(self): print 'onDICOMDirectoryChanged()' self.patientsTable.clear() self.patientsTable.setSortingEnabled(False) self.patientsTable.setHorizontalHeaderLabels( self.patientsTableHeaderLabels) self.patientGroupBox.setTitle('Patient Selection (DICOM Directory)') self.examinePatientButton.disconnect('clicked(bool)') self.examinePatientButton.setText('Examine Patient') self.examinePatientButton.connect('clicked(bool)', self.onExaminePatient) # recursively read directory TODO make this much faster self.patientFiles = {} pd = qt.QProgressDialog('Reading Files...', 'Cancel', 0, 100, slicer.util.mainWindow()) pd.setModal(True) pd.setMinimumDuration(0) pd.show() pd.setValue(0) for directory, subdir, f in os.walk(self.dirButton.directory): numFiles = len(f) fileProg = 0 for filename in f: pd.setValue(100 * fileProg / numFiles) slicer.app.processEvents() if filename[-4:] == '.dcm': filePath = os.path.join(directory, filename) dcmFile = dicom.read_file(filePath) patient = str(dcmFile.PatientID) modality = str(dcmFile.Modality) if patient not in self.patientFiles.keys(): self.patientFiles[patient] = {} self.patientFiles[patient]['Modalities'] = [] if modality not in self.patientFiles[patient]: self.patientFiles[patient][modality] = [] self.patientFiles[patient]['Modalities'].append( modality) self.patientFiles[patient][modality].append(filePath) self.patientFiles[patient]['PatientName'] = str( dcmFile.PatientName) self.patientFiles[patient]['PatientBirthDate'] = str( dcmFile.PatientBirthDate) self.patientFiles[patient]['PatientSex'] = str( dcmFile.PatientSex) try: self.patientFiles[patient]['EthnicGroup'] = str( dcmFile.EthnicGroup) except AttributeError: pass fileProg += 1 pd.setValue(100) # populate the table count = 0 patients = self.patientFiles.keys() self.patientsTable.setRowCount(len(patients)) for patient in patients: self.patientsTable.setItem(count, 0, qt.QTableWidgetItem(patient)) self.patientsTable.setItem( count, 1, qt.QTableWidgetItem(self.patientFiles[patient]['PatientName'])) self.patientsTable.setItem( count, 2, qt.QTableWidgetItem( self.patientFiles[patient]['PatientBirthDate'])) self.patientsTable.setItem( count, 3, qt.QTableWidgetItem(self.patientFiles[patient]['PatientSex'])) modalities = self.patientFiles[patient]['Modalities'] modalities.sort() self.patientsTable.setItem( count, 4, qt.QTableWidgetItem(','.join(modalities))) count += 1 self.patientsTable.resizeColumnsToContents() self.patientsTableHeader.setStretchLastSection(True) self.patientsTable.setSortingEnabled(True) self.patientsTableHeader.setSortIndicator(0, 0) # order by patient name print patients self.patientsTable.selectRow(0) self.examinePatientButton.enabled = True