Answering your two questions:
You can change your feature values from the layer
object, no need to access the dataProvider()
.
Yes, you can use the iterator in a for
loop (that's what iterators are for :) ).
Using layer.changeAttributeValue()
changeAttributeValue()
is handy when you want to change the value of a single field for your features. For instance, let's see how to modify a single field for selected features:
layers = QgsProject.instance().mapLayersByName('my_line')
layer = layers[0] # We assume there is at least 1
field_idx = layer.fields().indexOf('my_field_name')
new_value = 30
with edit(layer):
for feat_id in layer.selectedFeatureIds():
layer.changeAttributeValue(feat_id, field_idx, new_value)
Which updates the field value to 30 for selected features.
If you want to update the field value for all features in your layer, do something like this:
with edit(layer):
for feat in layer.getFeatures():
layer.changeAttributeValue(feat.id(), field_idx, new_value)
Which updates the field value to 30 for all layer features. See this answer for optimizing the getFeatures()
method.
Regarding layer.updateFeature()
Always try to avoid the QgsVectorLayer.updateFeature()
method. It's less efficient than changeAttributeValue()
.
From the docs:
This method needs to query the underlying data provider to fetch the
feature with matching QgsFeature::id() on every call. Depending on the
underlying data source this can be slow to execute. Consider using the
more efficient changeAttributeValue() or changeGeometry() methods
instead.
my_index = layer.fieldNameIndex("my_field_name")
to get the index.