3

I am creating my very first QGIS plugin using two combo boxes - one to select a layer and the other to select a field.

Whilst the layer selection feature seems to work, the field name combo box is not updated when a new layer is selected.

My code is as follows...

    self.dlg.comboBox.clear()
    self.dlg.comboBox_2.clear()

    layers = self.iface.legendInterface().layers()
    layer_list = []
    for layer in layers:
        layer_list.append(layer.name())
    self.dlg.comboBox.addItems(layer_list)
    selectedLayerIndex = self.dlg.comboBox.currentIndex()
    selectedLayer = layers[selectedLayerIndex]

    fields = [field.name() for field in selectedLayer.pendingFields() ]
    self.dlg.comboBox_2.addItems(fields)

Does anyone happen to know how I can accomplish this?

7

You could put most of your code in a function which will be run every time a user changes the current layer from the combobox. For example, you could use something like:

self.dlg.comboBox.clear()
self.dlg.comboBox_2.clear()

layers = self.iface.legendInterface().layers()
layer_list = []
for layer in layers:
    layer_list.append(layer.name())
self.dlg.comboBox.addItems(layer_list)

def field_select():
    self.dlg.comboBox_2.clear()
    selectedLayerIndex = self.dlg.comboBox.currentIndex()
    selectedLayer = layers[selectedLayerIndex]
    fields = [field.name() for field in selectedLayer.pendingFields()]
    self.dlg.comboBox_2.addItems(fields)

# This connects the function to the layer combobox when changed
self.dlg.comboBox.currentIndexChanged.connect(field_select)
  • @JamieTasker - Most welcome, glad it helped :) – Joseph Jan 27 '17 at 10:56
  • Thanks for this solution. On my version, the first layer combox box get filled automatically from the start and it doesn't allow the selection of the associated field. It's only when the layer is actually selected 'by hand' that the field combo box update itself. Any idea to start with empty combo boxes? – Leo Jan 15 at 5:16
  • @Leo - One way could be to add an empty item to the beginning of the list. So for the first combo box after layer_list = [], add layer_list.append(''). But you would probably need to include an if statement in the field_select() function to check if a layer is selected or an empty item is selected from the first combo box. If the latter then clear the combo box else show the list of fields. There might be an easier way but it's been a while since I worked on something like this :) – Joseph Jan 15 at 11:05
  • 1
    @Leo 1: It is because the index of the second combo box no longer matches the index of the first (because of the added empty item). I would instead identify the layer using the name. So you could try replacing selectedLayerIndex = self.dlg.comboBox.currentIndex() with selectedLayerText = self.dlg.comboBox.currentText(); and selectedLayer = layers[selectedLayerIndex] with selectedLayer = QgsMapLayerRegistry.instance().mapLayersByName(str(selectedLayerText))[0]. 2: Make sure before any items are added to the second combo box that it is cleared: self.dlg.comboBox_2.clear(). – Joseph Jan 16 at 10:42
  • 1
    Thank you so much! It works, that's so nice of you to have taken the time. Learned a lot doing it. For anyone reading this, it is also useful to had a if/else after selectedLayerText to avoid a 'list out of range' error if the first empty ' ' layer is selected again by mistake. If selected layer is ' ' self.dlg.comboBox2.clear(). Else: carry on with the rest of def field_select() – Leo Jan 16 at 23:54
1

Just a little update for QGIS 3 users, layers = self.iface.legendInterface().layers() should be replaced by layers = [layer for layer in QgsProject.instance().mapLayers().values()]

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.