[GIS] How to get the selected value in a value map with Function Editor in QGIS 3.0.2

pyqgispyqt5pythonqgis-3

I'm trying to automatically ("on-the-fly") add values to a value map widget depending on the value selected from another value map widget by using the Function editor in Expression dialog in the Layer properties – Attributes Form.

— UPDATE (included 3 more images):
Layer properties of the shapefile mis_testf.shp

Expression dialog - Expression

Expression dialog - Function editor

First, the user select a Livsmiljø from a value map (combo box/drop down list called LIVSMILJO), secondly he/she chooses Kalkinnhold from another value map (combo box/drop down list called KALKINNH).

The options should be spink or datt

I've managed to add values to the value map of the field (attribute) called 'KALKINNH' with this code (based on How to create predefined values in a field in PyQGIS):

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
from PyQt5.QtCore import *

@qgsfunction(args='auto', group='Custom')
def kalkinnhold(feature, parent):   
    layer = qgis.utils.iface.activeLayer()
    fieldIndex = layer.fields().indexFromName( 'KALKINNH' )
    editor_widget_setup = QgsEditorWidgetSetup( 'ValueMap', {
                         'map': {u'hei': u'a', 
                                 u'morna': u'b'}
                        }
                      )
    layer.setEditorWidgetSetup( fieldIndex, editor_widget_setup )

Now I'm trying to add an if condition (if the value map 'LIVSMILJO' is set to 1 then the 'KALKINNH' value map should have these values, else 'KALKINNH' should be populated with some other values).
Sadly, I'm not able to figure out how to do this.

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
from PyQt5.QtCore import *

@qgsfunction(args='auto', group='Custom')
def kalkinnhold(feature, parent):   
    layer = qgis.utils.iface.activeLayer()
    fieldIndex = layer.fields().indexFromName( 'KALKINNH' )
    kjell = layer.dataProvider().fieldNameIndex('LIVSMILJO')
    if kjell == 1:
        editor_widget_setup = QgsEditorWidgetSetup( 'ValueMap', {
                         'map': {u'hei': u'a', 
                                 u'morna': u'b'}
                        }
                      )
    elif kjell != 1:
        editor_widget_setup = QgsEditorWidgetSetup( 'ValueMap', {
                         'map': {u'spink': u'c', 
                                 u'datt': u'd'}
                        }
                      )
    layer.setEditorWidgetSetup( fieldIndex, editor_widget_setup )

I've have tried different variants of if kjell == 1: and if kjell.currentValue() == 1:. The first alternative I believe just gives me the index (as an integer) of the 'LIVSMILJO' attribute (and not the actual value set in 'LIVSMILJO'). That's why I in the second alternative add currentValue(), but this fail since "'int' object has no attribute 'currentValue'".

Fair enough, but is there a way of getting the current value (chosen item) of the value map 'LIVSMILJO'? And in that way decide the content of another value map on-the-fly?

Best Answer

You need to connect your LIVSMILJO comboBox to a signal and return the current text of LIVSMILJO comboBox every time selection of text changes in LIVSMILJO comboBox.This can be done as follows

def addValues(self):
    txt = self.dlg.LIVSMILJO.currentText()
    if txt=='1':
        self.dlg.KALKINNH.clear()
        self.dlg.KALKINNH.addItems(["hei","morna"])
    else:
        self.dlg.KALKINNH.clear()
        self.dlg.KALKINNH.addItems(["spink","datt"])
def makeConnections(self):
    self.dlg.LIVSMILJO.currentTextChanged.connect(self.addValues)

Now all you need is, to call this makeConnections method inside your initGui like this

def initGui(self):
    self.makeConnections()

Please note that here "dlg" is the name of your dialog it can be different in your case so you may need to change it. But if you have only one dialog and you used plugin builder to get basic template then you do not need to change it. Hope this answers your question.

Related Question