0

I'm trying to build QGIS plugin, using QT Designer with QGIS 3.34.2 custom widgets.

It is really convenient to set up most of interface actions using signals and slots, so after choosing Layer in QgsMapLayerComboBox there is a signal layerChanged(QgsMapLayer*) to few QgsFieldComboBox-es to display lists of fields there in slot: setLayer(QgsMapLayer*). All this is set in QT Designer.

Anyway, I've got layerCombo to choose layer, then fieldColumnCombo that displays fields within layer (filterd using self.fieldColumnCombo.setFilters(QgsFieldProxyModel.Numeric))). All works fine until I'd like to set default values (columns) in those fields.

I can do that without any problem by connecting event with method to set field values self.layerCombo.currentIndexChanged.connect(self.defaultFieldNames) but... it doesn't work right away.

There is no error and values are set, AND defaults are displayed after 2nd layer choice (2nd time choice of the same layer), but not after 1st layer choice (despite after 1st choice field names are set and I can choose from them). I guess it's because QgsFieldComboBox is not refreshed or updated right after choice...(maybe signals use different type of 'refresh', or something like 'dialog refresh' ??)

If you choose layer from layerCombo the fieldColumnCombo shows list of fields, but I've noticed that method defaultFieldNames can't access list of field names displayed there: fieldNames = [self.fieldColumnCombo.itemText(i) for i in range(self.fieldColumnCombo.count())] is an empty list.

I've tried self.fieldColumnCombo.update(), but it doesn't work.

Shall I update the whole UI dialog or set some update method in __init__ instead of defaultFieldNames?

1 Answer 1

0

The problem was: layer I wanted was first on the list. Because only signal in QT Designer for QgsMapLayerComboBox is layerChanged(QgsMapLayer*) and there was no change on the list (selected first item on the list, still: no index or item "change") there was no signal sent.

Best solution was to add new connection based on "activated" event: self.layerCombo.activated.connect(self.defaultFieldNames)

Also: field names is (probably) best to verify for being on "defaults" list using:

def defaultFieldNames(self):
    tbLayer = self.layerCombo.currentLayer()
    dataFields = [field.name() for field in tbLayer.fields()]
    defaultFNames = ['def_a','def_b','def_c']
    fieldA = [x for x in defaultFNames if x in dataFields]
    # first match used
    if len(fieldA)>0: self.fieldColumnCombo.setField(fieldA[0])

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.