8

In the Memory provider described in PyQGIS Cookbook and in the question Creating new empty vector layer with PyQGIS I can see how to create a Vector Layer programmatically using standard fields (String, Int, Double).

With PyQGIS/QGIS 1.8.0, is it possible to programmatically add calculated fields like the ones defined using the Field Calculator?

After reading about QgsExpression I'm thinking in something like this:

exp = QgsExpression('Column * 3')
pr.addAttributes( [ QgsField( "fieldName", QVariant.Expression, exp ) ] )
Taras
35.8k5 gold badges77 silver badges151 bronze badges
asked Oct 4, 2012 at 17:28
3
  • Is you question about adding the attribute, modifying the value of an attribute or about the expression syntax/parser present in the field calculator? Could you outline a short example of what you want to accomplish? Commented Apr 22, 2013 at 15:38
  • Is about adding a new attribute defined with the parser present in the field calculator. I've edited the question to add an example that tries to clarify what I want to achieve. Commented May 1, 2013 at 14:57
  • Please, do not forget about "What should I do when someone answers my question?" Commented Jul 28, 2023 at 17:40

1 Answer 1

9

To accomplish this, you have to take a two-step approach. The first step is to create the field, the second one is to loop over all your features, evaluate the expression and update the attribute for each feature.

vl is your QgsVectorLayer

QGIS 2.0

from PyQt4.QtCore import QVariant
from qgis.core import QgsField, QgsExpression, QgsFeature
vl.startEditing()
#step 1
myField = QgsField( 'myattr', QVariant.Int )
vl.addAttribute( myField )
idx = vl.fieldNameIndex( 'myattr' )
#step 2
e = QgsExpression( 'Column * 3' )
e.prepare( vl.pendingFields() )
for f in vl.getFeatures():
 f[idx] = e.evaluate( f )
 vl.updateFeature( f )
vl.commitChanges()

QGIS 1.8

from PyQt4.QtCore import QVariant
from qgis.core import QgsField, QgsExpression, QgsFeature
vl.startEditing()
#step 1
myField = QgsField( 'myattr', QVariant.Int )
vl.addAttribute( myField )
idx = vl.fieldNameIndex( 'myattr' )
#step 2
e = QgsExpression( 'Column * 3' )
e.prepare( vl.pendingFields() )
f = QgsFeature()
vl.select( vl.pendingAllAttributesList() )
while vl.nextFeature( f ):
 vl.changeAttributeValue( f.id(), idx, e.evaluate( f ) )
vl.commitChanges()
Taras
35.8k5 gold badges77 silver badges151 bronze badges
answered May 2, 2013 at 13:36
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.