I have been working on a PyQGIS project for a bit, and I have been using QgsProject.instance().addMapLayer
to add layers to the map.
However, now I need to add layers to my canvas and legend in specific groups, so I changed my logic for adding layers to the map to use the underlying QgsLayerTree
object to add groups and add layers to those groups. I got it working, but it also introduced a new problem:
Whenever I add a layer to the map within a layer group using the new logic, the layer is not available whenever QGIS is restarted. The QgsLayerTreeLayer
instances of the layers are still available, but it looks like they can't resolve their references to their source or other metadata. From what I can tell, it looks like they only have access to the layer ID.
How do I persist the layer tree between QGIS sessions? Or is there another way to implement adding layers within groups that would avoid this problem?
Adding Layers to Map
layer = QgsRasterLayer(...)
root = QgsProject.instance().layerTreeRoot()
group = root.insertGroup('Layers')
group.insertLayer(0, layer)
Reading Layers after QGIS Restart
root = QgsProject.instance().layerTreeRoot()
layer_tree_layers = root.findLayers() # Returns list of QgsLayerTreeLayer objects
map_layers = []
for lyr in layer_tree_layers:
map_layer = lyr.layer() # Once QGIS has restarted, returns None!
map_layers.append(map_layer)
I saw that in the QGIS API Documentation, it noted that the QgsLayerTreeLayer.layer()
may return None/nullptr "...in the case of a layer node representing a layer which has not yet been fully loaded into a project, or a layer node representing a layer with an invalid data source...."
So why does my QGIS workspace persist normal map layers between instances, but not QgsLayerTreeLayers
that were added to the map programmatically or is there an error in my logic that is causing this?
Note: The layers that I am loading into the map are QgsRasterLayers that have been read from geopackage tables. Didn't think it had anything to do with this because I am instantiating the layer objects from the source in the same way as I would any other layers. But just thought I'd mention it.