class ReportExportProgress(QObject): def __init__(self, name, eventCount, eventStart, eventFinish, child=None): QObject.__init__(self) self.name = name self.eventCount = eventCount self.eventStart = eventStart self.eventFinish = eventFinish self.child = child self.label = QLabel() self.label.setWordWrap(True) self.bar = QProgressBar() self.bar.setFormat(" %v/%m (%p%)") self.reset() def reset(self): self.title = "" self.current = 0 self.count = 0 def event(self, event): if event.type == self.eventStart: self.title = event.value.value() if self.child: self.child.reset() if event.type == self.eventFinish: self.current += 1 self.bar.setValue(self.current) if event.type == self.eventCount: self.count = event.value.value() self.bar.setValue(0) self.bar.setMaximum(self.count) self.label.setText( self.tr("Extraction ") + self.name + " : " + str(self.title))
class ReportExportProgressItems(QObject): def __init__(self): QObject.__init__(self) self.eventCount = ReportManager.EventExportItems self.eventFinish = [ ReportManager.EventExportCategoryFinish, ReportPage.EventExportFinish, ReportPageFragment.EventWriteFinish, ReportPageFragment.EventWriteElementFinish ] self.label = QLabel(self.tr("Extracting report")) self.bar = QProgressBar() self.bar.setFormat(" %v/%m (%p%)") self.reset() def reset(self): self.count = 0 self.current = 0 def event(self, event): if event.type == self.eventCount: self.count = event.value.value() self.bar.setValue(0) self.bar.setMaximum(self.count) if event.type in self.eventFinish: self.current += 1 self.bar.setValue(self.current)
class TrackProgressDialog(QDialog): finished = pyqtSignal() def __init__(self, parent=None, numStages=1): QDialog.__init__(self, parent) self.currentStep = 0 self.progress = None l = QVBoxLayout() self.setLayout(l) self.overallProgress = QProgressBar() self.overallProgress.setRange(0, numStages) self.overallProgress.setFormat("step %v of " + str(numStages)) self.currentStepProgress = QProgressBar() self.currentStepProgress.setRange(0, 100) self.currentStepProgress.setFormat("%p %") self.overallLabel = QLabel("Overall progress") self.currentStepLabel = QLabel("Current step") l.addWidget(self.overallLabel) l.addWidget(self.overallProgress) l.addWidget(self.currentStepLabel) l.addWidget(self.currentStepProgress) l.maximumSize() self.update() def __onNewStep(self, description): self.currentStep += 1 self.currentStepProgress.setValue(0) self.overallProgress.setValue(self.currentStep) self.currentStepLabel.setText(description) self.update() def __onCurrentStepProgressChanged(self, progress): timesHundred = round(1000.0 * progress) timesTen = round(100.0 * progress) if (not self.currentStepProgress.value() == timesTen) and (timesHundred - 10 * timesTen) == 0: self.currentStepProgress.setValue(timesTen) self.update() def run(self): self.trackProgress = TrackProgress(self) self.trackProgress.progress.connect( self.__onCurrentStepProgressChanged, Qt.BlockingQueuedConnection) self.trackProgress.newStep.connect(self.__onNewStep, Qt.BlockingQueuedConnection) self.trackProgress.done.connect(self.onTrackDone) self.trackProgress.start() def onTrackDone(self): self.trackProgress.wait( ) # Join the extractor thread so its safe to immediately destroy the window self.finished.emit() self.close()
class SeekOverlay(Overlay): def __init__(self, keyPressHandler, parent = None): Overlay.__init__(self, keyPressHandler, parent) self.setupUI() def setupUI(self): self.layout = QHBoxLayout(self) self.timeBar = QProgressBar() self.layout.addWidget(self.timeBar) def resizeEvent(self, event): textHeight = event.size().height() * .4 self.timeBar.setStyleSheet('QProgressBar {font-size: %dpt;}' % textHeight) def setTime(self, current, total): current = int(current) total = int(total) self.timeBar.setMaximum(total) self.timeBar.setValue(current) self.timeBar.setFormat(MPlayer.formatTime(current) + '/' + MPlayer.formatTime(total))
class BusyBar(QThread): """ Adapted from: http://stackoverflow.com/questions/8007602/ looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e Looping progress bar create the signal that the thread will emit .. note:: This function creates a busy bar but I have not figured out how to \ attach it to a process. Therefore, it is currently functionally \ useless. """ changeValue = pyqtSignal(int) def __init__(self, text=""): QThread.__init__(self, parent=None) self.text = text self.stop = False self.proBar = QProgressBar() self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) self.proBar.setRange(0, 100) self.proBar.setTextVisible(True) self.proBar.setFormat(self.text) self.proBar.setValue(0) self.proBar.setFixedSize(300, 40) self.proBar.setAlignment(Qt.AlignCenter) self.proBar.show() #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) # Make the Busybar delete itself and the QProgressBar when done self.finished.connect(self.onFinished) def run(self): """ """ while not self.stop: # keep looping while self is visible # Loop sending mail for i in range(100): # emit the signal instead of calling setValue # also we can't read the progress bar value from the thread self.changeValue.emit(i) time.sleep(0.01) self.changeValue.emit(0) def onFinished(self): """ """ self.proBar.deleteLater() self.deleteLater() def Kill(self): """ """ self.stop = True
class BusyBar(QThread): """ Adapted from: http://stackoverflow.com/questions/8007602/ looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e Looping progress bar create the signal that the thread will emit .. note:: This function creates a busy bar but I have not figured out how to \ attach it to a process. Therefore, it is currently functionally \ useless. """ changeValue = pyqtSignal(int) def __init__(self, text = "" ): QThread.__init__(self, parent = None) self.text = text self.stop = False self.proBar = QProgressBar() self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen ) self.proBar.setRange( 0, 100 ) self.proBar.setTextVisible( True ) self.proBar.setFormat( self.text ) self.proBar.setValue( 0 ) self.proBar.setFixedSize( 300 , 40 ) self.proBar.setAlignment(Qt.AlignCenter) self.proBar.show() #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) # Make the Busybar delete itself and the QProgressBar when done self.finished.connect(self.onFinished) def run(self): """ """ while not self.stop: # keep looping while self is visible # Loop sending mail for i in range(100): # emit the signal instead of calling setValue # also we can't read the progress bar value from the thread self.changeValue.emit( i ) time.sleep(0.01) self.changeValue.emit( 0 ) def onFinished(self): """ """ self.proBar.deleteLater() self.deleteLater() def Kill(self): """ """ self.stop = True
class ProgressView(QWidget): def __init__(self, parent=None): super(ProgressView, self).__init__(parent) self._progressBar = QProgressBar() layout = QVBoxLayout(self) layout.addWidget(self._progressBar) def setRunner(self, runner): self.show() self._progressBar.setMaximum(0) runner.progress.connect(self._showProgress) runner.done.connect(self.hide) def _showProgress(self, dct): step = dct['step'] if step in ('install', 'remove'): self._progressBar.setMaximum(100) self._progressBar.setValue(dct['percent']) if step == 'install': self._progressBar.setFormat(i18n('Installing... %p%')) else: self._progressBar.setFormat(i18n('Removing... %p%')) elif step == 'acquire': fetched = dct['fetched_bytes'] total = dct['total_bytes'] self._progressBar.setMaximum(total) self._progressBar.setValue(fetched) locale = KGlobal.locale() self._progressBar.setFormat(i18n('Downloading... %1 / %2', locale.formatByteSize(fetched), locale.formatByteSize(total) ))
class ExpandingProgressDialog(QProgressDialog): def __init__(self, parent=None): QProgressDialog.__init__(self, parent) self.progress = QProgressBar(self) self.progress.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setBar(self.progress) def set_progress_text_visible(self, visible): self.progress.setTextVisible(visible) def set_progress_text(self, text): self.progress.setFormat(text) # overrides QProgressDialog.sizeHint def sizeHint(self): size = QProgressDialog.sizeHint(self) if size.width() < 400: size.setWidth(400) return size
class InputForm(QWidget): __instance = None @staticmethod def instance(): return InputForm.__instance def __init__(self): if not InputForm.__instance: InputForm.__instance = self super(InputForm, self).__init__() Global.event.task_started.connect(self._on_task_started) Global.event.task_completed.connect(self._on_task_completed) Global.event.task_progressed.connect(self._on_task_progressed) Global.event.task_range_progressed.connect(self._on_task_range_progressed) Global.event.interface_load_task_params.connect(self._on_interface_load_task_params) self.vl = QVBoxLayout() self.vl.setContentsMargins(0,0,0,0) self.setLayout(self.vl) self.setFixedWidth(290) self.tab = QTabWidget() self.vl.addWidget(self.tab) self.input_parameters = InputParameters() self.input_parameters.ranges_state_changed.connect(self._on_ranges_state_changed) self.tab.addTab(self.input_parameters, 'Parameters') self.import_parameters = ImportParameters() self.tab.addTab(self.import_parameters, 'Observation') control_buttons = QWidget() control_buttons.setLayout(QVBoxLayout()) control_buttons.layout().setContentsMargins(0, 0, 0, 0) control_buttons.layout().setAlignment(Qt.AlignBottom) self._progress = QProgressBar() self._progress.setValue(0) self._progress.setTextVisible(True) self._progress.setAlignment(Qt.AlignCenter) self._progress.hide() control_buttons.layout().addWidget(self._progress) self._range_progress = QProgressBar() self._range_progress.setValue(0) self._range_progress.setTextVisible(True) self._range_progress.setAlignment(Qt.AlignCenter) self._range_progress.hide() control_buttons.layout().addWidget(self._range_progress) self._calculate = QPushButton('Calculate') self._calculate.clicked.connect(self._on_calculate) control_buttons.layout().addWidget(self._calculate) self._cancel = QPushButton('Cancel') self._cancel.hide() self._cancel.clicked.connect(self._on_cancel) control_buttons.layout().addWidget(self._cancel) self.vl.addWidget(control_buttons) if exists("./config/last-session.ini") : self.load_params("./config/last-session.ini") def _on_ranges_state_changed(self, parameters): Global.task_range().reset() if len(parameters): keys = parameters.keys() for key in parameters: Global.task_range().set_range(key, copy(parameters[key].range.values)) self._calculate.setText('Calculate ' + str(Global.task_range()._total_count) + ' variations') else: self._calculate.setText('Calculate') def _on_calculate(self): self.import_parameters.import_observation() combination = Global.task_range().get_next_combination() Global.task().input.semi_major_axis = self.input_parameters.semi_major_axis.getValue() Global.task().input.star_radius = self.input_parameters.star_radius.getValue() Global.task().input.planet_radius = self.input_parameters.planet_radius.getValue() Global.task().input.star_temperature = self.input_parameters.star_temperature.getValue() Global.task().input.planet_temperature = self.input_parameters.planet_temperature.getValue() Global.task().input.darkening_law = self.input_parameters.darkening_law.value.itemData(self.input_parameters.darkening_law.value.currentIndex()).toString() Global.task().input.darkening_1 = self.input_parameters.darkening_coefficient_1.getValue() Global.task().input.darkening_2 = self.input_parameters.darkening_coefficient_2.getValue() Global.task().input.inclination = self.input_parameters.inclination.getValue() Global.task().input.phase_start = 0 Global.task().input.phase_end = self.input_parameters.phase_end.getValue() Global.task().input.phase_step = self.input_parameters.phase_step.getValue() Global.task().input.precision = 10**self.input_parameters.integration_precision.getValue() if combination: for param in combination: setattr(Global.task().input, param[0], param[1]) Global.task().start() def _on_task_range_progressed(self, progress): self._range_progress.setFormat( str(Global.task_range().completed_count()) + ' of ' + str(Global.task_range().total_count())) self._range_progress.setValue(math.ceil(((float(Global.task_range().completed_count()))/Global.task_range().total_count())*100)) self._on_calculate() def _on_task_started(self, task): self._calculate.hide() self._progress.show() self._progress.setValue(0) self._cancel.show() self.tab.setDisabled(True) if Global.task_range().total_count(): self._range_progress.show() if Global.task_range().completed_count() == 0: self._range_progress.setFormat('0 of ' + str(Global.task_range().total_count())) self._range_progress.setValue(0) def _on_task_progressed(self, task, progress): self._progress.setValue(progress) def _on_task_completed(self, task): if Global.task_range().total_count() and Global.task_range().completed_count(): return self._calculate.show() self._progress.hide() self._progress.setValue(0) self._cancel.hide() self.tab.setDisabled(False) self._range_progress.hide() self._range_progress.setValue(0) def _on_cancel(self): Global.task().stop() self._calculate.show() self._progress.hide() self._progress.setValue(0) self._range_progress.hide() self._range_progress.setValue(0) self._cancel.hide() self.tab.setDisabled(False) def _on_interface_load_task_params(self, task): self.input_parameters.semi_major_axis.value.setValue(task.input.semi_major_axis) self.input_parameters.star_radius.value.setValue(task.input.star_radius) self.input_parameters.planet_radius.value.setValue(task.input.planet_radius) self.input_parameters.star_temperature.value.setValue(task.input.star_temperature) self.input_parameters.planet_temperature.value.setValue(task.input.planet_temperature) self.input_parameters.inclination.value.setValue(task.input.inclination) darkening_law_index = 0 for item in DarkeningLaw.items: if item[1] == task.input.darkening_law: break darkening_law_index += 1 self.input_parameters.darkening_law.value.setCurrentIndex(darkening_law_index) self.input_parameters.darkening_coefficient_1.value.setValue(task.input.darkening_1) self.input_parameters.darkening_coefficient_2.value.setValue(task.input.darkening_2) self.input_parameters.phase_end.value.setValue(task.input.phase_end) self.input_parameters.phase_step.value.setValue(task.input.phase_step) self.input_parameters.integration_precision.value.setValue(log10(task.input.precision)) for parameter_name in copy(self.input_parameters.range_parameters): parameter = getattr(self.input_parameters, parameter_name) if parameter.range: parameter.range.set_active(False) self.repaint() def load_params(self, filename): config = ConfigParser() config.read(filename) self._normalize_config(config) # Input Parameters self._load_config_param(config, 'input', 'semi_major_axis') self._load_config_param(config, 'input', 'star_radius') self._load_config_param(config, 'input', 'planet_radius') self._load_config_param(config, 'input', 'star_temperature') self._load_config_param(config, 'input', 'planet_temperature') self._load_config_param(config, 'input', 'inclination') self._load_config_param(config, 'input', 'darkening_law') self._load_config_param(config, 'input', 'darkening_coefficient_1') self._load_config_param(config, 'input', 'darkening_coefficient_2') self._load_config_param(config, 'input', 'phase_end') self._load_config_param(config, 'input', 'phase_step') self._load_config_param(config, 'input', 'integration_precision') # Import Parameters if config.has_option('import', 'filename') and config.get('import', 'filename'): if '/data/' in config.get('import', 'filename') and config.get('import', 'filename').index('/data/') == 0: self.import_parameters.filename = os.getcwd().replace('\\', '/') + config.get('import', 'filename') else: self.import_parameters.filename = config.get('import', 'filename') self.import_parameters.update_file_label() if config.has_option('import', 'jd2phase') and config.getboolean('import', 'jd2phase') == True : self.import_parameters.hjd_to_phases.setCheckState(Qt.Checked) if config.has_option('import', 'jd2phase_tzero') : self.import_parameters.time_zero.setValue(config.getfloat('import', 'jd2phase_tzero')) if config.has_option('import', 'jd2phase_period') : self.import_parameters.period.setValue(config.getfloat('import', 'jd2phase_period')) if config.has_option('import', 'mag2flux') and config.getboolean('import', 'mag2flux') == True : self.import_parameters.magnitude_to_flux.setCheckState(Qt.Checked) if config.has_option('import', 'mag2flux_mag') : self.import_parameters.magnitude_max.setValue(config.getfloat('import', 'mag2flux_mag')) # Fixes painting bug with range buttons when loading new file # the active ranges stayed active even if they are inactive self.repaint() def _normalize_config(self, config): if config.has_option('input', 'darkening_1'): config.set('input', 'darkening_coefficient_1', config.get('input', 'darkening_1')) config.remove_option('input', 'darkening_1') if config.has_option('input', 'darkening_2'): config.set('input', 'darkening_coefficient_2', config.get('input', 'darkening_2')) config.remove_option('input', 'darkening_2') if config.has_option('input', 'precision'): config.set('input', 'integration_precision', config.get('input', 'precision')) config.remove_option('input', 'precision') def _load_config_param(self, config, section, name): param = getattr(self.input_parameters, name) if config.has_option(section, name): if type(param.value) is QComboBox: param.value.setCurrentIndex(config.getint(section, name)) else: param.value.setValue(literal_eval(config.get(section, name))) if param.range: _from = _to = _step = _values = None _active = False if config.has_option(section, name + '_range_from'): _from = literal_eval(config.get(section, name + '_range_from')) if config.has_option(section, name + '_range_to'): _to = literal_eval(config.get(section, name + '_range_to')) if config.has_option(section, name + '_range_step'): _step = literal_eval(config.get(section, name + '_range_step')) if config.has_option(section, name + '_range_values'): _values = literal_eval(config.get(section, name + '_range_values')) if config.has_option(section, name + '_range_active'): _active = config.getboolean(section, name + '_range_active') if _values: param.range.set_range(_values) elif _from and _to and _step: param.range.set_range(_from, _to, _step) param.range.set_active(_active) def _save_config_param(self, config, section, name): param = getattr(self.input_parameters, name) if type(param.value) is QComboBox: config.set(section, name, param.value.currentIndex()) else: config.set(section, name, param.getValue()) if param.range: if param.range.range_from and param.range.range_to and param.range.range_step: config.set(section, name + '_range_from', param.range.range_from) config.set(section, name + '_range_to', param.range.range_to) config.set(section, name + '_range_step', param.range.range_step) elif param.range.values: config.set(section, name + '_range_values', param.range.values) if param.range.is_active(): config.set(section, name + '_range_active', param.range.is_active()) def save_params(self, filename): config = ConfigParser() config.add_section('input') # Input Parameters self._save_config_param(config, 'input', 'semi_major_axis') self._save_config_param(config, 'input', 'star_radius') self._save_config_param(config, 'input', 'planet_radius') self._save_config_param(config, 'input', 'star_temperature') self._save_config_param(config, 'input', 'planet_temperature') self._save_config_param(config, 'input', 'inclination') self._save_config_param(config, 'input', 'darkening_law') self._save_config_param(config, 'input', 'darkening_coefficient_1') self._save_config_param(config, 'input', 'darkening_coefficient_2') self._save_config_param(config, 'input', 'phase_end') self._save_config_param(config, 'input', 'phase_step') self._save_config_param(config, 'input', 'integration_precision') config.add_section('import') if os.getcwd().replace('\\', '/') in str(self.import_parameters.filename) and str(self.import_parameters.filename).index(os.getcwd().replace('\\', '/')) == 0 : save_file_path = str(self.import_parameters.filename).replace(os.getcwd().replace('\\', '/'), '') else: save_file_path = str(self.import_parameters.filename) config.set('import', 'filename', save_file_path) config.set('import', 'jd2phase', self.import_parameters.hjd_to_phases.checkState() == Qt.Checked) config.set('import', 'jd2phase_tzero', self.import_parameters.time_zero.value()) config.set('import', 'jd2phase_period', self.import_parameters.period.value()) config.set('import', 'mag2flux', self.import_parameters.magnitude_to_flux.checkState() == Qt.Checked) config.set('import', 'mag2flux_mag', self.import_parameters.magnitude_max.value()) with open(filename, 'wb') as configfile: config.write(configfile) pass
class UploadDialog(QDialog): def __init__(self, tracks, device_info=None, username=None, password=None, auth_token=None, parent=None): super(UploadDialog, self).__init__(parent) self.tracks = tracks self.username = username self.password = password self._first_auth = True self.total_progress = QProgressBar(self) self.total_progress.setRange(0, len(tracks)) self.total_progress.setValue(0) self.total_progress.setFormat('%v of %m tracks uploaded') self.item_progress = QProgressBar(self) self.item_progress.setRange(0, 100) self.item_progress.setValue(0) self.item_progress.setFormat('%p%') self.buttons = QDialogButtonBox(QDialogButtonBox.Cancel) self.buttons.rejected.connect(self.reject) self.status_msg = QLabel('Starting upload', self) self.setWindowTitle('Uploading') self._createLayout() self.upload = StravaUpload(tracks, device_info=device_info, parent=self, auth_token=auth_token) self.upload.authNeeded.connect(self._onAuthNeeded) self.upload.itemProgress.connect(self.item_progress.setValue) self.upload.totalProgress.connect(self.total_progress.setValue) self.upload.statusMessage.connect(self.status_msg.setText) self.upload.finished.connect(self._onFinished) self.rejected.connect(self._onCanceled) QTimer.singleShot(100, self.upload.start) def _createLayout(self): l = QVBoxLayout() l.addWidget(self.status_msg) l.addWidget(self.item_progress) l.addWidget(self.total_progress) l.addWidget(self.buttons) self.setLayout(l) def _onAuthNeeded(self): if self._first_auth and self.username is not None and self.password is not None: self._first_auth = False self.upload.authenticate(self.username, self.password) return d = AuthDialog(self) if d.exec_() == QDialog.Accepted: u, p = d.getValues() self.upload.authenticate(u, p) else: log.debug('Auth dialog rejected') self._onCanceled() def _onFinished(self): res = self.upload.results if len(res) != len(self.tracks): res.extend([{'status' : 'ERROR', 'msg' : 'Canceled'}] * (len(self.tracks) - len(res))) log.debug('Upload finished') d = ResultDialog(zip(self.tracks, res), self) d.exec_() self.accept() def _onCanceled(self): log.debug('Upload canceled') self.upload.cancel() self._onFinished()
class SoilErosionDockWidget(QtGui.QDockWidget, FORM_CLASS): closingPlugin = pyqtSignal() def __init__(self, parent=None): """Constructor.""" super(SoilErosionDockWidget, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.settings = QSettings("CTU", "Soil_Erosion_Plugin") self.iface = iface # Define first computation, no results in map window self._first_computation = True # Read code tables self._factors = {} self._readFactorCodes() # Fill C combobox self.combobox_c.clear() list = self._factors['C'].list() self.combobox_c.addItems(list) # Set filters for QgsMapLayerComboBoxes self.shp_box_euc.setFilters(QgsMapLayerProxyModel.PolygonLayer) self.load_shp_euc.clicked.connect(self.onLoadShapefile) self.raster_box.setFilters(QgsMapLayerProxyModel.RasterLayer) self.load_raster.clicked.connect(self.onLoadRaster) self.shp_box_bpej.setFilters(QgsMapLayerProxyModel.PolygonLayer) self.load_shp_bpej.clicked.connect(self.onLoadShapefile) self.shp_box_lpis.setFilters(QgsMapLayerProxyModel.PolygonLayer) self.load_lpis.clicked.connect(self.onLoadShapefile) # Set functions for buttons self.compute_k_button.clicked.connect(self.onAddKFactor) self.compute_c_button.clicked.connect(self.onAddCFactor) self.set_button.clicked.connect(self.onCompute) def closeEvent(self, event): self.closingPlugin.emit() event.accept() def onLoadRaster(self): """Open 'Add raster layer dialog'.""" sender = '{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') fileName = QFileDialog.getOpenFileName(self,self.tr(u'Open Raster'), u'{}'.format(lastUsedFilePath), QgsProviderRegistry.instance().fileRasterFilters()) if fileName: self.iface.addRasterLayer(fileName, QFileInfo(fileName).baseName()) self.settings.setValue(sender, os.path.dirname(fileName)) def onLoadShapefile(self): """Open 'Add shapefile layer dialog'.""" sender = '{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') fileName = QFileDialog.getOpenFileName(self,self.tr(u'Open Shapefile'), u'{}'.format(lastUsedFilePath), QgsProviderRegistry.instance().fileVectorFilters()) if fileName: self.iface.addVectorLayer(fileName, QFileInfo(fileName).baseName(), "ogr") self.settings.setValue(sender, os.path.dirname(fileName)) def onAddKFactor(self): bpej_layer = self.shp_box_bpej.currentLayer() bpej_error = self.tr(u'layer must contain field \'BPEJ\'(format:\'X.XX.XX\' or value \'99\' for NoData)') try: if bpej_layer is None: self.showError(self.tr(u'You have to choose or load BPEJ layer.\n This ') + bpej_error) return elif bpej_layer.fieldNameIndex('BPEJ') == -1: self.showError(self.tr(u'BPEJ ') + bpej_error) return else: bpej_layer.startEditing() self._addColumn(bpej_layer, 'K') bpej_layer.commitChanges() except: bpej_layer.rollBack() self.showError(self.tr(u'Error during add \'K\' field, please check BPEJ layer.')) try: bpej_layer.startEditing() idx = bpej_layer.fieldNameIndex('BPEJ') for feature in bpej_layer.getFeatures(): bpej = feature.attributes()[idx] fid = feature.id() if bpej == '99': k_value = None else: k_value = self._factors['K'].value(bpej[2] + bpej[3]) self.setFieldValue(bpej_layer, 'K', k_value, fid) bpej_layer.commitChanges() self.setBpejStyle(bpej_layer) self.iface.messageBar().pushMessage(self.tr('Soil Erosion Plugin'), self.tr('K factor is computed!')) except: bpej_layer.rollBack() self.showError(self.tr(u'BPEJ ') + bpej_error) return def onAddCFactor(self): lpis_layer = self.shp_box_lpis.currentLayer() lpis_error = self.tr(u'layer must contain field \'KULTURAKOD\'\nwith allowed codes for land:\n R - Arable land\n' \ u' T - Permanent grassland\n S - Orchard\n L - Forest\n V - Vineyard\n C - Hop-garden\n' \ u'At least one feature must have code \'R\'!') if lpis_layer is None: self.showError(self.tr(u'You have to choose or load LPIS layer.\nThis ') + lpis_error) return elif lpis_layer.fieldNameIndex('KULTURAKOD') == -1: self.showError(self.tr(u'LPIS ') + lpis_error) return else: lpis_layer.startEditing() self._addColumn(lpis_layer, 'C') lpis_layer.commitChanges() try: self.setLpisStyle(lpis_layer) lpis_layer.startEditing() combobox_value = self.combobox_c.currentText() idx = lpis_layer.fieldNameIndex('KULTURAKOD') for feature in lpis_layer.getFeatures(): lpis = feature.attributes()[idx] fid = feature.id() if lpis == 'T': c_value = 0.005 elif lpis == 'S': c_value = 0.45 elif lpis == 'L': c_value = 0.003 elif lpis == 'V': c_value = 0.85 elif lpis == 'C': c_value = 0.8 elif lpis == 'R': c_value = self._factors['C'].value(combobox_value) self.setFieldValue(lpis_layer, 'C', c_value, fid) lpis_layer.commitChanges() self.iface.messageBar().pushMessage(self.tr('Soil Erosion Plugin'), self.tr('C factor is computed!')) except: lpis_layer.rollBack() self.showError(self.tr(u'LPIS ') + lpis_error) return def setFieldValue(self, euc_layer, field_name, value, fid=None): index = euc_layer.dataProvider().fieldNameIndex(field_name) if fid is None: for feature in euc_layer.getFeatures(): fid = feature.id() euc_layer.changeAttributeValue(fid, index, value) else: euc_layer.changeAttributeValue(fid, index, value) def _readFactorCodes(self): for fact in ('K','C'): filename = os.path.join(os.path.dirname(__file__), 'code_tables', fact + '_factor.csv') self._factors[fact] = ReadCSV(filename) def _addColumn(self, layer, name): for field in layer.pendingFields(): if field.name() == name: return # column does not exists # TODO # caps & QgsVectorDataProvider.AddAttributes): layer.dataProvider().addAttributes( [QgsField(name, QVariant.Double)] ) # def onIntersectLayers(self): # euc_layer = self.shp_box_euc.currentLayer() # bpej_layer = self.shp_box_bpej.currentLayer() # analyzer = QgsOverlayAnalyzer() # analyzer.intersection(euc_layer, bpej_layer, os.path.join(os.path.dirname(__file__), 'intersect.shp'), False, None) def onCompute(self): if hasattr(self, "computeThread"): return # remove results from map window, if it is not first computation if self._first_computation == False: try: QgsMapLayerRegistry.instance().removeMapLayer(self._se_layer.id()) for field in self._euc_vector.pendingFields(): if field.name() == 'G': field_id = self._euc_vector.fieldNameIndex(field.name()) fList = list() fList.append(field_id) self._euc_vector.dataProvider().deleteAttributes(fList) QgsMapLayerRegistry.instance().removeMapLayer(self._euc_vector.id()) except: self.showError(self.tr(u'Error during deleting layers from previous computation.')) return # find input layers euc_layer = self.shp_box_euc.currentLayer() dmt_layer = self.raster_box.currentLayer() bpej_layer = self.shp_box_bpej.currentLayer() lpis_layer = self.shp_box_lpis.currentLayer() # check fields self._cancel = False self.checkField('BPEJ', bpej_layer, 'K') if self._cancel == True: return self.checkField('LPIS', lpis_layer, 'C') if self._cancel == True: return # check crs of input layers euc_crs = euc_layer.crs().authid() dmt_crs = dmt_layer.crs().authid() bpej_crs = bpej_layer.crs().authid() lpis_crs = lpis_layer.crs().authid() if euc_crs == dmt_crs == bpej_crs == lpis_crs: if not int(euc_crs[5:]) >= 100000: epsg = int(euc_crs[5:]) else: self.showError(self.tr(u'It\'s not allow compute in own projection!\n\nSet CRS of'\ u' input layers: {}\n\nPlease change CRS of input layers to EPSG Code.').format(euc_crs)) return else: self.showError(self.tr(u'All inputs have to be at the same projection!\nEUC: {}\nDMT: {}\nBPEJ: {}\nLPIS: {}\n'\ u'Please set only one projections for all input layers.').format(euc_crs, dmt_crs, bpej_crs, lpis_crs)) return # add paths to layers to data data = [] euc_path = euc_layer.dataProvider().dataSourceUri() data.append(euc_path[:euc_path.rfind('|')]) dmt_path = dmt_layer.dataProvider().dataSourceUri() data.append(dmt_path) bpej_path = bpej_layer.dataProvider().dataSourceUri() data.append(bpej_path [:bpej_path.rfind('|')]) lpis_path = lpis_layer.dataProvider().dataSourceUri() data.append(lpis_path [:lpis_path.rfind('|')]) # find r, p factors and add them to factors factors = [] r_factor = self.r_factor.text() p_factor = self.p_factor.text() factors.append(r_factor) factors.append(p_factor) self.progressBar() self.computeThread = ComputeThread(data, factors, epsg) self.computeThread.computeFinished.connect(lambda: self.importResults(epsg)) self.computeThread.computeStat.connect(self.setStatus) self.computeThread.computeError.connect(self.showError) #self.computeThread.computeProgress.connect(self.progressBar) if not self.computeThread.isRunning(): self.computeThread.start() def checkField(self, name_lyr, layer, field_name): if layer.fieldNameIndex(field_name) == -1: self.showError(self.tr(u'{} layer must contain field {}.\nClick on \'Compute {} factor\'')\ .format(name_lyr, field_name, field_name)) self._cancel = True def showError(self, text): QMessageBox.critical(self, self.tr(u'Soil Erosion Plugin'), u"{}".format(text)) def importResults(self, epsg): # if self.computeThread.aborted: # return # Import results to QGIS temp_path = self.computeThread.output_path() for file in os.listdir(temp_path): if file.endswith(".tif"): try: self._se_layer = iface.addRasterLayer(os.path.join(temp_path, file), self.tr('G Faktor')) crs = self._se_layer.crs() crs.createFromId(epsg) self._se_layer.setCrs(crs) self.layerOnTop(self._se_layer) # # Set style be renderer: # self.setStyle(self._se_layer) # # set style on .gml file: euc = self.shp_box_euc.currentLayer() self._euc_vector = iface.addVectorLayer(euc.source(), "EUC", euc.providerType()) self.layerOnTop(self._euc_vector) se_source = self._se_layer.source() self.zonalStat(self._euc_vector, se_source) self.setVectorErosionStyle(self._euc_vector) self._euc_vector.commitChanges() # for field in _euc_vector.pendingFields(): # if field.name() == 'C': # _euc_vector.startEditing() # oldname = field.name() # field.setName('NewName') # newname = field.name() # self.showError(u'Old name: {},New name: {}'.format(oldname,newname)) # except: self.showError(u'Error during compute zonal statistics.') self._first_computation = False self.computeThread.cleanup() del self.computeThread # kill progress bar if it is still on (if computation is still on) try: self.progress.setParent(None) self.iface.messageBar().popWidget(self.progressMessageBar) except: pass def layerOnTop(self, layer): root = QgsProject.instance().layerTreeRoot() alayer = root.findLayer(layer.id()) clone = alayer.clone() parent = alayer.parent() parent.insertChildNode(0, clone) parent.removeChildNode(alayer) def setBpejStyle(self, layer): # define ranges: label, lower value, upper value, hex value of color k_values = ( (self.tr('0.0-0.1'), 0.0, 0.1, '#458b00'), (self.tr('0.1-0.2'), 0.1, 0.2, '#bcee68'), (self.tr('0.2-0.3'), 0.2, 0.3, '#eedd82'), (self.tr('0.3-0.4'), 0.3, 0.4, '#ffa07a'), (self.tr('0.4-0.5'), 0.4, 0.5, '#ff4500'), (self.tr('0.5 and more'), 0.5, 9999.0, '#8b2500'), ) # create a category for each item in k_values ranges = [] for label, lower, upper, color in k_values: symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol.setColor(QColor(color)) rng = QgsRendererRangeV2(lower, upper, symbol, label) ranges.append(rng) # create the renderer and assign it to a layer expression = 'K' # field name renderer = QgsGraduatedSymbolRendererV2(expression, ranges) layer.setRendererV2(renderer) def setLpisStyle(self, layer): # define a lookup: value -> (color, label) land_types = { 'L': ('#005900', self.tr('Forest')), 'R': ('#6d4237', self.tr('Arable land')), 'S': ('#fb5858', self.tr('Orchard')), 'V': ('#d875e4', self.tr('Vineyard')), 'C': ('#f2d773', self.tr('Hop-garden')), 'T': ('#329932', self.tr('Permanent grassland')), '': ('#808080', self.tr('Unknown')), } # create a category for each item in land_types categories = [] for land_type, (color, label) in land_types.items(): symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol.setColor(QColor(color)) category = QgsRendererCategoryV2(land_type, symbol, label) categories.append(category) # create the renderer and assign it to a layer expression = 'KULTURAKOD' # field name renderer = QgsCategorizedSymbolRendererV2(expression, categories) layer.setRendererV2(renderer) def setVectorErosionStyle(self, layer): # define ranges: label, lower value, upper value, hex value of color g_values = ( (self.tr('Very weakly endangered'), 0.0, 1.0, '#458b00'), (self.tr('Weakly endangered'), 1.0, 2.0, '#bcee68'), (self.tr('Moderately endangered'), 2.0, 4.0, '#eedd82'), (self.tr('Severely endangered'), 4.0, 8.0, '#ffa07a'), (self.tr('Very severely endangered'), 8.0, 10.0, '#ff4500'), (self.tr('Extremely endangered'), 10.0, 999999.9, '#8b2500'), ) # create a category for each item in g_values ranges = [] for label, lower, upper, color in g_values: symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol.setColor(QColor(color)) rng = QgsRendererRangeV2(lower, upper, symbol, label) ranges.append(rng) # create the renderer and assign it to a layer expression = 'G' # field name renderer = QgsGraduatedSymbolRendererV2(expression, ranges) layer.setRendererV2(renderer) def progressBar(self): """Initializing progress bar. :text: message to indicate what operation is currently on """ self.progressMessageBar = iface.messageBar().createMessage(self.tr(u'Soil Erosion Plugin:'), self.tr(u' Computing...')) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.cancelButton = QtGui.QPushButton() self.cancelButton.setText(self.tr('Cancel')) self.progressMessageBar.layout().addWidget(self.cancelButton) self.progressMessageBar.layout().addWidget(self.progress) msgBar = self.iface.messageBar() msgBar.pushWidget(self.progressMessageBar, iface.messageBar().INFO) msgBar.findChildren(QToolButton)[0].setHidden(True) self.cancelButton.clicked.connect(self.onCancelButton) def onCancelButton(self): """Show message box with question on canceling. Cancel computation.""" reply = QMessageBox.question(self, self.tr(u'Soil Erosion Plugin'), self.tr(u'Cancel computation?{ls}').format( ls=2 * os.linesep), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) if reply == QMessageBox.Yes: self.computeThread.terminate() self.computeThread.cleanup() del self.computeThread # kill progress bar if it is still on (if computation is still on) try: self.progress.setParent(None) self.iface.messageBar().popWidget(self.progressMessageBar) except: pass def setStatus(self, num, text): """Update progress status. :num: progress percent """ self.progressMessageBar.setText(text) self.progress.setFormat('{}%'.format(num)) self.progress.setValue(num) def setStyle(self, layer): provider = layer.dataProvider() extent = layer.extent() stats = provider.bandStatistics(1, QgsRasterBandStats.All, extent, 0) if stats.minimumValue < 0: min = 0 else: min = stats.minimumValue max = stats.maximumValue range = max - min add = range // 2 interval = min + add colDic = {'red': '#ff0000', 'yellow': '#ffff00', 'blue': '#0000ff'} valueList = [min, interval, max] lst = [QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['red'])), QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['yellow'])), QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['blue']))] myRasterShader = QgsRasterShader() myColorRamp = QgsColorRampShader() myColorRamp.setColorRampItemList(lst) myColorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED) # TODO: add classificationMode=Continuos # myColorRamp.setClassificationMode(QgsColorRampShader.ClassificationMode(1)) # AttributeError: type object 'QgsColorRampShader' has no attribute 'setClassificationMode' myRasterShader.setRasterShaderFunction(myColorRamp) myPseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), layer.type(), myRasterShader) layer.setRenderer(myPseudoRenderer) layer.triggerRepaint() def zonalStat(self, vlayer, rlayer_source): prefix = 'Erosion_G_' zonalstats = QgsZonalStatistics(vlayer, rlayer_source, prefix, stats=QgsZonalStatistics.Statistic(4)) zonalstats.calculateStatistics(None) vlayer.startEditing() for field in vlayer.pendingFields(): if field.name() == 'Erosion_G_': idx = vlayer.fieldNameIndex(field.name()) vlayer.renameAttribute(idx, 'G') vlayer.commitChanges()
class _CancellableProgressEditor(Editor): title = Unicode # synced from factory.title_name message = Unicode # synced from factory.message_name min = Int#Float # synced from factory.min_name max = Int#Float # synced from factory.max_name show_time = Bool # synced from factory.show_time_name def _title_changed(self): if self._title is not None: self._title.setText('<B>%s</B>' % self.title) self._title.setVisible(len(self.title) > 0) def _message_changed(self): if self._message is not None: self._message.setText(self.message) self._message.setVisible(len(self.message) > 0) if self.factory.prefix_message: self.set_text() def _show_time_changed(self): if self._time_widget is not None: self._time_widget.setVisible(self.show_time) @on_trait_change('min, max') def change_range(self): if self._progress_bar is not None: self._progress_bar.setRange(self.min, self.max) self.update_editor() def init(self, parent): self.title = self.factory.title if len(self.factory.title_name) > 0: self.sync_value(self.factory.title_name, 'title')#, 'from') self.message = self.factory.message if len(self.factory.message_name) > 0: self.sync_value(self.factory.message_name, 'message')#, 'from') self.min = self.factory.min if len(self.factory.min_name) > 0: self.sync_value(self.factory.min_name, 'min')#, 'from') self.max = self.factory.max if len(self.factory.max_name) > 0: self.sync_value(self.factory.max_name, 'max')#, 'from') self.show_time = self.factory.show_time if len(self.factory.show_time_name) > 0: self.sync_value(self.factory.show_time_name, 'show_time')#, 'from') self.control = self._create_control(parent) self.can_cancel = self.factory.can_cancel if len(self.factory.can_cancel_name) > 0: self.sync_value(self.factory.can_cancel_name, 'can_cancel')#, 'from') self.set_tooltip() self.reset() can_cancel = Bool(False) from traits.api import Any buttons = Any @on_trait_change('can_cancel') def set_buttons_visible(self, value): self.buttons.setVisible(value) def _create_control(self, parent): layout = QVBoxLayout() if len(self.title) > 0: self._title = QLabel('<B>%s</B>' % self.title) layout.addWidget(self._title) if not self.factory.prefix_message and len(self.message) > 0: self._message = QLabel(self.message) # self._message = QTextEdit(self.message) # self._message.setReadOnly(True) layout.addWidget(self._message) self._progress_bar = QProgressBar() self._progress_bar.setRange(self.min, self.max) if not self.factory.can_cancel: layout.addWidget(self._progress_bar) else: self.buttons = QDialogButtonBox() self.buttons.addButton(u'Cancel', QDialogButtonBox.RejectRole) self.buttons.connect(self.buttons, SIGNAL('rejected()'), self.factory.cancelled) grid_layout = QGridLayout() grid_layout.addWidget(self._progress_bar, 0, 0) grid_layout.setColumnStretch(0, 1) grid_layout.addWidget(self.buttons, 0, 1) layout.addLayout(grid_layout) if self.factory.show_time: elapsed_label = QLabel('Elapsed time:') estimated_label = QLabel('Estimated time:') remaining_label = QLabel('Remaining time:') self._elapsed_control = QLabel('unknown') self._estimated_control = QLabel('unknown') self._remaining_control = QLabel('unknown') grid_layout = QGridLayout() grid_layout.addWidget(elapsed_label, 0, 0) grid_layout.addWidget(self._elapsed_control, 0, 1) grid_layout.addWidget(estimated_label, 1, 0) grid_layout.addWidget(self._estimated_control, 1, 1) grid_layout.addWidget(remaining_label, 2, 0) grid_layout.addWidget(self._remaining_control, 2, 1) grid_layout.setColumnStretch(1, 1) self._time_widget = QWidget() self._time_widget.setLayout(grid_layout) layout.addWidget(self._time_widget) if self.factory.show_text: self.set_text() else: self._progress_bar.setTextVisible(False) widget = QWidget() widget.setLayout(layout) return widget def set_text(self): if self._progress_bar is None: return if self.factory.prefix_message: format = self.message + ' ' else: format = '' if self.factory.show_value: format += '%v' if self.factory.show_max: if self.factory.show_value: format += '/' format += '%m' if self.factory.show_value or self.factory.show_max: format += ' ' if self.factory.show_percent: if self.factory.show_value or self.factory.show_max: format += '(%p%)' else: format += '%p%' self._progress_bar.setFormat(format) def _set_time_label(self, value, control): hours = value / 3600 minutes = (value % 3600) / 60 seconds = value % 60 label = "%1u:%02u:%02u" % (hours, minutes, seconds) control.setText(control.text()[:-7] + label) def update_editor(self): if self.factory.min <= self.value <= self.factory.max: if self.value == self.factory.min: self.reset() self._progress_bar.setValue(self.value) if self.factory.show_time: if (self.factory.max != self.factory.min): percent = (float(self.value) - self.factory.min) / (self.factory.max - self.factory.min) # if float(<undefined>) raises an error here then probably the # name of the trait this is editing is mispelled or owned by # the handler, e.g. 'handler.progress' instead of 'progress'. else: percent = 1.0 if self.factory.show_time and (percent != 0): current_time = time.time() elapsed = current_time - self._start_time estimated = elapsed / percent remaining = estimated - elapsed self._set_time_label(elapsed, self._elapsed_control) self._set_time_label(estimated, self._estimated_control) self._set_time_label(remaining, self._remaining_control) def reset(self): self._progress_bar.reset() self._start_time = time.time()
class VmUsageBarWidget(QWidget): class VmUsageBarItem(QTableWidgetItem): def __init__(self, value, vm): super(VmUsageBarWidget.VmUsageBarItem, self).__init__() self.value = value self.vm = vm def set_value(self, value): self.value = value def __lt__(self, other): if self.vm.qid == 0: return True elif other.vm.qid == 0: return False elif self.value == other.value: return self.vm.qid < other.vm.qid else: return int(self.value) < int(other.value) def __init__(self, min, max, format, update_func, vm, load, hue=210, parent=None): super(VmUsageBarWidget, self).__init__(parent) self.min = min self.max = max self.update_func = update_func self.value = min self.widget = QProgressBar() self.widget.setMinimum(min) self.widget.setMaximum(max) self.widget.setFormat(format) self.widget.setStyleSheet( "QProgressBar:horizontal{" +\ "border: 1px solid hsv({0}, 100, 250);".format(hue) +\ "border-radius: 4px;\ background: white;\ text-align: center;\ }\ QProgressBar::chunk:horizontal {\ background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, " +\ "stop: 0 hsv({0}, 170, 207),".format(hue) + " stop: 1 white); \ }" ) layout = QHBoxLayout() layout.addWidget(self.widget) self.setLayout(layout) self.tableItem = self.VmUsageBarItem(min, vm) self.update_load(vm, load) def update_load(self, vm, load): self.value = self.update_func(vm, load) self.widget.setValue(self.value) self.tableItem.set_value(self.value)
class UploadDialog(QDialog): def __init__(self, bbclient, parent=None, session_id=None, username=None, password=None): super(UploadDialog, self).__init__(parent, Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowMinMaxButtonsHint) self.session_id = session_id self.username = username self.password = password self._first_auth = True self.total_progress = QProgressBar(self) self.total_progress.setRange(0, 100) self.total_progress.setValue(0) self.total_progress.setFormat('%p%') self.status_msg = QLabel('Starting upload', self) self.setWindowTitle('Uploading') self._createLayout() self.upload = BrytonSportUpload(bbclient, parent=self) self.upload.authNeeded.connect(self._onAuthNeeded) self.upload.totalProgress.connect(self.total_progress.setValue) self.upload.statusMessage.connect(self.status_msg.setText) self.upload.finished.connect(self._onFinished) self.upload.failed.connect(self._onError) # self.upload.start() QTimer.singleShot(100, self.upload.start) def _createLayout(self): l = QVBoxLayout() l.addWidget(self.status_msg) l.addWidget(self.total_progress) self.setLayout(l) def _onAuthNeeded(self): if self._first_auth and self.username is not None and self.password is not None: self._first_auth = False self.upload.authenticate(self.username, self.password) return d = AuthDialog(self) if d.exec_() == QDialog.Accepted: u, p = d.getValues() self.upload.authenticate(u, p) else: self.accept() def _onFinished(self): QMessageBox.information(self, 'Upload Finished', 'The tracks was successfully uploaded.') self.accept() def _onError(self): QMessageBox.warning(self, 'Upload Failed', 'The upload failed with an unknown error.') self.accept()
class VmUsageBarWidget (QWidget): class VmUsageBarItem (QTableWidgetItem): def __init__(self, value, vm): super(VmUsageBarWidget.VmUsageBarItem, self).__init__() self.value = value self.vm = vm def set_value(self, value): self.value = value def __lt__(self, other): if self.vm.qid == 0: return True elif other.vm.qid == 0: return False elif self.value == other.value: return self.vm.qid < other.vm.qid else: return int(self.value) < int(other.value) def __init__(self, min, max, format, update_func, vm, load, hue=210, parent = None): super (VmUsageBarWidget, self).__init__(parent) self.min = min self.max = max self.update_func = update_func self.value = min self.widget = QProgressBar() self.widget.setMinimum(min) self.widget.setMaximum(max) self.widget.setFormat(format) self.widget.setStyleSheet( "QProgressBar:horizontal{" +\ "border: 1px solid hsv({0}, 100, 250);".format(hue) +\ "border-radius: 4px;\ background: white;\ text-align: center;\ }\ QProgressBar::chunk:horizontal {\ background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, " +\ "stop: 0 hsv({0}, 170, 207),".format(hue) + " stop: 1 white); \ }" ) layout = QHBoxLayout() layout.addWidget(self.widget) self.setLayout(layout) self.tableItem = self.VmUsageBarItem(min, vm) self.update_load(vm, load) def update_load(self, vm, load): self.value = self.update_func(vm, load) self.widget.setValue(self.value) self.tableItem.set_value(self.value)
class GroundRadiationMonitoringDockWidget(QtGui.QDockWidget, FORM_CLASS): closingPlugin = pyqtSignal() def __init__(self, parent=None): """Constructor.""" super(GroundRadiationMonitoringDockWidget, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.settings = QSettings("CTU", "GRMplugin") self.iface = iface # Set filters for QgsMapLayerComboBoxes self.raster_box.setFilters(QgsMapLayerProxyModel.RasterLayer) self.track_box.setFilters(QgsMapLayerProxyModel.LineLayer) self.load_raster.clicked.connect(self.onLoadRaster) self.load_track.clicked.connect(self.onLoadTrack) self.save_button.setEnabled(False) self.report_button.clicked.connect(self.onReportButton) #self.dir_button.clicked.connect(self.onCsvButton) self.shp_button.clicked.connect(self.onShpButton) self.save_button.clicked.connect(self.onExportRasterValues) def closeEvent(self, event): self.closingPlugin.emit() event.accept() def onLoadRaster(self): """Open 'Add raster layer dialog'.""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') fileName = QFileDialog.getOpenFileName( self, self.tr(u'Open raster'), self.tr(u'{}').format(lastUsedFilePath), QgsProviderRegistry.instance().fileRasterFilters()) if fileName: self.iface.addRasterLayer(fileName, QFileInfo(fileName).baseName()) self.settings.setValue(sender, os.path.dirname(fileName)) def onLoadTrack(self): """Open 'Add track layer dialog'.""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') fileName = QFileDialog.getOpenFileName( self, self.tr(u'Open track'), self.tr(u'{}').format(lastUsedFilePath), QgsProviderRegistry.instance().fileVectorFilters()) if fileName: self.iface.addVectorLayer(fileName, QFileInfo(fileName).baseName(), "ogr") self.settings.setValue(sender, os.path.dirname(fileName)) name, fileExtension = os.path.splitext(fileName) if fileExtension not in QgsProviderRegistry.instance( ).fileVectorFilters(): return # TODO: make this work for multiple layer loading if self.iface.activeLayer().geometryType() != QGis.Line: self.sendMessage( u'Info', u'{} does not have lineString type.'.format( QFileInfo(fileName).baseName()), 'INFO') def onReportButton(self): """Get destination of report, csv and shape file. Set path and name for csv and shape file by default as file path for report file. Set default name for report file same as track layer name""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') self.saveReportName = QFileDialog.getSaveFileName( self, self.tr(u'Select destination file'), self.tr(u'{}{}.txt').format(lastUsedFilePath, os.path.sep), filter="TXT (*.txt)") self.saveShpName = self.tr(u'{}.shp').format( self.saveReportName.split('.')[0]) self.report_file.setText(self.tr(u'{}').format(self.saveReportName)) if self.saveReportName: self.shp_file.setText(self.tr(u'{}').format(self.saveShpName)) self.settings.setValue(sender, os.path.dirname(self.saveReportName)) # Enable the saveButton if file is chosen if not self.report_file.text(): self.save_button.setEnabled(False) else: self.save_button.setEnabled(True) def onShpButton(self): """Get destination of shp file.""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') self.saveShpName = QFileDialog.getSaveFileName( self, self.tr(u'Select destination file'), self.tr(u'{}{}.shp').format(lastUsedFilePath, os.path.sep), filter="ESRI Shapefile (*.shp)") self.shp_file.setText(u'{}'.format(self.saveShpName)) if self.saveShpName: self.settings.setValue(sender, os.path.dirname(self.saveShpName)) if not (self.report_file.text() and self.shp_file.text()): self.save_button.setEnabled(False) else: self.save_button.setEnabled(True) def onExportRasterValues(self): """Export sampled raster values to output CSV file. Prints error when user selected length of segment or speed is not positive real number and computation is not performed. When no raster or track vector layer given, than computation is not performed. If shapefile that will be created has the same name as one of the layers in map canvas, that layer will be removed from map layer registry. """ noSamplingFlag = False if not self.vertex_dist.text().strip(): distanceBetweenVertices = 0 noSamplingFlag = True if noSamplingFlag == False: try: distanceBetweenVertices = float( self.vertex_dist.text().replace(',', '.')) except ValueError: self.sendMessage( u'Error', u'"{}" is not a number. (distance between vertices)'. format(self.vertex_dist.text()), 'CRITICAL') return if distanceBetweenVertices <= 0 and noSamplingFlag == False: self.sendMessage( u'Error', u'"{}" is not a positive number. (distance between vertices)'. format(distanceBetweenVertices), 'CRITICAL') return if not self.speed.text(): self.sendMessage(u'Error', u'No speed given.', 'CRITICAL') return try: speed = float(self.speed.text().replace(',', '.')) except ValueError: self.sendMessage( u'Error', u'"{}" is not a number. (speed)'.format(self.speed.text()), 'CRITICAL') return if speed <= 0: self.sendMessage( u'Error', u'"{}" is not a positive number. (speed)'.format(speed), 'CRITICAL') return if not self.raster_box.currentLayer( ) or not self.track_box.currentLayer(): self.sendMessage(u'Error', u'No raster/track layer chosen.', 'CRITICAL') return # remove layers with same name as newly created layer for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.source() == self.saveShpName: QgsMapLayerRegistry.instance().removeMapLayer(lyr.id()) self.saveCsvName = None if self.create_csv.isChecked(): self.saveCsvName = self.tr(u'{}.csv').format( self.saveShpName.split('.')[0]) self.computeThread = GroundRadiationMonitoringComputation( self.raster_box.currentLayer().id(), self.track_box.currentLayer().id(), self.saveReportName, self.saveCsvName, self.saveShpName, distanceBetweenVertices, speed, self.unit_box.currentText()) self.saveShpNameOriginal = self.saveShpName self.saveReportNameOriginal = self.saveReportName self.saveCsvNameOriginal = self.saveCsvName self.computeThread.computeEnd.connect(self.addNewLayer) self.computeThread.computeStat.connect(self.setStatus) self.computeThread.computeProgress.connect(self.progressBar) self.computeThread.computeMessage.connect(self.sendMessage) if not self.computeThread.isRunning(): self.computeThread.start() self.save_button.setEnabled(False) def onCancelButton(self): """Show message box with question on canceling. Cancel computation.""" reply = QMessageBox.question( self, u'Ground Radiation Monitoring', u"Cancel computation?{ls}(All created files will be lost.)".format( ls=2 * os.linesep), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) if reply == QMessageBox.Yes: GroundRadiationMonitoringComputation.abortThread( self.computeThread) # kill progress bar if it is still on (if computation is still on) try: self.progress.setParent(None) self.iface.messageBar().popWidget(self.progressMessageBar) except: pass self.cleanCreatedFiles() if not (self.report_file.text() and self.shp_file.text()): self.save_button.setEnabled(False) else: self.save_button.setEnabled(True) def cleanCreatedFiles(self): """Remove created files.""" # remove layers with same name as newly created layer (if is created # and added to map canvas) so shape file could be removed for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.source() == self.saveShpNameOriginal: QgsMapLayerRegistry.instance().removeMapLayer(lyr.id()) # remove created files if os.path.isfile(self.saveReportNameOriginal): os.remove(self.saveReportNameOriginal) try: if os.path.isfile(self.saveCsvNameOriginal): os.remove(self.saveCsvNameOriginal) except: pass if os.path.isfile(self.saveShpNameOriginal): os.remove(self.saveShpNameOriginal) if os.path.isfile(self.saveShpNameOriginal.split('.')[0] + '.shx'): os.remove(self.saveShpNameOriginal.split('.')[0] + '.shx') if os.path.isfile(self.saveShpNameOriginal.split('.')[0] + '.dbf'): os.remove(self.saveShpNameOriginal.split('.')[0] + '.dbf') if os.path.isfile(self.saveShpNameOriginal.split('.')[0] + '.prj'): os.remove(self.saveShpNameOriginal.split('.')[0] + '.prj') def progressBar(self): """Initializing progress bar. """ self.progressMessageBar = iface.messageBar().createMessage( u"Ground Radiation Monitoring:", u" Computing...") self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.cancelButton = QtGui.QPushButton() self.cancelButton.setText('Cancel') self.progressMessageBar.layout().addWidget(self.cancelButton) self.progressMessageBar.layout().addWidget(self.progress) msgBar = self.iface.messageBar() msgBar.pushWidget(self.progressMessageBar, iface.messageBar().INFO) #hide x button msgBar.findChildren(QToolButton)[0].setHidden(True) self.cancelButton.clicked.connect(self.onCancelButton) def setStatus(self, num, text): """Update progress status. :num: progress percent """ self.progress.setFormat(text) self.progress.setValue(num) def addNewLayer(self): """End computeThread. Ask to add new layer of computed points to map canvas. """ # Message box reply = QMessageBox.question( self, u'Ground Radiation Monitoring', u"Add new layer to map canvas?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) # add map layer to map canvas if reply == QMessageBox.Yes: newLayer = iface.addVectorLayer( u'{f}'.format(f=self.saveShpNameOriginal), u'{f}'.format( f=QFileInfo(self.saveShpNameOriginal).baseName()), "ogr") self.iface.messageBar().popWidget(self.progressMessageBar) self.save_button.setEnabled(True) def sendMessage(self, caption, message, type): if type == 'CRITICAL': self.iface.messageBar().pushMessage(self.tr(u'{}').format(caption), self.tr(u'{}').format(message), level=QgsMessageBar.CRITICAL, duration=5) elif type == 'INFO': self.iface.messageBar().pushMessage(self.tr(u'{}').format(caption), self.tr(u'{}').format(message), level=QgsMessageBar.INFO, duration=5)
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " ec = ExplorerContainer() super(Main, self).initialize(*args, **kwargs) self.editor_s = self.locator.get_service('editor') # directory auto completer self.completer = QCompleter(self) self.dirs = QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.group0 = QGroupBox() self.group0.setTitle(' Source ') self.source = QComboBox() self.source.addItems(['Clipboard', 'Local File', 'Remote URL', 'Ninja']) self.source.currentIndexChanged.connect(self.on_source_changed) self.infile = QLineEdit(path.expanduser("~")) self.infile.setPlaceholderText(' /full/path/to/file.html ') self.infile.setCompleter(self.completer) self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open') self.open.setCursor(QCursor(Qt.PointingHandCursor)) self.open.clicked.connect(lambda: self.infile.setText(str( QFileDialog.getOpenFileName(self.dock, "Open a File to read from", path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e) for e in ['css', 'html', 'js', 'txt', '*']]))))) self.inurl = QLineEdit('http://www.') self.inurl.setPlaceholderText('http://www.full/url/to/remote/file.html') self.output = QPlainTextEdit(SAMPLE_TEXT) vboxg0 = QVBoxLayout(self.group0) for each_widget in (self.source, self.infile, self.open, self.inurl, self.output, ): vboxg0.addWidget(each_widget) [a.hide() for a in iter((self.infile, self.open, self.inurl))] self.group1 = QGroupBox() self.group1.setTitle(' CSS3 ') self.group1.setCheckable(True) self.group1.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group1.graphicsEffect().setEnabled(False) self.group1.toggled.connect(self.toggle_css_group) self.ckcss1 = QCheckBox('Remove unnecessary Comments') self.ckcss2 = QCheckBox('Remove unnecessary Whitespace characters') self.ckcss3 = QCheckBox('Remove unnecessary Semicolons') self.ckcss4 = QCheckBox('Remove unnecessary Empty rules') self.ckcss5 = QCheckBox('Condense and Convert Colors from RGB to HEX') self.ckcss6 = QCheckBox('Condense all Zero units') self.ckcss7 = QCheckBox('Condense Multidimensional Zero units') self.ckcss8 = QCheckBox('Condense Floating point numbers') self.ckcss9 = QCheckBox('Condense HEX Colors') self.ckcss10 = QCheckBox('Condense multiple adjacent Whitespace chars') self.ckcss11 = QCheckBox('Condense multiple adjacent semicolon chars') self.ckcss12 = QCheckBox('Wrap the lines of the to 80 character length') self.ckcss13 = QCheckBox('Condense Font Weight values') self.ckcss14 = QCheckBox('Condense the 17 Standard Named Colors values') self.ckcss15 = QCheckBox('Condense the 124 Extra Named Colors values') self.ckcss16 = QCheckBox('Condense all Percentages values when posible') self.ckcss17 = QCheckBox('Condense all Pixels values when posible') self.ckcss18 = QCheckBox('Remove unnecessary quotes from url()') self.ckcss19 = QCheckBox('Add standard Encoding Declaration if missing') vboxg1 = QVBoxLayout(self.group1) for each_widget in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19): vboxg1.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group2 = QGroupBox() self.group2.setTitle(' HTML5 ') self.group2.setCheckable(True) self.group2.setGraphicsEffect(QGraphicsBlurEffect(self)) self.group2.graphicsEffect().setEnabled(False) self.group2.toggled.connect(self.toggle_html_group) self.ckhtml0 = QCheckBox('Condense Style and Script HTML Tags') self.ckhtml1 = QCheckBox('Condense DOCTYPE to new HTML5 Tags') self.ckhtml2 = QCheckBox('Condense Href and Src to protocol agnostic') self.ckhtml4 = QCheckBox('Remove unnecessary Tags but keep HTML valid') self.help1 = QLabel('''<a href= "https://developers.google.com/speed/articles/optimizing-html"> <small><center>Help about Unneeded Unnecessary HTML tags ?</a>''') self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.help1.setOpenExternalLinks(True) vboxg2 = QVBoxLayout(self.group2) for each_widget in (self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4, self.help1, ): vboxg2.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group3 = QGroupBox() self.group3.setTitle(' Javascript ') self.ckjs0 = QCheckBox('Condense and Compress Javascript') self.ckjs1 = QCheckBox('Condense $(document).ready(function(){ });') vboxg2 = QVBoxLayout(self.group3) for each_widget in (self.ckjs0, self.ckjs1): vboxg2.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) self.group4 = QGroupBox() self.group4.setTitle(' General ') self.chckbx1 = QCheckBox('Lower case ALL the text') self.chckbx2 = QCheckBox('Remove Spaces, Tabs, New Lines, Empty Lines') self.befor, self.after = QProgressBar(), QProgressBar() self.befor.setFormat("%v Chars") self.after.setFormat("%v Chars") vboxg4 = QVBoxLayout(self.group4) for each_widget in (self.chckbx1, self.chckbx2, QLabel('<b>Before:'), self.befor, QLabel('<b>After:'), self.after): vboxg4.addWidget(each_widget) each_widget.setToolTip(each_widget.text()) [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19, self.ckjs1, self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4, self.chckbx1, self.chckbx2))] self.button = QPushButton(QIcon.fromTheme("face-cool"), 'Process Text') self.button.setCursor(QCursor(Qt.PointingHandCursor)) self.button.setMinimumSize(100, 50) self.button.clicked.connect(self.run) def must_glow(widget_list): ' apply an glow effect to the widget ' for glow, each_widget in enumerate(widget_list): try: if each_widget.graphicsEffect() is None: glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) each_widget.setGraphicsEffect(glow) glow.setEnabled(True) except: pass must_glow((self.button, )) class TransientWidget(QWidget): ' persistant widget thingy ' def __init__(self, widget_list): ' init sub class ' super(TransientWidget, self).__init__() vbox = QVBoxLayout(self) for each_widget in widget_list: vbox.addWidget(each_widget) tw = TransientWidget((QLabel('<b>HTML5/CSS3/JS Optimizer Compressor'), self.group0, self.group1, self.group2, self.group3, self.group4, self.button, )) self.scrollable = QScrollArea() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(tw) self.dock = QDockWidget() self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setMinimumWidth(350) self.dock.setWidget(self.scrollable) ec.addTab(self.dock, "Web") QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__, HELPMSG)) def run(self): ' run the string replacing ' if self.source.currentText() == 'Local File': with open(path.abspath(str(self.infile.text()).strip()), 'r') as f: txt = f.read() elif self.source.currentText() == 'Remote URL': txt = urlopen(str(self.inurl.text()).strip()).read() elif self.source.currentText() == 'Clipboard': txt = str(self.output.toPlainText()) if str(self.output.toPlainText()) is not '' else str(QApplication.clipboard().text()) else: txt = self.editor_s.get_text() self.output.clear() self.befor.setMaximum(len(txt) + 10) self.after.setMaximum(len(txt) + 10) self.befor.setValue(len(txt)) txt = txt.lower() if self.chckbx1.isChecked() is True else txt txt = condense_style(txt) if self.ckhtml0.isChecked() is True else txt txt = condense_script(txt) if self.ckhtml0.isChecked() is True else txt txt = condense_doctype(txt) if self.ckhtml1.isChecked() is True else txt txt = condense_href_src(txt) if self.ckhtml2 is True else txt txt = clean_unneeded_tags(txt) if self.ckhtml4.isChecked() is True else txt txt = condense_doc_ready(txt) if self.ckjs1.isChecked() is True else txt txt = jsmin(txt) if self.ckjs0.isChecked() is True else txt txt = remove_comments(txt) if self.ckcss1.isChecked() is True else txt txt = condense_whitespace(txt) if self.ckcss10.isChecked() is True else txt txt = remove_empty_rules(txt) if self.ckcss4.isChecked() is True else txt txt = remove_unnecessary_whitespace(txt) if self.ckcss2.isChecked() is True else txt txt = remove_unnecessary_semicolons(txt) if self.ckcss3.isChecked() is True else txt txt = condense_zero_units(txt) if self.ckcss6.isChecked() is True else txt txt = condense_multidimensional_zeros(txt) if self.ckcss7.isChecked() is True else txt txt = condense_floating_points(txt) if self.ckcss8.isChecked() is True else txt txt = normalize_rgb_colors_to_hex(txt) if self.ckcss5.isChecked() is True else txt txt = condense_hex_colors(txt) if self.ckcss9.isChecked() is True else txt txt = wrap_css_lines(txt, 80) if self.ckcss12.isChecked() is True else txt txt = condense_semicolons(txt) if self.ckcss11.isChecked() is True else txt txt = condense_font_weight(txt) if self.ckcss13.isChecked() is True else txt txt = condense_std_named_colors(txt) if self.ckcss14.isChecked() is True else txt # txt = condense_xtra_named_colors(txt) if self.ckcss14.isChecked() is True else txt # FIXME txt = condense_percentage_values(txt) if self.ckcss16.isChecked() is True else txt txt = condense_pixel_values(txt) if self.ckcss17.isChecked() is True else txt txt = remove_url_quotes(txt) if self.ckcss18.isChecked() is True else txt txt = add_encoding(txt) if self.ckcss19.isChecked() is True else txt txt = " ".join(txt.strip().split()) if self.chckbx2.isChecked() is True else txt self.after.setValue(len(txt)) self.output.setPlainText(txt) self.output.show() self.output.setFocus() self.output.selectAll() def on_source_changed(self): ' do something when the desired source has changed ' if self.source.currentText() == 'Local File': self.open.show() self.infile.show() self.inurl.hide() self.output.hide() elif self.source.currentText() == 'Remote URL': self.inurl.show() self.open.hide() self.infile.hide() self.output.hide() elif self.source.currentText() == 'Clipboard': self.output.show() self.open.hide() self.infile.hide() self.inurl.hide() self.output.setText(QApplication.clipboard().text()) else: self.output.show() self.open.hide() self.infile.hide() self.inurl.hide() self.output.setText(self.editor_s.get_text()) def toggle_css_group(self): ' toggle on or off the css checkboxes ' if self.group1.isChecked() is True: [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19))] self.group1.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in iter((self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17, self.ckcss18, self.ckcss19))] self.group1.graphicsEffect().setEnabled(True) def toggle_html_group(self): ' toggle on or off the css checkboxes ' if self.group2.isChecked() is True: [a.setChecked(True) for a in iter((self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4))] self.group2.graphicsEffect().setEnabled(False) else: [a.setChecked(False) for a in iter((self.ckhtml0, self.ckhtml1, self.ckhtml2, self.ckhtml4))] self.group2.graphicsEffect().setEnabled(True)
class DeviceInfoWidget(QWidget): DEVICE_IMAGES = { 'rider20' : resource_path('img/rider20_icon.jpg'), 'rider30' : resource_path('img/rider30_icon.jpg'), 'rider35' : resource_path('img/rider35_icon.jpg'), 'rider40' : resource_path('img/rider40_icon.jpg'), 'rider50' : resource_path('img/rider50_icon.jpg'), 'rider' : resource_path('img/rider_icon.jpg'), 'cardio30' : resource_path('img/cardio30_icon.jpg'), 'cardio35' : resource_path('img/cardio35_icon.jpg'), 'cardio' : resource_path('img/cardio_icon.jpg'), } def __init__(self, parent=None): super(DeviceInfoWidget, self).__init__(parent) self.image = QLabel(self) self.image.setPixmap(QPixmap(self.DEVICE_IMAGES['rider'])) self.image_frame = QFrame(self) self.image_frame.setMaximumHeight(55) self.image_frame.setMinimumHeight(55) self.image_frame.setMaximumWidth(55) self.image_frame.setMinimumWidth(55) self.image_frame.setFrameShape(QFrame.StyledPanel) self.image_frame.setFrameShadow(QFrame.Raised) self.storage_usage = QProgressBar(self) self.storage_usage.setFormat('Disk usage %p%') self.storage_usage.setRange(0, 100) self.storage_usage.setValue(0) self.device_name = QLabel(self) self.device_name.setText('<b>Unknown</b>') self.device_name.setContentsMargins(3, 0, 0, 0) self._createLayout() def setDeviceInfo(self, dev_info): name = dev_info['name'].lower() if name in self.DEVICE_IMAGES: img = self.DEVICE_IMAGES[name] elif 'rider' in name: img = self.DEVICE_IMAGES['rider'] elif 'cardio' in name: img = self.DEVICE_IMAGES['cardio'] else: img = self.DEVICE_IMAGES['rider'] self.device_name.setText('<b>%s</b>' % dev_info['name']) self.image.setPixmap(QPixmap(img)) self.storage_usage.setValue( float(dev_info['storage_used']) / dev_info['total_storage'] * 100 ) def _createLayout(self): l = QHBoxLayout() l.addWidget(self.image) l.setContentsMargins(1, 1, 1, 1) self.image_frame.setLayout(l) l = QHBoxLayout() l.addWidget(self.image_frame) v = QVBoxLayout() v.addWidget(self.device_name) v.addWidget(self.storage_usage, 1) l.addLayout(v) self.setLayout(l)
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setWindowTitle('%s %s' % (QApplication.applicationName(), QApplication.applicationVersion())); self.config = ConfigHandler(os.path.join(os.path.expanduser('~'), '.pywv/pywv.cfg'), self) self.setStyle(QStyleFactory.create(self.config.loadStyle())) if self.config.loadStyleSheet(): self.setStyleSheet(self.config.loadStyleSheet()) else: self.setStyleSheet("* {}") # without any stylesheet, windowstyles won't apply self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks | QMainWindow.VerticalTabs); # self.dummy = QWidget(self) self.setCentralWidget(QWidget(self)) self.pBar = QProgressBar(self) self.pBar.setRange(0, self.config.loadReloadInterval()) self.pBar.setFormat("%v Sekunden") if not self.config.loadAutoload(): self.pBar.hide() self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) self.statusBar.addWidget(self.pBar) self.reloadTimer = QTimer(self); self.reloadTimer.setInterval(self.config.loadReloadInterval() * 1000) self.connect(self.reloadTimer, SIGNAL('timeout()'), self.reload_) if self.config.loadAutoload(): self.reloadTimer.start() self.autoloadStatusTimer = QTimer(self) self.autoloadStatusTimer.setInterval(1000) # 1 sec self.connect(self.autoloadStatusTimer, SIGNAL('timeout()'), self.onAutoloadStatus) self.autoloadStatusTimer.start() self.mAction = self.menuBar().addMenu(self.tr("&Action")) self.mAction.addAction(self.tr("&update"), self.reload_, QKeySequence('F5')) self.mAction.addAction(self.tr("e&xit"), self.onExit, 'Ctrl+Q') self.mStyle = QMenu(self.tr("&Style"), self) for s in list(QStyleFactory.keys()):# // fill in all available Styles self.mStyle.addAction(s) self.connect(self.mStyle, SIGNAL('triggered(QAction*)'), self.onStyleMenu) self.mOption = self.menuBar().addMenu(self.tr("&Options")) self.mOption.addAction(self.tr("reloadinterval") , self.onReloadTime , 'F8') self.mOption.addAction(self.tr("manage links") , self.onNewLink , 'F6') self.mOption.addSeparator() self.ontopAction = QAction(self.tr("always on &top") , self) self.showTrayAction = QAction(self.tr("show tray &icon") , self) self.closeToTrayAction = QAction(self.tr("close to &tray") , self) self.autoloadAction = QAction(self.tr("auto&load") , self) self.ontopAction.setCheckable(True) self.showTrayAction.setCheckable(True) self.closeToTrayAction.setCheckable(True) self.autoloadAction.setCheckable(True) self.showTrayAction.setChecked (self.config.loadShowTray() ) self.ontopAction.setChecked (self.config.loadOntop() ) self.closeToTrayAction.setChecked(self.config.loadCloseToTray()) self.autoloadAction.setChecked (self.config.loadAutoload() ) self.connect(self.ontopAction , SIGNAL('toggled(bool)') , self.onOntopAction) self.connect(self.showTrayAction , SIGNAL('toggled(bool)') , self.onShowTrayAction) self.connect(self.closeToTrayAction , SIGNAL('toggled(bool)') , self.onCloseToTrayAction) self.connect(self.autoloadAction , SIGNAL('toggled(bool)') , self.onAutoloadAction) self.mOption.addAction(self.ontopAction) self.mOption.addAction(self.showTrayAction) self.mOption.addAction(self.closeToTrayAction) self.mOption.addAction(self.autoloadAction) self.mOption.addSeparator() self.mOption.addMenu(self.mStyle) self.trayIcon = QSystemTrayIcon(QIcon(':/appicon'), self); self.trayMgr = TrayManager(self.config, self.trayIcon) self.connect(self.trayIcon, SIGNAL('activated(QSystemTrayIcon::ActivationReason)'), self.onTrayIcon) if self.config.loadShowTray(): self.trayIcon.show() self.trayIconMenu = QMenu() self.trayIconMenu.addAction(self.tr("e&xit"), self.onExit) self.trayIcon.setContextMenu(self.trayIconMenu) self.mAbout = self.menuBar().addMenu(self.tr("&about")) self.mAbout.addAction(QApplication.applicationName(), self.onAboutAppAction) self.mAbout.addAction("Qt", self.onAboutQtAction) self.createWidgets() self.resize(self.config.loadWindowSize()) self.restoreState(self.config.loadWindowState()) if self.config.loadIsVisible(): self.show() self.reload_() def __del__(self): self.config.saveWindowState(self.saveState()) def createSingleWidget(self, name): # print 'crt', name, type(name), '\n', self.widgets # print 'crt', name, type(name) links = self.config.loadLinks() if links[name]['type'] == 'generic': self.widgets[name] = GenericWidget(name, self.config, self) else: pluginsAvail = classdirPlugins().all_() for plugin in pluginsAvail: if links[name]['type'] == plugin['class']: pluginClass = plugin['class'] break else: continue exec('self.widgets[name] = %s(name, self.config, self)' % pluginClass) # print(('loaded plugin', self.widgets[name])) self.addDockWidget(0x4, self.widgets[name]) self.widgets[name].reload_() def delWidget(self, name): #print 'del', name, type(name), '\n', self.widgets self.removeDockWidget(self.widgets[name]) self.widgets[name].deleteLater() self.widgets[name] = None del self.widgets[name] def createWidgets(self): self.widgets = {} for name in self.config.loadLinks(): self.createSingleWidget(name) @pyqtSlot() def onExit(self): self.config.saveWindowSize(self.size()) QApplication.exit(); def closeEvent(self, event): self.config.saveWindowSize(self.size()) # QApplication.exit() # tray is visible -> close to tray # else close app if self.trayIcon.isVisible(): event.accept() else: QApplication.exit() return # if close-to-tray is set, do so if self.config.loadCloseToTray(): event.accept() else: QApplication.exit() return; # save this state if self.trayIcon.isVisible(): self.config.saveIsVisible(False) else: self.config.saveIsVisible(True); @pyqtSlot() def reload_(self): for name in self.widgets: self.widgets[name].reload_() self.pBar.setValue(self.config.loadReloadInterval()) self.reloadTimer.start(self.config.loadReloadInterval()*1000) @pyqtSlot() def onAutoloadStatus(self): self.pBar.setValue(self.pBar.value()-1) # print([idx for idx in self.widgets]) def onStyleMenu(self, a): QApplication.setStyle(QStyleFactory.create(a.text())) self.setStyle(QStyleFactory.create(a.text())) self.config.saveStyle(a.text()) def onReloadTime(self): ok = False value, ok = QInputDialog.getInteger(self, self.tr("reloadinterval"), # title self.tr("insert time in s"), # text self.config.loadReloadInterval(), # default 10, # minimum 86400, # maximum (at least once a day) 1, # step ) if ok: self.config.saveReloadInterval(value) self.pBar.setRange(0,self.config.loadReloadInterval()) self.reload_() def onAutoloadAction(self, b): if b: self.reloadTimer.start() self.pBar.show() self.reload_() else: self.reloadTimer.stop() self.pBar.hide() self.config.saveAutoload(b) def onNewLink(self): inp = LinkInput(self.config, self) if inp.exec_(): # sync active widgets for name in inp.modifiedWidgets(): if name in self.widgets: self.delWidget(name) self.createSingleWidget(name) else: self.createSingleWidget(name) # remove deleted # for name in self.widgets: print 'shown', name # for name in self.config.loadLinks(): print 'conf', name todel = [] for name in self.widgets: if name not in self.config.loadLinks(): todel.append(name) for widget in todel: self.delWidget(widget) def onOntopAction(self, b): if b: self.setWindowFlags(Qt.Dialog | Qt.WindowStaysOnTopHint) else: self.setWindowFlags(Qt.Dialog) self.setWindowIcon(QIcon(':/appicon')) self.show(); self.config.saveOntop(b) def onShowTrayAction(self, b): if b: self.trayIcon.show() else: self.trayIcon.hide() self.config.saveShowTray(b) def onCloseToTrayAction(self, b): self.config.saveCloseToTray(b) def onTrayIcon(self, reason): if reason == QSystemTrayIcon.Trigger: if(self.isVisible()): self.config.saveWindowSize(self.size()) self.hide() self.config.saveIsVisible(False) else: self.show() self.resize(self.config.loadWindowSize()) self.config.saveIsVisible(True) def onAboutAppAction(self): QMessageBox.about(self, self.tr("&about"), self.tr("name %1 version %2").arg(QApplication.applicationName()).arg(QApplication.applicationVersion())) def onAboutQtAction(self): QMessageBox.aboutQt(self, self.tr("&about"))
class SR785_MainWindow(QMainWindow): GifInfo = { SR785.SCREEN_ALL: (21200, 'all'), SR785.SCREEN_MENU: (4840, 'menu'), SR785.SCREEN_STATUS: (4410, 'status'), SR785.SCREEN_GRAPHS: (11420, 'graphs') } def __init__(self, parent=None): super(SR785_MainWindow, self).__init__(parent) centralWidget = SR785_Widget() self.setCentralWidget(centralWidget) visaResource = 'GPIB0::10' sr785 = SR785(visaResource) sr785.configureScreenDump() centralWidget.associateInstrument(sr785) self.setWindowTitle('SR785 Front Panel Emulation: %s' % sr785.visaId()) self.progressBar = QProgressBar() statusBar = self.statusBar() statusBar.addWidget(self.progressBar) toolBar = QToolBar('Screen') toolBar.addActions(centralWidget.screenActions) self.addToolBar(toolBar) thread = centralWidget.workerThread thread.gifDownloadStarted.connect(self.gifDownloadStarted) thread.gifReceived.connect(self.gifReceived) thread.keyPressSimulated.connect(self.keyPressSimulated) thread.knobRotated.connect(self.knobRotated) dockWidget = QDockWidget('History') self.historyTe = QTextEdit() dockWidget.setWidget(self.historyTe) self.addDockWidget(Qt.TopDockWidgetArea, dockWidget) toolBar = self.addToolBar('File') action = QAction('Save screen', self) action.triggered.connect(self.saveScreen) toolBar.addAction(action) action = QAction('Print', self) action.triggered.connect(self.printScreen) toolBar.addAction(action) def saveScreen(self): directory = '' saveFile = QFileDialog.getSaveFileName(self, 'Save screen to', directory, '*.png *.gif', '*.png') print "saving as:", saveFile screenPixmap = self.centralWidget().screen.pixmap() screenPixmap.save(saveFile) self.log('Screen saved as: %s' % saveFile) def printScreen(self): pass def gifDownloadStarted(self, screen): self.progressBar.setMaximum(self.GifInfo[screen][0]) self.progressBar.setValue(0) label = self.GifInfo[screen][1] self.progressBar.setFormat('%s %%p%%' % label) self.log('Downloading %s' % label) def gifReceived(self, screen): self.progressBar.setValue(self.GifInfo[screen][0]) def keyPressSimulated(self, keyCode): self.log('Key %d pressed.' % keyCode) def knobRotated(self, steps): if steps > 0: self.log('Knob rotated CW.') else: self.log('Knob rotated CCW.') def log(self, message): self.historyTe.append(message + '\n') self.statusBar().showMessage(message, 2000)