[Qgis-developer] PyQGIS: Problems with the layerWasAdded SIGNAL

Martin Dobias wonder.sk at gmail.com
Tue Jun 16 07:51:13 EDT 2009


2009/6/16 Germán Carrillo <carrillo.german at gmail.com>:
> Hi Martin.
>
> I create the layers like the PyQGIS Wiki says:
>
> ( For shapefiles)  layer = QgsVectorLayer( layerPath, layerInfo.fileName(),
> layerProvider )
> Where layerPath is a QFileDialog result and layerProvider is "ogr".
>
> If the layer is valid, I call a function to add it to canvas:
>
>   if layer.isValid():
>     self.agregarCapa( layer )
>
>   def agregarCapa( self, capa ):
>     QgsMapLayerRegistry.instance().addMapLayer( capa )
>     self.layers.insert( 0, QgsMapCanvasLayer( capa ) )
>     self.canvas.setLayerSet( self.layers )
>
> I remove layers from the Legend class:
>     for i in self.layers:
>       if i.layer().getLayerID() == self.currentItem().layerId:
>         self.layers.remove( i )
>         QgsMapLayerRegistry.instance().removeMapLayer(
> i.layer().getLayerID() )
>         self.canvas.setLayerSet( self.layers )
>         break
>
> Then I remove the QTreeWidgetItem:
>         self.takeTopLevelItem( self.indexOfTopLevelItem( myItem ) )
>
> Like in the QGIS legend, I have an item for the layer name and its geometry
> type and a child item for its symbology.
> The parent item (the layer item) has the attribute canvasLayer to reference
> it and access its functions and attributes.
>
> I'm using this connect line:
> self.connect( QgsMapLayerRegistry.instance(),
> SIGNAL("layerWasAdded(QgsMapLayer *)"), self.legend.addLayerToLegend )
>
> The legend has another connect line to update the layer status:
>   self.connect( self, SIGNAL("itemChanged(QTreeWidgetItem *,int)"),
> self.updateLayerStatus )
>
> When all it's ok, remove layer always returns two lines like this:
> Object::disconnect: Unexpected null parameter

I think I know where's the problem: you remove the map layer and then
update layer set in canvas. When updating the layer set, the layers
which have been removed get disconnected from the slots of map canvas.
But that time your layer doesn't exist anymore and the pointer is
invalid - thus the disonnect warning or a crash.

So the solution should be to swap those two lines. Another way would
be to connect to registry's layerWillBeDeleted signal (which is
emitted in removeMapLayer() method when the layer still exists) and
update the GUI and canvas. This would be a bit cleaner solution if
there were more places in code where you remove a layer.

Martin


More information about the Qgis-developer mailing list