[QGIS-Developer] Processing alg - best solution for a "value relation" form input ?

Nyall Dawson nyall.dawson at gmail.com
Thu Jun 27 16:42:54 PDT 2019


On Thu, 27 Jun 2019 at 22:24, kimaidou <kimaidou at gmail.com> wrote:
>
> Hi,
>
> I would like to propose a QgsProcessingParameterEnum automatically filled with data from a layer, exactly in the same way QGIS does with the form value relation widget.
> Basically, the alg author would choose the layer, the key field, the value field, to order or not by value, and an optionnal filter.

Do you mean the layer is hardcoded here? How would that work? You'd
need to guarantee somehow that the layer is always available wherever
your algorithm is used. (That would be ok for a plugin I guess, where
you could package up a layer with the algorithm)

> I would like to know if someone had already done it, and if so, I there is some example code online.
>
> If not, I think I would do this:

I think there's two use cases to consider here.

1. Some predefined list of values which you want to expose through the
GUI, but you don't want to hardcode these, and instead want to
populate them from a SPECIFIC layer instead. In this case, I'd say you
could just do this using the existing api and reading through that
layer to populate the choices exposed in QgsProcessingParameterEnum
(but be wary of performance costs... algorithm parameters are read at
the same time your algorithm is registered with Processing, so this
could potentially impact QGIS launch speed).

2. Expose a list of field values based on a dynamic choice of layer
and field. I.e. your algorithm has a vector layer/feature source
parameter and a field parameter, and you want to show values from this
layer/field choice. It's like an extension of the existing field
parameter, where the listed fields are dependant on another
parameter's (the layer parameter's) value. It's just another level
deep, because the choices would depend on both the layer parameter AND
field parameters values. In this case this does sound like a new
parameter type would be warranted to address this use case, something
like QgsProcessingParameterExistingFieldValue. Potentially, this
parameter type could have options for either taking the layer (and
field name) choices from other parameters OR you could hard code a
value for them instead. Similarly, you could have a setting for the
parameter for overriding the "display field" choice, allowing
value/code type handling.

> Or I could also use the setMetadata method with a widget_wrapper, such as done for the ConnectionWidgetWrapper ?
>         db_param.setMetadata({
>             'widget_wrapper': {
>                 'class': 'processing.gui.wrappers_postgis.ConnectionWidgetWrapper'
>             }
>         })

I'd steer away from using metadata as much as possible. It's extremely
fragile and ill-defined.

Another note: If you're writing this as a candidate for inclusion in
master, please do so in c++ and ensure that any gui widgets use the
new c++ classes and api (not the deprecated Python WidgetWrapper api).
Time and time again Python has proved its fragility in handling core
Processing functionality, and we're never going to avoid future bugs
like https://github.com/qgis/QGIS/issues/30406 unless we stop using it
for ALL core Processing code.

Nyall




> and then do the magic inside a dedicated class ? How ?
>
> Any help appreciated.
>
> Regards,
> Michaƫl
> _______________________________________________
> QGIS-Developer mailing list
> QGIS-Developer at lists.osgeo.org
> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer


More information about the QGIS-Developer mailing list