QGIS – Zoom Canvas to Selected Features with Python Call from QGIS Layer Action

actionslayerspyqgisqgisqgis-2.12

I have been trying to get one layer's clicked-on feature to have an effect on another layer's viewed features with some success, but I am unable to get the map canvas to be filled by the the selected layer's features when using python code called from within the layer actions call.

For reference, I have two layers – one not referred to in the code is a layer of zones. The other (referred to below) is the same zones intersected with same to identify all zones with their neighbouring zones. My intention is that on clicking on a zone in the former layer, I get the neighbouring zones highlighted, and zoomed to as a seamless operation.

When I run this code from the python console, it behaves exactly as I was hoping for:

registry = QgsMapLayerRegistry.instance();
name= 'intersecting_zones';
layer = registry.mapLayersByName( name )[0];
layer.removeSelection();
expr = QgsExpression("\"msoa_code_\"='E02002869'");
it = layer.getFeatures(QgsFeatureRequest(expr));
ids = [i.id() for i in it];
layer.setSelectedFeatures(ids);
box = layer.boundingBoxOfSelected();
iface.mapCanvas().setExtent(box);
iface.mapCanvas().refresh();

This will not work in the exact form within the python call of the original layer's action properties and I have understood that instead of using iface, I needed to switch to using a reference to QgsMapCanvas, hence I use code of the following form – first easy to read, second same code in the single line for use within Layer Actions.

from qgis.coreimport QgsApplication;
from qgis.gui import QgsMapCanvas;
registry = QgsMapLayerRegistry.instance();
canvas = QgsMapCanvas();
name= 'intersecting_zones';
layer = registry.mapLayersByName( name )[0];
layer.removeSelection();
expr = QgsExpression("\"msoa_code_\"='[% "msoa_code_" %]'");
it = layer.getFeatures(QgsFeatureRequest(expr));
ids = [i.id() for i in it];
layer.setSelectedFeatures(ids);
canvas.setExtent(layer.extent());
canvas.refresh();

from qgis.core import QgsApplication; from qgis.gui import QgsMapCanvas; registry = QgsMapLayerRegistry.instance(); canvas = QgsMapCanvas(); name= 'intersecting_zones'; layer = registry.mapLayersByName( name )[0]; layer.removeSelection(); expr = QgsExpression("\"msoa_code_\"='[% "msoa_code_" %]'"); it = layer.getFeatures(QgsFeatureRequest(expr)); ids = [i.id() for i in it]; layer.setSelectedFeatures(ids); canvas.setExtent(layer.extent()); canvas.refresh();

This code (from within Layer Actions) works to a point, I get no error message and the desired target features are selected. However, I cannot get the zoom to selected features functionality to work at all. Am I using the pyqgis code incorrectly, or is there some other approach I should be using to get this last bit working?

Best Answer

Try this code snippet to zoom to selected features of the layer:

canvas = qgis.utils.iface.mapCanvas()
canvas.zoomToSelected(layer) # zooms to selected feature extent for layer