[Qgis-developer] QGIS Processing Framework

Martin Dobias wonder.sk at gmail.com
Fri Apr 29 11:17:41 EDT 2011

On Fri, Apr 29, 2011 at 12:31 PM, Julien Malik <julien.malik at c-s.fr> wrote:
>> Then, each library might require some additional parameter types that
>> might also require special editing widgets. The plugin implementing
>> support for such library will provide these types and editing widgets,
>> however they will stay opaque for QGIS. So in the result QGIS will
>> just know there is a parameter and it will know what widget to show in
>> the form, nothing more. Of course such custom types would not be
>> usable across various libraries, but that fine.
> OK, it seems a good balance.
> Is this good time to begin laying down this list somewhere ?

Camilo has started a wiki page regarding the parameter types, so that
is probably a good starting point:

It would be good to make a also review of GRASS and WPS types at the same time.

> Any idea about how to handle the 'non Qgis supported' parameters types for
> the Python API ?

This is how I think the API could look like - take it as a _very_ rough draft:

1. query module's parameters

>>> framework.getModules()
[ 'SAGA_Module1', 'GRASS_ModuleABC', 'FooModule' ]
>>> module = framework.getModule('SAGA_Module1')
>>> module.getParameters()
{ 'a' : ParameterInfo(type='int', default=321),
  'b' : ParameterInfo(type='RasterLayer', default=None),
  'c' : ParameterInfo(type='CustomSaga', default=<CustomSagaParameter>)

>From this you can see that QGIS would know the basic types such as
integer or layer, for the custom parameter types (e.g. a list of
points) it would only know the type name, the value would be opaque -
known only to the implementer.

2. execute modules (considering 3 input parameters and one output layer)

>>> module.setParameter('a', 123)
>>> module.setParameter('b', mylayer)
>>> module.setParameter('c', CustomSagaParam(1,2,3))
>>> module.execute()
>>> newlayer = module.output()

or with more Python syntax sugar:

>>> module.execute( a = 123, b = mylayer, c = CustomSagaParam(1,2,3) )
>>> newlayer = module.output()

Here we create an instance of the custom parameter type. The caller
has to know how to create the instance, QGIS only passes this custom
value to the implementation.

3. implement a module

class CustomSagaParam( QgsParameter ):
  def __init__(self, ...):
    # initialization of the parameter's value
  def type(self): # unique type name of the parameter type
    return 'CustomSaga'

>>> framework.registerParameterType( 'CustomSaga' )

This is an implementation of a custom parameter type. It would be
derived from abstract QgsParameter class (also parent of basic types
like QgsIntParameter or QgsRasterLayerParameter). It has to provide
type name so that QGIS knows the type. The custom parameter types
should be probably also registered to the framework so that QGIS can
perform sanity checks whether module's parameter types are fine.

class SagaModule( QgsModule ):
  def __init__(self, name, parameters):
     # store the name and parameters

  def execute():
    # prepare a command for OS from the parameters or execute it using API

QgsModule should be an abstract base class from the framework, it
would allow querying/setting parameters, all modules would have to
implement execute() method. This SagaModule is a generic
implementation for running all saga modules. Then during runtime the
SAGA plugin (adapter) will enumerate available modules in SAGA library
and create instances of SagaModule for them with appropriate names and

>>> framework.addModule( SagaModule( name = 'Module1', parameters = { ... } )

[I hope it makes some sense]

>> . Here QGIS would provide
>> default GUI for a module based on the description, with the
>> possibility for the developer to improve the basic behavior using Qt
>> signals and slots for a better user experience.
> Are signals and slots sufficient ?
> Maybe being able to provide a subclass of the default Qgis supported widgets
> would be cool ?

Custom subclasses should be supported - after all that's usually most
logical place where to do the signals/slots business.

>> I completely agree that many times the dependencies between the
>> parameters are far too complex to be modelled in a declarative way. I
>> hope my answer above clarifies this: you as a developer of the
>> orthorectification module would be allowed to watch for changes in the
>> form (using Qt signals) and update other parameters - or do whatever
>> you want.
> Yes it's more clear.
> We should consider not only being able to update the parameters values, but
> also the GUI part (changing some widget settings, eventually even changing
> the widget class somehow ?).

We could probably handle this with three possible cases:
- the default (auto-generated) GUI is fine - no changes
- the default GUI should be improved - a subclass just adds some bells
and whistles
- the default GUI is not sufficient - a completely custom GUI is used instead

These cases bring various stages of flexibility with different amounts
of required maintenance.

> Having "groups" of parameters is a need.
> If I'm not wrong, SAGA has this also (it's called Node). Camilo ?
> Also we want to have parameters shown only depending on a combobox value,
> for example.
> So a choice parameter value is declared with both what to show in the
> combobox, and an associated "parameter group".
> Please see at the end of
> http://wiki.orfeo-toolbox.org/index.php/OTB-Wrapper.
> If in this group you have another choice parameter, you end up with a
> tree...
> If you have a good idea to model that in a simpler way, I'll take it.
> Flat parameter model, but the GUI can rearrange/show/hide them dynamically ?

I would be more happy with flat parameter model. The rearangements of
GUI are doable. In Qt there is QStackedWidget class that basically
places several forms into one piece of space and allows the programmer
to select the current form as he likes.


More information about the Qgis-developer mailing list