1

I have built a plugin (PyQGIS) where once user login, it will display the map with layer retrieved from database. Let say, layer named lot_k is enabled for editing then new polygon is added for this layer after I digitize, it will pop up the feature attribute form as image follows.

enter image description here

Initially, I need to manually insert the value without any value provided.

I understand this can be achieved by edit of value map to populate the value based on field as follows. But I need to set it every time I relogin (as using plugin).

enter image description here

Hence, I would like to make dropdown with Python code to edit the field value for this form. For example, as picture below.

enter image description here

Below is my code :

def configure_attribute_form(layer, field_name, field_values):
  # Check if the field already exists
  if layer.fields().indexFromName(field_name) == -1:
     # Add the drop-down field to the layer
     layer_provider = layer.dataProvider()
     layer_provider.addAttributes([QgsField(field_name, QVariant.String)])
     layer.updateFields()

     # Set the field values
     idx = layer.fields().indexFromName(field_name)
     unique_values = set([f[field_name] for f in layer.getFeatures()])
     for value in field_values:
         if value not in unique_values:
             unique_values.add(value)
             layer_provider.changeAttributeValues({f.id(): {idx: value} for f in layer.getFeatures()})

    layer.commitChanges()
    layer.updateFields()

def on_feature_added(feature):
  # Replace 'lot_k' with the actual name of your layer
  layer_name = 'lot_k'

  # Replace 'majlis' with the name you want for the drop-down field
  field_name = 'kategori'

  # Replace 'value1', 'value2', etc., with the values you want in the drop-down list
  field_values = ['Dewasa', 'Kanak-kanak']

  # Get the layer
  layer = QgsProject.instance().mapLayersByName(layer_name)[0]

  # Configure the attribute form and populate the drop-down field
  configure_attribute_form(layer, field_name, field_values)

  layer_name = 'lot_k'
  layers = QgsProject.instance().mapLayersByName(layer_name)
  if layers:
     layer = layers[0]
     layer.featureAdded.connect(on_feature_added)
     # Configure the attribute form and populate the drop-down field
     configure_attribute_form(layer, 'kategori', ['Dewasa', 'Kanak-kanak'])
  else:
     print(f"Layer '{layer_name}' not found.") 
1
  • hi @Matt, yes I already made correction on indention. I ran above code as suggested chatgpt and it is still not create dropdown when I created new polygon for layer lot_k, I declare configure_attribute_form and on_feature_added function before the plugin class (eg : class(test)). And both function being called inside the class (test) starting (layer_name = 'lot_kubur' layers = QgsProject.instance().mapLayersByName(layer_name)
    – AJ 88
    Nov 29, 2023 at 2:19

1 Answer 1

1

You can set the value map on an existing field like so:

fields = layer.fields()
idx = fields.indexFromName(field_name)

field_values = ['Dewasa', 'Kanak-kanak']

# use dictionary comprehension to make the value map from the values list - could also create it explicitly: {'Dewasa': 'Dewasa', 'Kanak-kanak': 'Kanak-kanak'}
value_map = {'map': {value: value for value in field_values}}

# create a Value Map widget setup
setup = QgsEditorWidgetSetup('ValueMap', value_map)

# pass the widget setup to the layer using the field index
layer.setEditorWidgetSetup(idx, setup)

On adding a new feature via editing:

enter image description here

2
  • Thanks for the response but still it didn't display the drop down of field values. Shall I continue to use the old way to setting the value map first before digitize new polygon. Thanks for the help by the way
    – AJ 88
    Dec 1, 2023 at 8:23
  • That is strange, for me it works fine. When I run the above code and then add a feature to the layer with the edit tool I am able to choose the value from a dropdown in the Feature Attributes window.
    – Matt
    Dec 1, 2023 at 8:28

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.