def _setupUi(self, withBtn): self.setObjectName("DataList") self.setAcceptDrops(True) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setObjectName("verticalLayout") if withBtn: self.loadBtn = QPushButton(self) self.loadBtn.setText(tr("load")) self.loadBtn.setObjectName("loadBtn") self.loadBtn.released.connect(self.loadData) self.verticalLayout.addWidget(self.loadBtn) self.listWidget = QTreeWidget(self) self.listWidget.setHeaderHidden(True) self.listWidget.setContextMenuPolicy(Qt.ActionsContextMenu) self.listWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.listWidget.setDragEnabled(True) self.listWidget.setDragDropMode(QAbstractItemView.InternalMove) self.listWidget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.listWidget.setObjectName("listWidget") self.listWidget.itemSelectionChanged.connect(self.selectionChanged) self.listWidget.itemClicked.connect(self._itemClicked) self.listWidget.itemChanged.connect(self._itemChanged) self.listWidget.itemDoubleClicked.connect(self.itemDoubleClicked) self.listWidget.itemExpanded.connect(self.fitColumnsToContents) self.listWidget.itemCollapsed.connect(self.fitColumnsToContents) self.verticalLayout.addWidget(self.listWidget) self.sigReceivedUrls.connect(self.loadData) self.clearSelection = self.listWidget.clearSelection
def setupUi(self, *args): # called in MainWindowBase.__init__() # put the log widget at the bottom self.addDockWidget(Qt.BottomDockWidgetArea, self._setupLogWidget()) # file widget at the top self.toolbox = ToolBox(self) self._addToolboxItem(self._setupFileWidget()) self._addToolboxItem(self._setupDataWidget()) self._addToolboxItem(self._setupOptimWidget()) self._addToolboxItem(self._setupModelWidget()) self._addToolboxItem(self._setupStatsWidget()) # set up central widget of the main window self.centralLayout = QVBoxLayout() # put buttons in central widget self.centralLayout.addWidget(self.toolbox) self.centralLayout.addWidget(self._setupStartButton()) centralWidget = QWidget(self) centralWidget.setLayout(self.centralLayout) centralWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.setCentralWidget(centralWidget) self.onStartupSignal.connect(self.initUi) # set program icon, same for Win+Lin icopath = "resources/icon/mcsas.ico" if isMac(): icopath = "resources/icon/mcsas.icns" icopath = QFileInfo(makeAbsolutePath(icopath)).absoluteFilePath() self.setWindowIcon(QIcon(icopath))
class NavViewWidget(QWidget): def __init__(self, map_topic = '/map', paths = ['/move_base/SBPLLatticePlanner/plan', '/move_base/TrajectoryPlannerROS/local_plan'], polygons= ['/move_base/local_costmap/robot_footprint']): super(NavViewWidget, self).__init__() self._layout = QVBoxLayout() self.setWindowTitle('Navigation Viewer') self._nav_view = NavView(map_topic, paths, polygons) self._layout.addWidget(self._nav_view) self.setLayout(self._layout)
def _createEntries(self): entryWidget = QWidget(self) entryLayout = QHBoxLayout(entryWidget) inputWidgets = (self._createParamBox(), self._createAutoRange(), self._createLower(), self._createUpper(), self._createBins(), self._createXScale(), self._createYWeight()) self._labels = dict() # assumes same ordering of entryWidgets above and Histogram.displayData for col, inputWidget in zip(Histogram.displayData, inputWidgets): fieldWidget = QWidget(self) # combines label + input fieldLayout = QVBoxLayout(fieldWidget) fieldLayout.setContentsMargins(QMargins()) # create label, text is set in _selectParam() self._labels[col] = QLabel(self) self._labels[col].setAlignment(Qt.AlignHCenter) # stack label + input fieldLayout.addWidget(self._labels[col]) fieldLayout.addWidget(inputWidget) fieldWidget.setLayout(fieldLayout) # add field to row of inputs entryLayout.addWidget(fieldWidget) entryWidget.setLayout(entryLayout) self.pbox.setCurrentIndex(0) self.lentry.selectAll() # select the first input by default return entryWidget
def __init__(self, parent=None): super(MatDataPlot, self).__init__(parent) self._canvas = MatDataPlot.Canvas() vbox = QVBoxLayout() vbox.addWidget(self._canvas) self.setLayout(vbox) self._color_index = 0 self._curves = {} self.keep_secs = 30 self.scale_steps = 150 self.ref_name = 'RTK' self.tgt_name = 'FHWA2 Combined'
def __init__(self, parent, calculator, *args): super(ModelWidget, self).__init__(parent, None, *args) self._calculator = calculator self.title = TitleHandler.setup(self, "Model") # get all loadable ScatteringModels from model directory self._models = FindModels() layout = QVBoxLayout(self) layout.setObjectName("modelLayout") self.setLayout(layout) self.modelBox = QComboBox(self) self.modelBox.setFixedWidth(FIXEDWIDTH) layout.addWidget(self.modelBox) self.modelWidget = QWidget(self) paramLayout = QVBoxLayout(self.modelWidget) self.modelWidget.setLayout(paramLayout) layout.addWidget(self.modelWidget)
def __init__(self, parent, appSettings): super(DataWidget, self).__init__(parent) self.title = TitleHandler.setup(self, "Data Settings") self.appSettings = appSettings # forwarded to SettingsGridWidget below self._widgets = [] self._restored = set() # basic row oriented layout hlayout = QVBoxLayout(self) hlayout.setObjectName("baseLayout") hlayout.setContentsMargins(0, 0, 0, 0)
def __init__(self, parent=None, model=None): QDialog.__init__(self, parent) assert isinstance(model, ScatteringModel) self._model = model self.setObjectName("AddRangeDialog") self.setWindowTitle("Add Range") self.setWindowModality(Qt.WindowModal) vlayout = QVBoxLayout(self) vlayout.setObjectName("vlayout") vlayout.addWidget(self._createEntries()) vlayout.addWidget(self._createButtons()) self.setLayout(vlayout)
class MainWindow(MainWindowBase): onCloseSignal = Signal() _args = None # python command line arguments parser _calculator = None # calculator calling algorithm on all data def __init__(self, parent=None, args=None): # calls setupUi() and restoreSettings() MainWindowBase.__init__(self, version, parent) self._args = args @property def calculator(self): """Returns a calculator object.""" if self._calculator is None: self._calculator = Calculator() return self._calculator def setupUi(self, *args): # called in MainWindowBase.__init__() # put the log widget at the bottom self.addDockWidget(Qt.BottomDockWidgetArea, self._setupLogWidget()) # file widget at the top self.toolbox = ToolBox(self) self._addToolboxItem(self._setupFileWidget()) self._addToolboxItem(self._setupDataWidget()) self._addToolboxItem(self._setupOptimWidget()) self._addToolboxItem(self._setupModelWidget()) self._addToolboxItem(self._setupStatsWidget()) # set up central widget of the main window self.centralLayout = QVBoxLayout() # put buttons in central widget self.centralLayout.addWidget(self.toolbox) self.centralLayout.addWidget(self._setupStartButton()) centralWidget = QWidget(self) centralWidget.setLayout(self.centralLayout) centralWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.setCentralWidget(centralWidget) self.onStartupSignal.connect(self.initUi) # set program icon, same for Win+Lin icopath = "resources/icon/mcsas.ico" if isMac(): icopath = "resources/icon/mcsas.icns" icopath = QFileInfo(makeAbsolutePath(icopath)).absoluteFilePath() self.setWindowIcon(QIcon(icopath)) def _addToolboxItem(self, widget): self.toolbox.addItem( widget, "{n}. {t}".format(n=self.toolbox.count() + 1, t=widget.title())) try: widget.layout().setContentsMargins(0, 0, 0, 0) except: pass def _setupFileWidget(self): # set up file widget fileWidget = FileList(self, title="Data Files", withBtn=False, nestedItems=False) fileWidget.setToolTip( "Right-click to add datafiles.\n" + "Double click to use the estimated size for the model.") self.fileWidget = fileWidget return fileWidget def _setupDataWidget(self): """Set up property widget with settings.""" self.dataWidget = DataWidget(self, self.appSettings) self.dataWidget.sigConfig.connect(self.fileWidget.setDataConfig) self.fileWidget.sigSelectedData.connect(self.dataWidget.onDataSelected) self.fileWidget.sigEmpty.connect(self.dataWidget.onEmptyDataList) return self.dataWidget def _setupOptimWidget(self): """Set up property widget with settings.""" self.optimWidget = OptimizationWidget(self, self.calculator.algo, self.appSettings) self.fileWidget.sigSelectedData.connect( self.optimWidget.onDataSelected) return self.optimWidget def _setupModelWidget(self): """Set up property widget with settings.""" self.modelWidget = ModelWidget(self, self.calculator, self.appSettings) self.fileWidget.sigSphericalSizeRange.connect( self._onSphericalSizeRange) self.fileWidget.sigSelectedData.connect( self.modelWidget.onDataSelected) return self.modelWidget def _onSphericalSizeRange(self, *args): if self.modelWidget.setSphericalSizeRange(*args): self.toolbox.setCurrentWidget(self.modelWidget) def _setupStatsWidget(self): """Set up property widget with settings.""" # setup similar to the file widget self.statsWidget = RangeList(parent=self, calculator=self.calculator, appSettings=self.appSettings, title="Post-fit Analysis", withBtn=False, nestedItems=False) self.modelWidget.setStatsWidget(self.statsWidget) self.modelWidget.sigBackendUpdated.connect( self.statsWidget.updateHistograms) return self.statsWidget def _setupLogWidget(self): """Set up widget for logging output.""" logDock = DockWidget(self, LogWidget, appversion=version) logWidget = logDock.child self.onCloseSignal.connect(logWidget.onCloseSlot) logWidget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) logWidget.append(INFOTEXT) if len(CHANGESTEXT): logWidget.append(CHANGESTEXT) logWidget.append("\n\r") self.logWidget = logWidget return logDock def _setupStartButton(self): """Set up "Start/Stop" - button.""" self.startStopBtn = QPushButton() self.startStopBtn.setCheckable(True) self.startStopBtn.clicked[bool].connect(self.onStartStopClick) btnLayout = QHBoxLayout() btnLayout.setContentsMargins(0, 0, 0, 0) self.startStopBtn.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) btnLayout.addWidget(self.startStopBtn) btnWidget = QWidget(self) btnWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) btnWidget.setLayout(btnLayout) return btnWidget def restoreSettings(self): MainWindowBase.restoreSettings(self) for settingsWidget in (self.optimWidget, self.modelWidget): # no self.dataWidget, it is restored on demand internally settingsWidget.restoreSession() if self.appSettings is None: return try: value = str(self.appSettings.value("lastpath").toString()) except AttributeError: # QVariant value = str(self.appSettings.value("lastpath")) if os.path.isdir(value): LastPath.set(value) def storeSettings(self): MainWindowBase.storeSettings(self) for settingsWidget in (self.optimWidget, self.modelWidget, self.dataWidget): settingsWidget.storeSession() if self.appSettings is not None: self.appSettings.setValue("lastpath", LastPath.get()) self.appSettings.sync() return # test for additionally storing settings to file tempSettings = QSettings("/tmp/qsettings.test", QSettings.IniFormat) for key in self.appSettings.allKeys(): if key in ('geometry', 'windowState', 'lastpath'): continue tempSettings.setValue(key, self.appSettings.value(key)) tempSettings.sync() def fileDialog(self): filenames = getOpenFiles(self, "Load one or more data files", LastPath.get(), multiple=True) self.loadFiles(filenames) def initUi(self): self.logWidget.scrollToTop() self.fileWidget.loadData(getattr(self._args, "fnames", [])) self.onStartStopClick(getattr(self._args, "start", False)) def _updateWidgetsFinally(self): for w in self.findChildren(AlgorithmWidget): w.updateAll() if (not len(self.statsWidget.data()) and len(self.modelWidget.model.activeParams())): # make sure there is an histogram range defined, # otherwise ask the user for one self.toolbox.setCurrentWidget(self.statsWidget) self.statsWidget.loadData() def onStartStopClick(self, checked): processEventLoop() if checked: # # write HDF datafile # self.hdfStore("test3.h5") self.startStopBtn.setText("stop") self.startStopBtn.setChecked(True) self._updateWidgetsFinally( ) # get latest input in case sth didn't update self.calc() # run this also for 'start' after calculation self.calculator.stop() self.startStopBtn.setText("start") self.startStopBtn.setChecked(False) # def hdfWrite(self, hdf): # hdf.writeMember(self, "calculator") def calc(self): if len(self.fileWidget) <= 0: return self.logWidget.clear() self.logWidget.scrollToBottom() idx, data = self.fileWidget.currentSelection() # process the selected data only if there is a selection selectedOnly = data is not None self.calculator.prepare() self.fileWidget.updateData(updateFunc=self.calculator, stopFunc=self.calculator.isStopped, selectedOnly=selectedOnly, showProgress=False) self.calculator.postProcess() def closeEvent(self, closeEvent): super(MainWindow, self).closeEvent(closeEvent) self.onStartStopClick(False) self.onCloseSignal.emit() def keyPressEvent(self, keyEvent): if keyEvent.key() == Qt.Key_Escape and self.startStopBtn.isChecked(): self.onStartStopClick(False) # hit 'stop' logging.info("Calculation aborted by user interupt!")
class DataList(QWidget, DropWidget, ContextMenuWidget): """ Manages all loaded spectra. >>> from utilsgui import DialogInteraction, DisplayException >>> from spectralist import SpectraList >>> sl = DialogInteraction.instance(SpectraList) Test available actions >>> [str(action.text()) for action in sl.listWidget.actions()] ['load spectra', 'remove', '', 'save matrices', 'select all'] >>> sl.listWidget.count() 0 Test methods on empty list >>> sl.updateSpectra() >>> sl.removeSelectedSpectra() >>> [sl.getMatrix(i) for i in -1,0,1] [None, None, None] >>> DialogInteraction.query(DisplayException, sl.saveMatrix, ... slot = 'accept') >>> sl.selectionChangedSlot() """ sigSelectedData = Signal((object,)) sigUpdatedData = Signal((object,)) sigRemovedData = Signal(list) sigEmpty = Signal() sigReceivedUrls = Signal(list) sigEditingFinished = Signal() _nestedItems = None # are nested items allowed? (plain list behaviour) def __init__(self, parent = None, title = None, withBtn = True, nestedItems = True): QWidget.__init__(self, parent) ContextMenuWidget.__init__(self) self.title = TitleHandler.setup(self, title) self._nestedItems = nestedItems self._setupUi(withBtn) self._setupActions() self.setupUi() QMetaObject.connectSlotsByName(self) def _setupUi(self, withBtn): self.setObjectName("DataList") self.setAcceptDrops(True) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setObjectName("verticalLayout") if withBtn: self.loadBtn = QPushButton(self) self.loadBtn.setText(tr("load")) self.loadBtn.setObjectName("loadBtn") self.loadBtn.released.connect(self.loadData) self.verticalLayout.addWidget(self.loadBtn) self.listWidget = QTreeWidget(self) self.listWidget.setHeaderHidden(True) self.listWidget.setContextMenuPolicy(Qt.ActionsContextMenu) self.listWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.listWidget.setDragEnabled(True) self.listWidget.setDragDropMode(QAbstractItemView.InternalMove) self.listWidget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.listWidget.setObjectName("listWidget") self.listWidget.itemSelectionChanged.connect(self.selectionChanged) self.listWidget.itemClicked.connect(self._itemClicked) self.listWidget.itemChanged.connect(self._itemChanged) self.listWidget.itemDoubleClicked.connect(self.itemDoubleClicked) self.listWidget.itemExpanded.connect(self.fitColumnsToContents) self.listWidget.itemCollapsed.connect(self.fitColumnsToContents) self.verticalLayout.addWidget(self.listWidget) self.sigReceivedUrls.connect(self.loadData) self.clearSelection = self.listWidget.clearSelection def _setupActions(self): self.addMenuEntry( name = "load", text = tr("load %1"), menuStates = "*", toolTip = tr("Add one or more %1."), callbacks = self.loadData) self.addMenuSeparator() self.addMenuEntry( name = "remove", text = tr("remove"), toolTip = tr("Remove selected %1."), shortCut = QKeySequence.Delete, menuStates = "isRemovableSelected", callbacks = self.removeSelected) self.addMenuSeparator("hasSelection") self.addMenuSeparator("isNotEmpty") self.addMenuEntry( name = "selectall", text = tr("select all"), shortCut = QKeySequence.SelectAll, menuStates = "isNotEmpty", callbacks = self.selectAll) self.addMenuEntry( name = "expandall", text = tr("expand all"), toolTip = tr("Show nested items of this %1. (double-click)"), callbacks = self.expandAll, menuStates = "itemsHaveChildren") self._updateContextMenu() def _updateContextMenu(self): self.updateMenu(self.listWidget) def fitColumnsToContents(self, *args): for c in range(0, self.listWidget.columnCount()): self.listWidget.resizeColumnToContents(c) def setupUi(self): """Reimplement this in child classes for custom UI configuration.""" pass def leaveEvent(self, event): self.sigEditingFinished.emit() def clear(self): self.listWidget.clear() def selectAll(self): """Selects all items in the list if not all are selected. Clears the selection if all items in the list already are selected. """ if (old_div(len(self.listWidget.selectedIndexes()), self.listWidget.columnCount())) == len(self): self.listWidget.clearSelection() else: self.listWidget.selectAll() def expandAll(self): self.listWidget.expandAll() self.fitColumnsToContents() def __len__(self): return self.listWidget.topLevelItemCount() def isEmpty(self): return len(self) <= 0 def isNotEmpty(self): return not self.isEmpty() def hasSelection(self): return len(self.listWidget.selectedItems()) > 0 def isRemovableSelected(self): """True, if there is at least one item selected which may be removed""" return self.hasSelection() def itemsHaveChildren(self): return any([item.childCount() > 0 for item in self.topLevelItems()]) def setHeader(self, labels = None): if not isList(labels): return self.listWidget.setHeaderLabels(labels) self.listWidget.setHeaderHidden(False) self.listWidget.setColumnCount(len(labels)) def updateItems(self): for item in self.topLevelItems(): item.update() self.fitColumnsToContents() def _itemClicked(self, item, column): item.setClicked(column) if item.wasClickedAndChanged(): self.itemUpdate(item, column) def _itemChanged(self, item, column): item.setChanged(column) if item.wasClickedAndChanged(): self.itemUpdate(item, column) def itemUpdate(self, item, column): """Reimplement to update item if changed by user in GUI""" pass def itemDoubleClicked(self, item, column): pass def currentSelection(self): selected = self.listWidget.selectedItems() index, data = -1, None if len(selected) > 0: index = selected[0].listIndex() data = selected[0].data() return index, data def selectionChanged(self): index, data = self.currentSelection() self.sigSelectedData.emit(data) self._updateContextMenu() if self.isEmpty(): self.sigEmpty.emit() def removeItems(self, indexList): """Deletes items specified in the given list of indices.""" if not isList(indexList) or not len(indexList): return removedItems = [] for i in reversed(sorted(indexList)): item = self.listWidget.topLevelItem(i) if not item.isRemovable: continue item.remove() removedItems.append(item.data()) self.sigRemovedData.emit(removedItems) self.selectionChanged() def removeSelected(self): selected = self.listWidget.selectedItems() index = 0 self.sigRemovedData.emit(self.data(selected)) for item in selected: if not item.isRemovable: continue index = item.listIndex() item.remove() # select the next item after the removed ones self.listWidget.clearSelection() if index >= len(self): index = len(self) - 1 if index >= 0: self.listWidget.setCurrentIndex( self.listWidget.indexFromItem( self.listWidget.topLevelItem(index))) self.selectionChanged() def setCurrentIndex(self, index): if index < 0 or index >= len(self): return item = self.listWidget.topLevelItem(index) index = self.listWidget.indexFromItem(item) self.listWidget.setCurrentIndex(index) self.selectionChanged() def add(self, data): if self.isEmpty(): self.setHeader(data.displayDataDescr) DataItem(data) # WTF? w/o it returns QTreeWidgetItem instead of DataItem below! self.listWidget.addTopLevelItem(DataItem(data)) item = self.listWidget.topLevelItem(len(self)-1) if not self._nestedItems: item.setFlags(int(item.flags()) - int(Qt.ItemIsDropEnabled)) return item def topLevelItems(self): return [self.listWidget.topLevelItem(i) for i in range(0, len(self))] def data(self, indexOrItem = None, selectedOnly = False): """ Returns the list of data for a given list index or list widget item. If none is specified return the data of all items or the data of selected items only, if desired. """ if type(indexOrItem) is int: if indexOrItem < 0 or indexOrItem >= len(self): raise IndexError items = [self.listWidget.topLevelItem(indexOrItem)] elif type(indexOrItem) is DataItem: items = [indexOrItem] elif (isList(indexOrItem) and len(indexOrItem) > 0 and type(indexOrItem[0]) is DataItem): items = indexOrItem else: # no indexOrItem given if selectedOnly: items = self.listWidget.selectedItems() else: items = self.topLevelItems() return [item.data() for item in items] def updateData(self, selectedOnly = False, showProgress = True, updateFunc = None, prepareFunc = None, stopFunc = None, **kwargs): """ Calls the provided function on all data items. The object returned by prepareFunc() is forwarded as optional argument to updateFunc(dataItem, optionalArguments = None). """ data = self.data(selectedOnly = selectedOnly) if data is None or len(data) <= 0: self.sigUpdatedData.emit(None) return progress = None if showProgress: from gui.utils.progressdialog import ProgressDialog progress = ProgressDialog(self, count = len(data)) updateResult = [] # check provided stop function if (stopFunc is not None and not isinstance(stopFunc, collections.Callable)): stopFunc = None # call provided functions which can raise exceptions errorOccured = False # raise error after processing all items try: # call prepare function prepareResult = None if prepareFunc is not None: prepareResult = prepareFunc(**kwargs) if prepareResult is None: prepareResult = [] if not isList(prepareResult): prepareResult = [prepareResult,] # call update function on each data object for item in data: try: updateResult.append( updateFunc(item, *prepareResult, **kwargs)) if progress is not None and progress.update(): break if stopFunc is not None and stopFunc(): break except Exception as e: errorOccured = True import traceback logging.error(traceback.format_exc()) itemName = str(item) try: itemName = item.filename except AttributeError: pass logging.error("Skipping '{}'".format(itemName)) continue if progress is not None: progress.close() except Exception as e: # progress.cancel() # catch and display _all_ exceptions in user friendly manner # DisplayException(e) errorOccured = True import traceback logging.error(traceback.format_exc()) pass if errorOccured: self.reraiseLast() # self.selectionChanged() self.sigUpdatedData.emit(self.currentSelection()[1]) return updateResult def loadData(self, sourceList = None, processSourceFunc = None, showProgress = True, alignment = None, **kwargs): """ Loads a list of data source items. processSourceFunc is expected to be a function which gets individual elements of sourceList as argument. It returns an arbitrary data item which is then added to this data list widget. Reimplement it in child classes and it will be called on load button and add action signal. This method handles exceptions and progress indication. Test loading a single spectra >>> import utils >>> from tests import TestData >>> from utilsgui import DialogInteraction, UiSettings, fileDialogType >>> from chemsettings import ChemSettings >>> from datafiltersgui import DataFiltersGui >>> from spectralist import SpectraList >>> cs = DialogInteraction.instance(ChemSettings) >>> dfg = DialogInteraction.instance(DataFiltersGui) >>> sl = DialogInteraction.instance(SpectraList, settings = cs) >>> utils.LastPath.path = TestData.spectra(0) >>> DialogInteraction.query(fileDialogType(), sl.loadData, ... slot = 'accept') >>> sl.updateSpectra() >>> utils.LastPath.path = utils.getTempFileName() >>> matrixfiles = DialogInteraction.query(fileDialogType(), sl.saveMatrix, ... slot = 'accept') >>> len(matrixfiles) 1 >>> matrixfiles Verify written matrix data with existent matrix export >>> TestData.verifyMatrix(TestData.spectra(0), ... matrixfiles[0]) True """ assert processSourceFunc is not None assert isList(sourceList) progress = None if showProgress: from gui.utils.progressdialog import ProgressDialog progress = ProgressDialog(self, count = len(sourceList)) self.listWidget.clearSelection() errorOccured = False lastItem = None for sourceItem in sourceList: data = None try: data = processSourceFunc(sourceItem, **kwargs) except Exception as e: # progress.cancel() # DisplayException(e) # on error, skip the current file errorOccured = True logging.error(str(e).replace("\n"," ") + " ... skipping") continue if data is not None: lastItem = self.add(data) try: lastItem.setAlignment(alignment) # sometime PySide return a QTreeWidgetItem instead of a DataItem except AttributeError: pass if progress is not None and progress.update(): break if progress is not None: progress.close() self.fitColumnsToContents() # notify interested widgets about changes if lastItem is not None: self.listWidget.setCurrentItem(lastItem) if errorOccured: self.reraiseLast() def reraiseLast(self): """Reraise the last error if any and display an error message dialog. """ try: if sys.exc_info()[0] is not None: raise except Exception as e: DisplayException(e)