I'm trying to load a qlr-file in QGIS 3.16 and zoom to a certain area using python:
QgsLayerDefinition.loadLayerDefinition('E:/QGIS/test.qlr',QgsProject.instance(), QgsProject.instance().layerTreeRoot())
iface.mapCanvas().setCenter(QgsPointXY(712345,5123456))
iface.mapCanvas().zoomScale(2200)
print ("done")
I would expect the loadLayerDefinition-command to be completed before the setCenter- and zoomScale-commands are executed. But when I run this script with no layer in the layertree QGIS prints "done" (the last command) before it even starts to draw the loaded layer on the map and finally zooms to a full extent instead of zooming to the scale of '2200'.
How can I make QGIS to finish loading the qlr-file before continuing with the next command?
1 Answer 1
I concur with your observations and tried a few approaches to solve the problem. I don't love this approach, but it does seem to work effectively.
The workaround is to connect the mapCanvasRefreshed
signal, which will be emmitted when the canvas is redrawn after the layer definition file has been loaded, to a slot function which immediately disconnects the slot from from the signal (since the mapCanvasRefreshed
signal is also fired on zooming, panning etc.), then sets the canvas center and zoom level.
project = QgsProject.instance()
filepath = 'E:/QGIS/test.qlr'
def set_scale():
# disconnect the slot from the signal immediately
iface.mapCanvas().mapCanvasRefreshed.disconnect(set_scale)
iface.mapCanvas().setCenter(QgsPointXY(712345,5123456))
iface.mapCanvas().zoomScale(2200)
print ("done")
# connect set_scale function to mapCanvasRefreshed signal which will be emmitted
# when the canvas is redrawn **after** the layer definition file has been loaded
iface.mapCanvas().mapCanvasRefreshed.connect(set_scale)
QgsLayerDefinition.loadLayerDefinition(filepath, project, project.layerTreeRoot())