2

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?

  • You might be looking for north-road.com/drill-down-cascading-forms, which will be included in qgis 3.2 – ndawson May 20 '18 at 22:17
  • @ndawson, thanks for sharing such wonderful news! I'll try to be patient until end of June. – 9ls1 May 25 '18 at 11:57
  • @ndawson, I couldn't wait - downloaded the nightly build yesterday and used Current_value - works like a charm! \o/ – 9ls1 Jun 20 '18 at 8:45
2

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.

  • Thanks, @Asad Abbas. However, I'm not making a plugin nor an initGui, I'm only using the possibilities provided within QGIS. I have added different widgets to my attributes and now I'm trying to populate one of them based on another using Layer properties - Attribute forms - Expression dialog (in the default value) - Function editor. I may add some more images to my question above to clearify. – 9ls1 May 16 '18 at 6:04
  • OK that's fine with me – Asad Abbas May 16 '18 at 7:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.