Thanks Germán, your suggestion works great. Now I have the code up and running again!
Cheers 2010/9/4 Germán Carrillo <carrillo.ger...@gmail.com>: > Hi Ricardo, > what if you use the legendInterface class for getting the loaded layers? > Try this (in the Python console): > ------------------------------------------------------- > from PyQt4.QtCore import SIGNAL > q = qgis.utils.iface > l = q.legendInterface() > def f( layerId ): > for i in l.layers(): > print i.name(), i.geometryType() > q.connect( QgsMapLayerRegistry.instance(), SIGNAL( > "layerWillBeRemoved(QString)" ), f ) > ------------------------------------------------------- > I'm not sure it works if the user starts a new project... > Regards, > Germán > > On Sat, Sep 4, 2010 at 7:53 AM, Ricardo Filipe Soares Garcia da > <ricardo.garcia.si...@gmail.com> wrote: >> >> Hi list >> >> I'm trying to toggle my plugin's availability based on the presence or >> absence of loaded vector layers of type 'line'. >> For this purpose I have a _get_loaded_layers() and a >> toggle_availability() methods (code follows in the end of this >> message). >> >> After searching the online API docs, it seems that the >> QgsMapLayerRegistry class is the one that notifies the rest of the >> application about layers being added or removed. >> So I connect my plugin's toggle_availability() method to the >> layerWasAdded() and layerWillBeRemoved() signals of the >> QgsMapLayerRegistry.instance() object. >> >> When the user adds a new layer everything goes fine, my plugin's >> availability is toggled based on the presence of vector lines, >> including the new layer that was added. >> Also, if the user removes just one layer at a time, everything works >> as expected as well. >> >> Unfortunately, when several layers are removed at the same time (for >> example, if the user had an open project and decides to create a new >> one), my plugin is causing Qgis to segfault (very ugly!). >> >> It seems to be connected to what is happening with the >> QgsmapLayerRegistry instance when the layerWillBeRemoved() signal is >> emmited repeatedly. It seems to me that I am crashing Qgis because I >> am trying to call QgsMapLayerRegistry.instance().mapLayers() while the >> layers are being deleted... and that causes the segfault. >> I don't know what happens to the mapLayerRegistry instance, but its >> mapLayers() method seems to be the source of the error. >> >> Reading the pyQgis cookbook, I realized that when layers are removed >> from the mapLayerRegistry they are also deleted from Qgis, which seems >> a bit inconsistent, compared with the loading procedure. What I mean >> is, if layers can be loaded without being automatically added to the >> mapLayerRegistry, maybe they could also be removed from the >> mapLayerRegistry without being deleted from Qgis (Maybe this is the >> reason for having a layerWillBeRemoved() signal instead of a >> layerWasRemoved()?). >> >> Anyway, I don't understand why it works OK if layers are removed one >> at a time and not if they all get removed. >> I've tried to use the QgsMapLayerRegistry.removedAll() signal to catch >> those situations when all layers get removed at once. It does work, >> but the problem is that the QgsMapLayerRegistry.layerWillBeRemoved() >> is still geting called at the same time and will crash Qgis. >> >> So, I'd like to request your help in determining the best way to be >> notified when a layer is removed from the map canvas. >> >> Thanks >> >> #(python code follows) >> >> >> def initGui(self): >> self.action = QAction(QIcon(":/plugins/ProfileFromLine/icon.png"), >> \ >> "Profile from line", self.iface.mainWindow()) >> self.toggle_plugin_availability() >> QObject.connect(self.action, SIGNAL("activated()"), self.run) >> self.iface.addToolBarIcon(self.action) >> self.iface.addPluginToMenu("&Profile from line", self.action) >> QObject.connect(self.layerRegistry, >> SIGNAL("layerWasAdded(QgsMapLayer *)"), >> self.toggle_plugin_availability) >> QObject.connect(self.layerRegistry, >> SIGNAL("layerWillBeRemoved(QString)"), >> self.toggle_plugin_availability) >> >> >> def _get_loaded_layers(self): >> availableLayers = {"vectorLine" : [], "raster" : []} >> loadedLayers = self.layerRegistry.mapLayers() >> for layer in loadedLayers.itervalues(): >> layerType = layer.type() >> if layerType == 0: # it's a vector layer >> if layer.geometryType() == 1: # it's a line >> availableLayers["vectorLine"].append(layer) >> elif layerType == 1: #it's a raster layer >> availableLayers["raster"].append(layer) >> return availableLayers >> >> def toggle_plugin_availability(self, arg=None): >> print("toggle_plugin_availability method called") >> numLinesLayers = len(self._get_loaded_layers()["vectorLine"]) >> if numLinesLayers == 0: >> self.action.setEnabled(False) >> elif numLinesLayers == 1 and type(arg) == QString: >> layerAboutToGo = self.layerRegistry.mapLayer(arg) >> if layerAboutToGo.type() == 0: >> if layerAboutToGo.geometryType() == 1: >> self.action.setEnabled(False) >> >> >> >> -- >> ___________________________ ___ __ >> Ricardo Garcia Silva >> _______________________________________________ >> Qgis-developer mailing list >> Qgis-developer@lists.osgeo.org >> http://lists.osgeo.org/mailman/listinfo/qgis-developer > > -- > ----------- > |\__ > (:>__)( > |/ > > Soluciones Geoinformáticas Libres > http://geotux.tuxfamily.org/ > -- ___________________________ ___ __ Ricardo Garcia Silva _______________________________________________ Qgis-developer mailing list Qgis-developer@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/qgis-developer