When I try to load many huge rasterlayer into QGIS it blocks the UI. So I try to implement a QGIS-batch-raster-loading task in order to keep QGIS responsive.
Calling the task itself from within my plugin works so far but I cannot add layers to my project like this:
project = QgsProject.instance()
project.addMapLayers([my_array])
In the QGIS docs this warning is written:
Any background task (regardless of how it is created) must NEVER use any QObject that lives on the main thread, such as accessing QgsVectorLayer, QgsProject or perform any GUI based operations like creating new widgets or interacting with existing widgets. Qt widgets must only be accessed or modified from the main thread. Data that is used in a task must be copied before the task is started. Attempting to use them from background threads will result in crashes.
I wonder if this means that it is just not possible to bulk add layers from within a QgsTask or if I miss something?
The main snippet of my code is:
class RandomIntegerSumTask(QgsTask):
"""This shows how to subclass QgsTask"""
def __init__(self, description, duration, layer):
super().__init__(description, QgsTask.CanCancel)
self.duration = duration
self.total = 0
self.iterations = 0
self.exception = None
self.layer=layer
def addRasterLayer(self,layers_to_add, project):
layerarray=[]
mycrs = QgsCoordinateReferenceSystem.fromEpsgId(25832)
for path,name in layers_to_add.items():
print (path, name)
rlayer = QgsRasterLayer(path, name)
if rlayer is None:
continue
rlayer.setCrs(mycrs,True)
layerarray.append(rlayer)
project.addMapLayers([rlayer])
def run(self):
"""Here you implement your heavy lifting.
Should periodically test for isCanceled() to gracefully
abort.
This method MUST return True or False.
Raising exceptions will crash QGIS, so we handle them
internally and raise them in self.finished
"""
try:
project = QgsProject.instance()
self.layers_to_add={}
for path in self.layer:
name = QFileInfo(path).baseName()
self.layers_to_add[path]=name
self.addrasterlayer(self.layers_to_add,project)