7

Value Maps can be added to attributes via the loading of a CSV file, as described in the docs:

https://docs.qgis.org/3.28/en/docs/user_manual/working_with_vector/vector_properties.html#edit-widgets

enter image description here

It is possible to add a CSV (or any format) Value Map to an attribute of a layer using PyQGIS?

I have tried to find documentation on this, but it appears to be fairly sparse, and I can't tell if this is even the right class to be looking at:

https://qgis.org/pyqgis/3.28/core/QgsValueMapFieldFormatter.html

PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Tom Brennan
  • 4,787
  • 6
  • 26

1 Answers1

12

To set a value map widget with values loaded manually, you can just do something like:

#QgsVectorLayer object
vl = iface.activeLayer()

# Get field index
fld_idx = vl.fields().lookupField('fuzzylinefeaturetype')

# define value map
v_map = {'map': [{'Beach': '2'}, {'DuneLike': '3'}, {'GeneralLocality': '5'}, {'RangeLike': '13'}, {'ValleyLike': '18'}]}

# Set editor widget setup to layer, passing in field index & widget setup
vl.setEditorWidgetSetup(fld_idx, QgsEditorWidgetSetup('ValueMap', v_map))

To load the values from a csv, I think the easiest solution is just to write a simple function like below:

import csv

path = '/path/to/your/field_map.csv'

def loadValueMapFromCsv(fpath): v_map = {} entries = [] with open(fpath, newline='') as mapfile: reader = csv.reader(mapfile, delimiter=',') for row in reader: entries.append({row[1]: row[0]}) v_map['map'] = entries

return v_map

#print(loadValueMapFromCsv(path))

vl = iface.activeLayer()

fld_idx = vl.fields().lookupField('fuzzylinefeaturetype')

v_map = loadValueMapFromCsv(path)

vl.setEditorWidgetSetup(fld_idx, QgsEditorWidgetSetup('ValueMap', v_map))

Results on a test layer:

Example of csv file:

enter image description here

Attribute form dialog after running code in Python console:

enter image description here

The method in the source code which parses a csv file is: QgsValueMapConfigDlg::loadMapFromCSV

There are also useful references in the Python test for QgsAttributeForm.

By the way, to find the correct structure/syntax for the value map, I set it up manually then ran:

vl = iface.activeLayer()

fld_idx = vl.fields().lookupField('Name')

print(vl.editorWidgetSetup(fld_idx).config())

Ben W
  • 21,426
  • 3
  • 15
  • 39