Our QGIS project is dynamically generated on startup based on user roles. There are nearly 120 QgsVectorLayers that need to be generated. If created sequentially, the login process takes up to 2 minutes which is really annoying.
So, I thought I'll use a QThreadPool and create the layers in there. So, the threads basically just call this kind of code:
class LayerLoaderWorker(QRunnable):
def run(self):
db_connect = DatabaseConnection()
uri = QgsDataSourceUri()
uri.setConnection(db_connect.host, str(db_connect.port), db_connect.dbname, db_connect.user,
db_connect.password)
uri.setDataSource('public', self.viewname, 'geometry', '', 'id')
locker = QMutexLocker(mutex)
self.layer = QgsVectorLayer(uri.uri(False), self.layerSettings.displayname, "postgres")
self.finished = True
self.loader.workerFinished()
locker.unlock()
Only the layers are created in the threads, after creation they are added to the QgsProject
in the main (UI) thread.
Sometimes it seems to work, but most of the time the layers are not loaded correctly and the geometry column is empty.
Is the creation of the QgsVectorLayer
object thread safe? It seems to me that this isn't the case. I read somewhere that UI-related things should be handled in the UI-Thread, but I thought creating the object (which seems to connect to the database which takes some time) is a non-ui-task.
Is it possible to load layers in parallel somehow?