Let's say my algorithm returns many layers and I need to insert those layers into the specific index in layer list, while running algorithm.

QgsProject.instance().layerTreeRoot() worked in QGIS 2 and I could change layers indexes as described in QGIS Layer Tree API (Part 2), while Processing algorithm was running.

How can I do the same thing in QGIS 3 Processing script?

I took a glance at QgsProcessingAlgorithm Class Reference. There are some functions like parameterAs****(). I thought one of them could help me. But I couldn't find useful function. I can get layer, layer list, crs etc. by means of some. But I can't get the layer tree (layerTreeRoot) or the project (QgsProject) reference.

  • @csk, I didn't find anything about the question. Apr 5 '18 at 19:45
  • I should have said, look at the changelog to see if that change is documented. If you already did that, edit your question to mention which sources you've already looked at. Otherwise people will waste their time and yours by suggesting solutions you've already tried.
    – csk
    Apr 5 '18 at 19:49
  • 1
    Be careful doing this - you'll need to make sure your algorithm correctly returns the flag to indicate that it can't be run in the background thread, or you'll open the way for all sorts of crashes
    – ndawson
    Apr 5 '18 at 19:58
  • You mean QGIS 2? I tried in QGIS 2, it worked without crashing. But I know that it doesn't work QGIS 3.0. Apr 5 '18 at 20:01

It will be possible in 3.2 in standard algorithms through the use of QgsProcessingLayerPostProcessorInterface.

For 3.0, you'll need to grab the project's layer tree from context.project().layerTreeRoot() and manipulate it directly. But be aware that this isn't safe to do in anything but the main thread, so in 3.0 where there's no concept of layer post-processors (which run in the main thread) you'll need to tag your whole algorithm as thread-unsafe, by returning the QgsProcessingAlgorithm.FlagNoThreading flag in your algorithm's flags() implementation.

  • Thank you. I'll be careful. It worked after adding those lines: def flags(self): return super().flags() | QgsProcessingAlgorithm.FlagNoThreading. Apr 6 '18 at 3:46
  • Looks perfect to me!
    – ndawson
    Apr 6 '18 at 4:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.