class ErrorReportDialog(QDialog): def __init__(self, title, message, errors, username, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(title) self.verticalLayout = QVBoxLayout(self) self.label = QLabel(message, self) self.verticalLayout.addWidget(self.label) self.plainTextEdit = QPlainTextEdit(self) self.plainTextEdit.setPlainText(errors) self.plainTextEdit.setReadOnly(True) self.verticalLayout.addWidget(self.plainTextEdit) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.verticalLayout.addWidget(self.buttonBox) self.reportButton = self.buttonBox.addButton(self.tr("Report error"), QDialogButtonBox.ActionRole) self.reportButton.clicked.connect(self.__reportError) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.username = username self.metadata = MetaData() def __reportError(self): body = ("Please provide any additional information here:\n\n\n" "If you encountered an upload error, if possible please attach a zip file containing a minimal extract of the dataset, as well as the QGIS project file.\n\n\n" "Technical information:\n%s\n\n" "Versions:\n" " QGIS: %s\n" " Python: %s\n" " OS: %s\n" " QGIS Cloud Plugin: %s\n\n" "Username: %s\n") % ( self.plainTextEdit.toPlainText(), Qgis.QGIS_VERSION, sys.version.replace("\n", " "), platform.platform(), self.metadata.version(), self.username) url = QUrl() url.toEncoded("mailto:[email protected]?subject=%s&body=%s" % ( urllib.parse.quote(self.windowTitle()), urllib.parse.quote(body)), ) QDesktopServices.openUrl(url)
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: if output.value is None: output.value = self.tr("[temporary file]") commands = self.alg.getConsoleCommands() commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '{0}'").format( e.parameter.description)) except: self.text.setPlainText("")
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): try: parameters = self.parent.getParamValues() for output in self.alg.destinationParameterDefinitions(): if parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") commands = self.alg.getConsoleCommands(parameters) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description())) except: self.text.setPlainText("")
class ReadyPage(QWizardPage): def __init__(self, title="Ready", sub_title=" "): QWizardPage.__init__(self) self.setTitle(title) self.setSubTitle(sub_title) self.setCommitPage(True) self.createWidgets() self.setButtonText(QWizard.CommitButton, "Start") def createWidgets(self): vlayout = QVBoxLayout() vlayout.addWidget( QLabel( "PST now has all information necessary to start the analysis.") ) vlayout.addStretch(1) self._propView = QPlainTextEdit() self._propView.setReadOnly(True) self._propView.setVisible(False) vlayout.addWidget(self._propView, 30) hlayout = QHBoxLayout() hlayout.addWidget(QLabel("Click 'Start' to start the analysis."), 1) self._toggleSettingsButton = QPushButton("Show settings") self._toggleSettingsButton.clicked.connect(self.onToggleShowSettings) hlayout.addWidget(self._toggleSettingsButton) vlayout.addLayout(hlayout) self.setLayout(vlayout) def initializePage(self): self.wizard().removeDeprecatedProperties() props = self.wizard().properties() text = json.dumps(props, sort_keys=True, indent=4, separators=(',', ': ')) self._propView.setPlainText(text) def validatePage(self): if not QWizardPage.validatePage(self): return False self.wizard().saveProperties() return True def onToggleShowSettings(self): visible = not self._propView.isVisible() self._propView.setVisible(visible) self._toggleSettingsButton.setText( "Hide settings" if visible else "Show settings")
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): wrapper.widgetValueHasChanged.connect(self.parametersHaveChanged) # TODO - remove when all wrappers correctly emit widgetValueHasChanged! # For compatibility with 3.x API, we need to check whether the wrapper is # the deprecated WidgetWrapper class. If not, it's the newer # QgsAbstractProcessingParameterWidgetWrapper class # TODO QGIS 4.0 - remove if issubclass(wrapper.__class__, WidgetWrapper): w = wrapper.widget else: w = wrapper.wrappedWidget() self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) for output_widget in self.outputWidgets.values(): self.connectWidgetChangedSignals(output_widget) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, DestinationSelectionPanel): w.destinationChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[ output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()])): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '{0}'").format( e.parameter.description()))
class ChloeParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, ValuesSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, CustomInputLayerSelectorPanel): w.currentIndexChanged.connect(self.parametersHaveChanged) w.currentIndexChanged.connect( self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, ValuesSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ # if isinstance(param, ParameterString) and param.name in ["VALUES_RANGES"]: # # === Overload ParameterString for special parameter name like VALUES_RANGES,.. # if param.name == "VALUES_RANGES": # item = ValuesSelectionPanel(self.parent, self.alg, param.default) # if param.default: # item.setText(unicode(param.default)) # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self, param) return item
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()], context)): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description()))
class SelectedParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.types_of_metrics = {} for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() self.changePixelsPointsSelectDependent() self.changeWindowShapeDependent() # === Init cbFilter cbFilter = self.widgets["METRICS"].cbFilter cbFilter.addItems(self.alg.types_of_metrics.keys()) # === Init listSrc filter_txt = cbFilter.currentText() w_value = self.widgets["METRICS"].cbValue w_value.clear() if self.types_of_metrics: if filter_txt in self.types_of_metrics.keys(): w_value.addItems(self.types_of_metrics[filter_txt]) def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.initCalculateMetric) w.cmbText.currentIndexChanged.connect( self.parametersHaveChanged) w.cmbText.currentIndexChanged.connect(self.updateMetric) elif isinstance(w, DoubleCmbBoxSelectionPanel): w.cbFilter.currentIndexChanged.connect(self.updateMetric) w.cbValue.currentIndexChanged.connect( self.parametersHaveChanged) elif isinstance(w, ValuesSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets["WINDOW_SHAPE"] w.currentIndexChanged.connect(self.changeWindowShapeDependent) w = self.widgets["WINDOW_SIZES"] w.spnValue.setSingleStep(2) # step incrementation and decrementation w = self.widgets["PIXELS_POINTS_SELECT"] w.currentIndexChanged.connect(self.changePixelsPointsSelectDependent) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) w = self.widgets["METRICS"].cbFilter w.currentIndexChanged.emit(0) self.widgets["INPUT_LAYER_ASC"].cmbText.currentIndexChanged.emit(0) #@pyqtSlot(str) def initCalculateMetric(self): w = self.widgets['INPUT_LAYER_ASC'] try: val = w.getValue() if isinstance(val, QgsRasterLayer): rasterLayerParam = val.source().encode('utf-8') else: rasterLayerParam = val.encode('utf-8') int_values_and_nodata = ChloeUtils.extractValueNotNull( rasterLayerParam) self.types_of_metrics = ChloeUtils.calculateMetric( self.alg.types_of_metrics, self.alg.types_of_metrics_simple, self.alg.types_of_metrics_cross, int_values_and_nodata) except: self.types_of_metrics = [] # === param:PIXELS_POINTS_SELECT Widget:ComboBox #@pyqtSlot(str) def changePixelsPointsSelectDependent(self): index = self.widgets["PIXELS_POINTS_SELECT"].currentIndex() if index == 0: # pixel(s) file self.widgets["PIXELS_FILE"].leText.setDisabled(False) self.widgets["POINTS_FILE"].leText.setDisabled(True) elif index == 1: # point(s) file self.widgets["PIXELS_FILE"].leText.setDisabled(True) self.widgets["POINTS_FILE"].leText.setDisabled(False) # === param:WINDOW_SHAPE Widget:ComboBox #@pyqtSlot(str) def changeWindowShapeDependent(self): txt = self.widgets["WINDOW_SHAPE"].currentText() if txt == "FUNCTIONAL": self.widgets["FRICTION_FILE"].setEnabled(True) else: self.widgets["FRICTION_FILE"].setDisabled(True) #@pyqtSlot(str) def updateMetric(self): filter_txt = self.widgets["METRICS"].cbFilter.currentText() w_value = self.widgets["METRICS"].cbValue w_value.clear() if self.types_of_metrics: if filter_txt in self.types_of_metrics.keys(): w_value.addItems(self.types_of_metrics[filter_txt]) # == One parameter have changed == #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["METRICS"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = DoubleCmbBoxSelectionPanel(self.parent, self.alg, param.default) elif param.name in ["FILTER", "UNFILTER"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = ValuesSelectionPanel(self.parent, self.alg, param.default, 'INPUT_LAYER_ASC') if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self, param) return item
class MapMultiParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() # === Init cbFilter cbFilter = self.widgets["METRICS"].cbFilter cbFilter.addItems(self.alg.types_of_metrics.keys()) # === Init listSrc value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() listSrc.addItems(self.alg.types_of_metrics[value]) # === Init listDest listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() lineEdit = self.widgets["METRICS"].lineEdit lineEdit.setReadOnly(True) def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, ListSelectionPanel): w.pbRight.clicked.connect(self.addInListDst) w.listSrc.itemDoubleClicked.connect(self.addInListDst) w.pbLeft.clicked.connect(self.removeInListDst) w.pbAll.clicked.connect(self.addAllInListDst) w.pbClear.clicked.connect(self.removeAllListDst) w.lineEdit.textChanged.connect(self.parametersHaveChanged) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets["METRICS"].cbFilter w.currentIndexChanged.connect(self.changeMetricDependent) @staticmethod def iterAllItems(lws): for i in range(lws.count()): yield lws.item(i) #@pyqtSlot(str) def addAllInListDst(self): self.addInListDst(all=True) #@pyqtSlot(str) def addInListDst(self,item=None,all=False): """Add metrics selected in listSrc to ListDst""" if not all: selected = self.widgets["METRICS"].listSrc.selectedItems() else: selected = self.iterAllItems(self.widgets["METRICS"].listSrc) for lw in selected: self.metrics_selected.add(lw.text()) listDest = self.widgets["METRICS"].listDest listDest.clear() listDest.addItems(list(self.metrics_selected)) self.updateMetricsLigneEdit() #@pyqtSlot() def removeAllListDst(self): listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() self.updateMetricsLigneEdit() #@pyqtSlot(str) def removeInListDst(self): """Remove metrics selected in listDest""" selected = self.widgets["METRICS"].listDest.selectedItems() for lw in selected: self.metrics_selected.remove(lw.text()) listDest = self.widgets["METRICS"].listDest listDest.clear() listDest.addItems(list(self.metrics_selected)) self.updateMetricsLigneEdit() def updateMetricsLigneEdit(self): """update Metrics (QLineEdit in readOnly mode)""" lineEdit = self.widgets["METRICS"].lineEdit metrics = list(self.metrics_selected) if metrics: lineEdit.setText(";".join(metrics)) else: lineEdit.setText("") #@pyqtSlot(str) def changeMetricDependent(self): """ Update metric source list when the filter of metric change """ cbFilter = self.widgets["METRICS"].cbFilter # === Init list metric value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() listSrc.addItems(self.alg.types_of_metrics[value]) #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["METRICS"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = ListSelectionPanel(self.parent, self.alg, param.default) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class ClassificationParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, ClassificationTablePanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, CustomInputLayerSelectorPanel): w.currentIndexChanged.connect(self.parametersHaveChanged) w.currentIndexChanged.connect( self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, ClassificationTablePanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["DOMAINS"]: # === Overload ParameterString for special parameter name like DOMAINS,.. item = ClassificationTablePanel(self.parent, self.alg, param.default) if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = CustomInputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ChloeParametersPanel.getWidgetFromParameter(self, param) #item = ParametersPanel.getWidgetFromParameter(self,param) return item
class SearchAndReplaceParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() self.changeInputDependent() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect( self.parametersHaveChanged) w.cmbText.currentIndexChanged.connect( self.changeInputDependent) elif isinstance(w, TableReplaceInputDialog): w.leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets['MAP_CSV'] w.leText.textChanged.connect(self.updateDependantMapCSV) w = self.widgets['CHANGES'] w.pbApply.clicked.connect(self.applyCSVMap) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) #@pyqtSlot(str) def changeInputDependent(self): w = self.widgets['INPUT_LAYER_ASC'] try: val = w.getValue() if isinstance(val, QgsRasterLayer): rasterLayerParam = val.source().encode('utf-8') else: rasterLayerParam = val.encode('utf-8') except: pass # == Clean table w = self.widgets['CHANGES'] wt = w.twAssociation for row in xrange(0, wt.rowCount()): r0 = wt.item(row, 0) r1 = wt.item(row, 1) if isinstance(r0, QTableWidgetItem): r0.setText("") else: wt.setItem(row, 0, QTableWidgetItem("")) if isinstance(r1, QTableWidgetItem): r1.setText("") else: wt.setItem(row, 1, QTableWidgetItem("")) try: if rasterLayerParam: f_input = rasterLayerParam # === Parse asc value ds = gdal.Open(f_input) # DataSet band = ds.GetRasterBand(1) # -> band array = np.array(band.ReadAsArray()) # -> matrice values values = np.unique(array) values_and_nodata = np.insert( values, 0, band.GetNoDataValue()) # Add nodata values in numpy array int_values_and_nodata = [ int(math.floor(x)) for x in values_and_nodata ] # == Write value in table wt = w.twAssociation int_values_and_nodata for val, row in zip(int_values_and_nodata, xrange(0, wt.rowCount())): r0 = wt.item(row, 0) if isinstance(r0, QTableWidgetItem): r0.setText(str(val)) else: wt.setItem(row, 0, QTableWidgetItem(str(val))) except: pass #@pyqtSlot(str) def updateDependantMapCSV(self): w = self.widgets['MAP_CSV'] f_map_csv = w.leText.text().encode('utf-8') w_change = self.widgets['CHANGES'] cmbBox = w_change.cmbBox cmbBox.clear() try: # == Get list index if f_map_csv: if os.path.exists(f_map_csv): with open(f_map_csv, 'r') as f: line = f.next() headers = filter(None, re.split('\n|;| |,', line)) cmbBox.addItems(headers[1:]) except: pass #@pyqtSlot(str) def applyCSVMap(self): w = self.widgets['MAP_CSV'] f_map_csv = w.leText.text().encode('utf-8') w_change = self.widgets['CHANGES'] # Index if f_map_csv: if os.path.exists(f_map_csv): with open(f_map_csv, 'r') as f: line = f.next() headers = filter(None, re.split('\n|;| |,', line)) name_col = w_change.cmbBox.currentText() idex_col = headers[1:].index(name_col) + 1 t_ass = [] # Table d'association if f_map_csv: if os.path.exists(f_map_csv): with open(f_map_csv, 'r') as f: b_header = 1 for line in f: if b_header == 1: b_header = 0 continue # Jump the header data = filter(None, re.split('\n|;| |,', line)) t_ass.append([data[0], data[idex_col]]) # Table two dimention if t_ass: # Update with associtation table wt = w_change.twAssociation for t_as in t_ass: val_old = t_as[0] val_new = t_as[1] for row in xrange(0, wt.rowCount()): r0 = wt.item(row, 0) if r0: if r0.text() == str(val_old): # Update value r1 = wt.item(row, 1) if isinstance(r1, QTableWidgetItem): r1.setText(str(val_new)) else: wt.setItem(row, 1, QTableWidgetItem(str(val_new))) #@pyqtSlot(str) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["CHANGES"]: item = TableReplaceInputDialog(self, param) elif param.name in ["MAP_CSV"]: item = FileSelectionCSVTXTPanel(param.isFolder, param.ext) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self, param) return item
class SlidingMultiParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.types_of_metrics = {} for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() self.changeWindowShapeDependent() # === param:WINDOW_SIZES Widget:IntListSelectionPanel === lineEdit = self.widgets["WINDOW_SIZES"].lineEdit lineEdit.setReadOnly(True) sbInt = self.widgets["WINDOW_SIZES"].sbInt sbInt.setValue(3) # === param:METRICS Widget:ListSelectionPanel === # === Init cbFilter cbFilter = self.widgets["METRICS"].cbFilter cbFilter.addItems(self.alg.types_of_metrics.keys()) # === Init listSrc value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() if self.types_of_metrics: if value in self.types_of_metrics.keys(): listSrc.addItems(self.types_of_metrics[value]) # === Init listDest listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() self.window_sizes_selected = set() lineEdit = self.widgets["METRICS"].lineEdit lineEdit.setReadOnly(True) ## = OUTPUTS_ASC_BOOL def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.initCalculateMetric) w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) w.cmbText.currentIndexChanged.connect(self.removeAllListDst) w.cmbText.currentIndexChanged.connect(self.changeMetricDependent) elif isinstance(w, IntListSelectionPanel): w.pbRight.clicked.connect(self.addIntInListDst) w.pbRemove.clicked.connect(self.removeIntInListDst) w.pbClear.clicked.connect(self.removeIntAllListDst) w.lineEdit.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, ListSelectionPanel): w.pbRight.clicked.connect(self.addInListDst) w.listSrc.itemDoubleClicked.connect(self.addInListDst) w.pbLeft.clicked.connect(self.removeInListDst) w.pbAll.clicked.connect(self.addAllInListDst) w.pbClear.clicked.connect(self.removeAllListDst) w.lineEdit.textChanged.connect(self.parametersHaveChanged) w.cbFilter.currentIndexChanged.connect(self.changeMetricDependent) elif isinstance(w, ValuesSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets["WINDOW_SHAPE"] w.currentIndexChanged.connect(self.changeWindowShapeDependent) w = self.widgets["WINDOW_SIZES"] w.sbInt.setSingleStep(2) # step incrementation and decrementation w = self.widgets["METRICS"].cbFilter w.currentIndexChanged.emit(0) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) self.widgets["INPUT_LAYER_ASC"].cmbText.currentIndexChanged.emit(0) #@pyqtSlot(str) def initCalculateMetric(self): w = self.widgets['INPUT_LAYER_ASC'] try: val = w.getValue() if isinstance(val, QgsRasterLayer): rasterLayerParam = val.source().encode('utf-8') else: rasterLayerParam = val.encode('utf-8') int_values_and_nodata = ChloeUtils.extractValueNotNull(rasterLayerParam) self.types_of_metrics = ChloeUtils.calculateMetric( self.alg.types_of_metrics, self.alg.types_of_metrics_simple, self.alg.types_of_metrics_cross, int_values_and_nodata ) except: self.types_of_metrics = [] # === param:WINDOW_SHAPE Widget:ComboBox #@pyqtSlot(str) def changeWindowShapeDependent(self): txt = self.widgets["WINDOW_SHAPE"].currentText() if txt == "FUNCTIONAL": self.widgets["FRICTION_FILE"].setEnabled(True) else: self.widgets["FRICTION_FILE"].setDisabled(True) # === param:OUTPUTS_ASC_BOOL Widget:CheckBox === #@pyqtSlot(str) def changesOuputASCBoolDependent(self): w = self.widgets["OUTPUTS_ASC_BOOL"] w_asc = self.widgets["VISUALISE_ASC_BOOL"] if w.isChecked(): w_asc.setEnabled(True) else: w_asc.setDisabled(True) # === param:WINDOW_SIZES Widget:IntListSelectionPanel === #@pyqtSlot(str) def addIntInListDst(self): """Add grid size integer in listSrc""" int_value = self.widgets["WINDOW_SIZES"].sbInt.value() # if len(self.window_sizes_selected) == 0: # constraint V1.0: "select only one" self.window_sizes_selected.add(str(int_value)) listDest = self.widgets["WINDOW_SIZES"].listDest listDest.clear() listDest.addItems(list(self.window_sizes_selected)) self.updateWindowsSizesLigneEdit() #@pyqtSlot() def removeIntAllListDst(self): """Remove all grid sizes in listDest""" listDest = self.widgets["WINDOW_SIZES"].listDest listDest.clear() self.window_sizes_selected = set() self.updateWindowsSizesLigneEdit() #@pyqtSlot(str) def removeIntInListDst(self): """Remove grid sizes selected in listDest""" selected = self.widgets["WINDOW_SIZES"].listDest.selectedItems() for lw in selected: self.window_sizes_selected.remove(lw.text()) listDest = self.widgets["WINDOW_SIZES"].listDest listDest.clear() listDest.addItems(list(self.window_sizes_selected)) self.updateWindowsSizesLigneEdit() def updateWindowsSizesLigneEdit(self): """update Gris sizes (QLineEdit in readOnly mode)""" lineEdit = self.widgets["WINDOW_SIZES"].lineEdit WINDOW_SIZES = list(self.window_sizes_selected) if WINDOW_SIZES: lineEdit.setText(";".join(WINDOW_SIZES)) else: lineEdit.setText("") # === param:METRICS Widget:ListSelectionPanel === @staticmethod def iterAllItems(lws): for i in range(lws.count()): yield lws.item(i) #@pyqtSlot(str) def addAllInListDst(self): self.addInListDst(all=True) #@pyqtSlot(str) def addInListDst(self,item=None,all=False): """Add metrics selected in listSrc to ListDst""" if not all: selected = self.widgets["METRICS"].listSrc.selectedItems() else: selected = self.iterAllItems(self.widgets["METRICS"].listSrc) for lw in selected: self.metrics_selected.add(lw.text()) listDest = self.widgets["METRICS"].listDest listDest.clear() listDest.addItems(list(self.metrics_selected)) self.updateMetricsLigneEdit() #@pyqtSlot() def removeAllListDst(self): listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() self.updateMetricsLigneEdit() #@pyqtSlot(str) def removeInListDst(self): """Remove metrics selected in listDest""" selected = self.widgets["METRICS"].listDest.selectedItems() for lw in selected: self.metrics_selected.remove(lw.text()) listDest = self.widgets["METRICS"].listDest listDest.clear() listDest.addItems(list(self.metrics_selected)) self.updateMetricsLigneEdit() def updateMetricsLigneEdit(self): """update Metrics (QLineEdit in readOnly mode)""" lineEdit = self.widgets["METRICS"].lineEdit metrics = list(self.metrics_selected) if metrics: lineEdit.setText(";".join(metrics)) else: lineEdit.setText("") #@pyqtSlot(str) def changeMetricDependent(self): """ Update metric source list when the filter of metric change """ cbFilter = self.widgets["METRICS"].cbFilter # === Init list metric value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() if self.types_of_metrics: if value in self.types_of_metrics.keys(): listSrc.addItems(self.types_of_metrics[value]) #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["WINDOW_SIZES"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = IntListSelectionPanel(self.parent, self.alg, param.default) elif param.name in ["METRICS"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = ListSelectionPanel(self.parent, self.alg, param.default) elif param.name in ["FILTER", "UNFILTER"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = ValuesSelectionPanel(self.parent, self.alg, param.default,'INPUT_LAYER_ASC') if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class FromShapefileParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, CSVFieldSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, CustomFileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) w.leText.textChanged.connect(self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, CSVFieldSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message)
class FromCSVParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) # Add bouton pb = QPushButton(self.tr("Import header")) self.layoutMain.insertWidget(4,pb) self.pbHeader = pb self.pbHeader.clicked.connect(self.uploadHeader) self.connectParameterSignals() self.parametersHaveChanged() def uploadHeader(self): dlg = QFileDialog() dlg.setFileMode(QFileDialog.AnyFile) dlg.setFilter("ASC File (*.asc);; TXT File (*.txt);;All File (*.*)") filenames = QStringList() if dlg.exec_(): filenames = dlg.selectedFiles() self.getWidgetFromParameter # Parse header acs file name with open(str(filenames[0]), 'r') as infile: for line in infile: values = line.strip().split(' ') if values[0] == "ncols": self.widgets["N_COLS"].spnValue.setValue(int(values[1])) elif values[0] == "nrows": self.widgets["N_ROWS"].spnValue.setValue(float(values[1])) elif values[0] == "xllcorner": self.widgets["XLL_CORNER"].spnValue.setValue(float(values[1])) elif values[0] == "yllcorner": self.widgets["YLL_CORNER"].spnValue.setValue(float(values[1])) elif values[0] == "cellsize": self.widgets["CELL_SIZE"].spnValue.setValue(float(values[1])) elif values[0] == "NODATA_value": self.widgets["NODATA_VALUE"].spnValue.setValue(int(values[1])) else: break def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, CSVFieldSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.cleanFieldDependent) # Clean w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) # elif isinstance(w, CustomFileSelectionPanel): # w.leText.textChanged.connect(self.parametersHaveChanged) # w.leText.textChanged.connect(self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, CSVFieldSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["FIELDS"]: # === Overload ParameterString for special parameter name like FIELDS,.. item = CSVFieldSelectionPanel(self.parent, self.alg, param.default) if param.default: item.setText(unicode(param.default)) elif param.name in ["INPUT_FILE_CSV"]: layers = dataobjects.getTables() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((layer.name(), layer)) # if already set, put first in list for i, (name, layer) in enumerate(items): if layer and layer.source() == param.value: items.insert(0, items.pop(i)) item = InputLayerSelectorPanel(items, param) # # === Overload ParameterString for special parameter name like FIELDS,.. # item = CSVFieldSelectionPanel(self.parent, self.alg, param.default) # if param.default: # item.setText(unicode(param.default)) # elif isinstance(param, ParameterFile): # # === Overload of Panel for Raster in order to add signal for updating param # item = CustomFileSelectionPanel(param.isFolder, param.ext) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParamValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()], context)): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description()))
class OverlayParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) #@pyqtSlot(str) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["INPUTS_MATRIX"]: options = dataobjects.getRasterLayers(sorting=False) opts = [self.getExtendedLayerName(opt) for opt in options] item = OrderedMultipleInputPanel(opts) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): wrapper.widgetValueHasChanged.connect(self.parametersHaveChanged) # TODO - remove when all wrappers correctly emit widgetValueHasChanged! # For compatibility with 3.x API, we need to check whether the wrapper is # the deprecated WidgetWrapper class. If not, it's the newer # QgsAbstractProcessingParameterWidgetWrapper class # TODO QGIS 4.0 - remove if issubclass(wrapper.__class__, WidgetWrapper): w = wrapper.widget else: w = wrapper.wrappedWidget() self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) for output_widget in self.outputWidgets.values(): self.connectWidgetChangedSignals(output_widget) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, DestinationSelectionPanel): w.destinationChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()])): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description())) except AlgorithmDialogBase.InvalidOutputExtension as e: self.text.setPlainText(e.message)
class ChloeParametersPanel(ParametersPanel): def __init__(self, parent, alg): super().__init__(parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("Chloe Command line")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() # def initWidgets(self): # """Init widget panel for each input output""" # super().initWidgets() # for output_name, output_panel in self.outputWidgets.items(): # # # Add check box for automacial load after process algorithm # # for 'OUTPUT_ASC' (QgsProcessingParameterFileDestination) # if output_name == 'OUTPUT_ASC': # check = QCheckBox() # check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file after running algorithm')) # # def skipOutputChanged(checkbox, skipped): # checkbox.setEnabled(not skipped) # if skipped: # checkbox.setChecked(False) # check.setChecked(not output_panel.outputIsSkipped()) # check.setEnabled(not output_panel.outputIsSkipped()) # # output_panel.skipOutputChanged.connect(partial(skipOutputChanged, check)) # self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) # self.checkBoxes[output_name] = check def initWidgets(self): # Heavy overload # If there are advanced parameters — show corresponding groupbox for param in self.alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.grpAdvanced.show() break #widget_context = QgsProcessingParameterWidgetContext() #if iface is not None: # widget_context.setMapCanvas(iface.mapCanvas()) # Create widgets and put them in layouts for param in self.alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue print('initWidgets - param.name(): {}'.format(param.name())) if param.isDestination(): # and param.name() != 'OUTPUT_ASC': continue else: wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent) self.wrappers[param.name()] = wrapper #widget = wrapper.widget # For compatibility with 3.x API, we need to check whether the wrapper is # the deprecated WidgetWrapper class. If not, it's the newer # QgsAbstractProcessingParameterWidgetWrapper class # TODO QGIS 4.0 - remove is_python_wrapper = issubclass(wrapper.__class__, WidgetWrapper) if not is_python_wrapper: from qgis.gui import (QgsProcessingContextGenerator, QgsProcessingParameterWidgetContext) widget_context = QgsProcessingParameterWidgetContext() if iface is not None: widget_context.setMapCanvas(iface.mapCanvas()) wrapper.setWidgetContext(widget_context) widget = wrapper.createWrappedWidget(self.processing_context) wrapper.registerProcessingContextGenerator(self.context_generator) else: widget = wrapper.widget #if self.in_place and param.name() in ('INPUT', 'OUTPUT'): # don't show the input/output parameter widgets in in-place mode # we still need to CREATE them, because other wrappers may need to interact # with them (e.g. those parameters which need the input layer for field # selections/crs properties/etc) # continue if widget is not None: if is_python_wrapper: widget.setToolTip(param.toolTip()) if isinstance(param, QgsProcessingParameterFeatureSource): layout = QHBoxLayout() layout.setSpacing(6) layout.setMargin(0) layout.addWidget(widget) button = QToolButton() icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png')) button.setIcon(icon) button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) button.setToolTip(self.tr('Iterate over this layer, creating a separate output for every feature in the layer')) button.setCheckable(True) layout.addWidget(button) layout.setAlignment(button, Qt.AlignTop) self.iterateButtons[param.name()] = button button.toggled.connect(self.buttonToggled) widget = QWidget() widget.setLayout(layout) label = None if not is_python_wrapper: label = wrapper.createWrappedLabel() else: label = wrapper.label if label is not None: if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.layoutAdvanced.addWidget(label) else: self.layoutMain.insertWidget( self.layoutMain.count() - 2, label) elif is_python_wrapper: desc = param.description() if isinstance(param, QgsProcessingParameterExtent): desc += self.tr(' (xmin, xmax, ymin, ymax)') if isinstance(param, QgsProcessingParameterPoint): desc += self.tr(' (x, y)') if param.flags() & QgsProcessingParameterDefinition.FlagOptional: desc += self.tr(' [optional]') widget.setText(desc) if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.layoutAdvanced.addWidget(widget) else: self.layoutMain.insertWidget( self.layoutMain.count() - 2, widget) for output in self.alg.destinationParameterDefinitions(): if output.flags() & QgsProcessingParameterDefinition.FlagHidden: continue #if self.in_place and param.name() in ('INPUT', 'OUTPUT'): # continue label = QLabel(output.description()) #print('initWidgets 2 - param.name(): {}'.format(param.name())) widget = DestinationSelectionPanel(output, self.alg) # TODO, overload self.layoutMain.insertWidget(self.layoutMain.count() - 1, label) self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget) if isinstance(output, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorDestination # alk: checkboxes for Chloe handling ,ChloeCSVParameterFileDestination, ChloeASCParameterFileDestination, ChloeParameterFolderDestination) ): check = QCheckBox() check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file(s) after running algorithm')) def skipOutputChanged(checkbox, skipped): checkbox.setEnabled(not skipped) if skipped: checkbox.setChecked(False) check.setChecked(not widget.outputIsSkipped()) check.setEnabled(not widget.outputIsSkipped()) widget.skipOutputChanged.connect(partial(skipOutputChanged, check)) self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) self.checkBoxes[output.name()] = check # initial state if hasattr(output,'addToMapDefaultState'): check.setChecked(output.addToMapDefaultState) widget.setToolTip(param.toolTip()) self.outputWidgets[output.name()] = widget for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) # # alk: checkboxes for Chloe handling # for output in self.alg.destinationParameterDefinitions(): # if output.flags() & QgsProcessingParameterDefinition.FlagHidden: # continue # if isinstance(output, (ChloeCSVParameterFileDestination)) or isinstance(output, (ChloeASCParameterFileDestination)): # check = QCheckBox() # check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file(s) after running algorithm')) # def skipOutputChanged(checkbox, skipped): # checkbox.setEnabled(not skipped) # if skipped: # checkbox.setChecked(False) # check.setChecked(not widget.outputIsSkipped()) # check.setEnabled(not widget.outputIsSkipped()) # widget.skipOutputChanged.connect(partial(skipOutputChanged, check)) # print(str(self.layoutMain)+1) # self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) # self.checkBoxes[output.name()] = check # # connecting alg outputLoading info with checkbox state # self.alg.outputLoading[output.name()] = check.isChecked() # def updateOutputLoadingState(alg, outputName, checkbox, state): # self.alg.outputLoading[outputName] = checkbox.isChecked() # print( outputName + " " + str(checkbox.isChecked()) + " " + str(self.alg.outputLoading) + " " + str(self.alg)) # #print(str(self.alg.parameters)) # check.stateChanged.connect(partial(updateOutputLoadingState, self, output.name(), check)) # alk: addition of wrapper special config handling # for dependancy between wrapper, i.e. changing the value # of a FileSelectionPanel entails the update of another widget for k in self.wrappers: w = self.wrappers[k] if hasattr(w,'getParentWidgetConfig'): print(str(w) + " " + "getParentWidgetConfig") config = w.getParentWidgetConfig() if config != None: p = self.wrappers[config['paramName']] m = getattr(w, config['refreshMethod']) if m!=None: print(str(p) + " " + str(p.widget)) # todo generalize valueChanged handling # to any type of widget componant if isinstance(p.widget, FileSelectionPanel): p.widget.leText.textChanged.connect(m) elif isinstance(p, RasterWidgetWrapper): try: p.combo.valueChanged.connect(m) # QGIS 3.8 version except: p.combo.currentIndexChanged.connect(m) # QGIS LTR 3.4 def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): wrapper.widgetValueHasChanged.connect(self.parametersHaveChanged) # TODO - remove when all wrappers correctly emit widgetValueHasChanged! # For compatibility with 3.x API, we need to check whether the wrapper is # the deprecated WidgetWrapper class. If not, it's the newer # QgsAbstractProcessingParameterWidgetWrapper class # TODO QGIS 4.0 - remove if issubclass(wrapper.__class__, WidgetWrapper): w = wrapper.widget else: w = wrapper.wrappedWidget() self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) for output_widget in self.outputWidgets.values(): self.connectWidgetChangedSignals(output_widget) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, DestinationSelectionPanel): w.destinationChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()])): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description())) if e.parameter.name()=='MAP_CSV': raise