4

I am trying to run a processing script without a user defined layer output. The example below should create a vector layer with one point. The script runs without any error but the layertree is empty. If you run an other script afterwards, for example "Buffer" the layer is available and you can buffer the result from the script below.

What do I miss to make the created layer available for the layertree? My guess is that QgsProject.instance().addMapLayer(vl) does not work with the alg class? I know that the correct usage of the processing script would be using a QgsFeatureSink, but I am trying to do it the way below to get more control over the result layer.

from qgis.processing import alg
from qgis.PyQt.QtCore import QVariant
from qgis.core import QgsProject, QgsFeature, QgsField, QgsGeometry, QgsPointXY, QgsVectorLayer

@alg(name="test123", label=alg.tr("test123"), group="geophysics", group_label=alg.tr("Geophysics"))
@alg.output(type=alg.NUMBER, name="OUTPUT", label='Number of features processed')
def test123(instance, parameters, context, feedback, inputs):
    """
    tries to add a vectorlayer through a processing script
    """
    vl = QgsVectorLayer("Point", "Hello", "memory")
    pr = vl.dataProvider()
    pr.addAttributes([QgsField("name", QVariant.String),
              QgsField("field1",  QVariant.Int),
              QgsField("field2", QVariant.Double)])
    vl.updateFields() 

    f = QgsFeature()
    f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(20,20)))
    f.setAttributes(["Hello QGIS", 100, 10.1])
    pr.addFeature(f)
    vl.updateExtents() 
    QgsProject.instance().addMapLayer(vl)
    if vl.isValid():
       QgsProject.instance().addMapLayer(vl)
       out = 1
    else:  
       out = 0 
    return {"OUTPUT":out}

enter image description here

Vince
  • 20,017
  • 15
  • 45
  • 64
eurojam
  • 10,762
  • 1
  • 13
  • 27
  • 1
    You can try to refresh your project iface.mapCanvas().refresh() but I think the problem is more on the side of your v1 layer. Is your v1 layer is valid? – Vincent Bré Dec 16 '19 at 07:36
  • @Cyril: I use the german QGIS Interface: german word for Buffer is Puffer;-) – eurojam Dec 16 '19 at 07:52
  • @Vincent: running the part from creating the vectorlayer until adding it to the project runs fine from the console – eurojam Dec 16 '19 at 07:54
  • 1
    Hi @eurojam, I can't fully answer your question, but as I understand it, interacting with the project instance is not thread safe and doing so in a processing script (which run in a background thread by default) can lead to unpredictable behavior. There was a similar question fairly recently (which I can't find now) where Nyall Dawson outlined this in a comment. I'm not really familiar with the new @alg decorator style of processing script- I am accustomed to the older style of sub-classing QgsProcessingAglorithm, where you can re-implement the flags() method... – Ben W Dec 17 '19 at 08:06
  • 1
    ...and return the NoThreading flag. It must be possible to do the same with the new style of script (which I think Nathan Woodrow developed) but I'm not sure how! – Ben W Dec 17 '19 at 08:08
  • 1
    Thanks a lot Ben, I've found the thread you talking about: https://gis.stackexchange.com/questions/278406/getting-layertree-reference-in-processing-script-in-qgis-3 – eurojam Dec 17 '19 at 12:58
  • No worries :-) That's actually a different thread again! But that one looks really useful. – Ben W Dec 17 '19 at 13:35
  • 1
    I've played around with the flags, but did't get it to work with the new style processing script. Using the 'old' style it works if you set the QgsProcessingAlgorithm.FlagNoThreading Flag...thanks again for the discussion – eurojam Dec 19 '19 at 17:50

0 Answers0