The following code works to change and save the specified attribute of a selected feature in the QGIS console:
selectedLayer = iface.activeLayer() # add self before iface for external script
features = layer.selectedFeatures() # creates a list of features so you need to index it to access the feature
feature = features[0]
newValue1 = 'hello'
newValue2 = 'hola'
with edit(selectedLayer): # the with edit & update feature method works fine in Qgis console.
feature.setAttribute('December', newValue1) # Tested with plain text instead of newValue1. Tested with feature['December'] = 'K'.
feature.setAttribute('February', newValue2) # feel like it's something to do with how the target feature is specified and passed to the function.
selectedLayer.updateFeature(feature)# Tested with commitChanges().
print(feature.attributes())
However, the with edit
statement does not work when applied in a plugin. The function is correctly called when the relevant button is pressed in the UI. Does with edit just not work in a plugin environment?
This is the code:
def saveFeatureEdits(self):
print('Save Feature Edits called') # Prints so feature is called.
global selectedLayer # Have tried with this in the function & also tried without; it works to get the selected feature so assume this isn't the problem.
selectedFeature = selectedLayer.selectedFeatures()
feature = selectedFeature[0]
featureID = str(feature['ID'])
print(featureID) # Prints the correct ID.
newValue1 = self.dockwidget.editFeatureAttribute1.text()
print(newValue1) # Prints the correct value.
newValue2 = self.dockwidget.editFeatureAttribute2.text()
print(newValue2) # Prints the correct value.
with edit(selectedLayer): # the with edit & update feature method works fine in Qgis console.
feature.setAttribute('December', newValue1)
print(feature.attributes()) # Doesn't print anything.
feature.setAttribute('February', newValue2)
selectedLayer.updateFeature(feature) # Tested with commitChanges() and also with adding commitChanges() at the end.
print(feature.attributes()) # Doesn't print anything.
Note that I've also tried the following in the QGIS console as an alternative. It works to update the attribute December to 'G' but only if I run the code twice, so as expected it doesn't work in the plugin. I am at a loss for how to update the feature attribute now in the plugin:
layer = iface.activeLayer()
feature = layer.selectedFeatures()
feature = feature[0] # access the feature
layerFields = layer.fields()
fieldIndex = layerFields.indexFromName("December")
feature = layer.selectedFeatures() # creates a list of features so you need to index it to access the feature
featureID = feature[0].id()
label = 'G'
layer.startEditing()
layer.changeAttributeValue(featureID, fieldIndex, label)
layer.commitChanges()
print(fieldIndex)
for f in feature:
print(f.attributes())
Output in console 1st and 2nd run:
exec(open('...'.encode('utf-8')).read())
3
[10, 11182833, NULL, 'S']
exec(open('....encode('utf-8')).read())
3
[10, 11182833, NULL, 'G']
1 Answer 1
In the last code block, you change the value of the feature in the source data, not the value of the variable feature
. So feature
still remains unchanged.
At the first run, it prints the first/unchanged values of feature
. At the second run, feature
is assigned the changed values of the source data.
If you add feature = layer.selectedFeatures()
before for
loop, you will see that the attribute values have actually changed at the first run.
feature = layer.selectedFeatures()
for f in feature:
print(f.attributes())
I couldn't test the issue in with edit
.
-
Thank you, the last code block now works correctly in the QGIS console. However it does not work when transferred to the plugin, so I will leave the question open for further comments.TuftyPuff– TuftyPuff2023年06月20日 09:16:27 +00:00Commented Jun 20, 2023 at 9:16