I have a custom form that calculates some area values, I'd like to automatically fill the base field using the geometry of the feature if the user hasn't set some value specifically. So I have the following code:

def formOpen(dialog,layerid,featureid):
    global sqMField
    sqMField = dialog.findChild(QLineEdit,"property_area_m2")
    global sqFtField
    sqFtField = dialog.findChild(QLineEdit,"property_area_ft2")
    global haField
    haField = dialog.findChild(QLineEdit,"area_area_ha")
    global acreField
    acreField = dialog.findChild(QLineEdit,"property_area_acres")
    sqMField.textChanged.connect( sqMChanged )
    #if sqMField.text().strip() is None:
    layer = QgsMapLayerRegistry.instance().mapLayers()[layerid]
    feature = layer.getFeature(featureid)
    if feature.hasGeometry():
        area = feature.geometry().area()

This is called when I use the identify tool on a layer, having set this function as the Python init function on the fields tab of the layer properties. Thus I'm assuming the QGIS fills the parameters in for me?

But I get a KeyError error and on further checking it seems like I get a different layerid parameter each time the dialog opens, e.g:

An error occurred during execution of following code:
formOpen( _qgis_featureform_50_31, _qgis_layer_register20150529183519760_31, _qgis_feature_20170214103800202)

An error occurred during execution of following code:
formOpen( _qgis_featureform_51_32, _qgis_layer_register20150529183519760_32, _qgis_feature_20170214103829234)

So I could probably fix it by stripping some stuff off the layerid but that seems wrong. Can anyone show me what I'm missing?

  • Instead of matching the layer by id (since it seems to change dynamically), match it by name? E.g. layer = QgsMapLayerRegistry.instance().mapLayersByName("name")[0]
    – Joseph
    Feb 14, 2017 at 10:56
  • but I don't know the name of the layer
    – Ian Turton
    Feb 14, 2017 at 11:16
  • @iant Could you please post how did you define the layerid and featureid variables? I mean, a sample of line where you define them.
    – mgri
    Feb 14, 2017 at 11:22
  • as a python init function on identify clicks (see updated q)
    – Ian Turton
    Feb 14, 2017 at 11:27
  • 1
    @mgri - no I'm using a custom form that opens when I use the identify tool on my layer. You can set an init function that is run before the form is displayed
    – Ian Turton
    Feb 14, 2017 at 13:04

1 Answer 1


You can just use the layer- and the feature-handler like this:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

nameField = None
myDialog = None
myLayer = None
sqMField = None

def formOpen(dialog,layer,featureid):
    global myDialog
    global sqMField
    myDialog = dialog
    sqMField = dialog.findChild(QLineEdit,"property_area_m2")
    myLayer = layer
    print layer
    feature = featureid
    print feature
    if feature.geometry():
        area = feature.geometry().area()
        print area
  • fantastic, so in fact I get passed the layer and feature - bonus points if you can point to the manual entry that would have told me that?
    – Ian Turton
    Feb 14, 2017 at 15:38
  • 1
    I think there is no manual entry for this topic. Many people refer to Nathan Woodrows blogpost: nathanw.net/2011/09/05/…. I found a comment from Nathan Woodrow about this blogpost which is important: "My blog post is pre 2.0 which used to only get pasted the feature id. Now it gets passed the whole object." ( gis.stackexchange.com/questions/79755/… )
    – Thomas B
    Feb 16, 2017 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.