1

I am developing a QGIS plugin which contains 2 combo boxes:

  1. comboBox
  2. comboBox_2

combobox lists the vector layers available, however I would like the 2nd combobox_2 to list the all names available in attribute column 'names' (from the attribute table). After debugging following code I can select leyers from combobox but combobox_2 not working for selecting names.

    def run(self):
    """Run method that performs all the real work"""
    if self.first_start == True:
        self.first_start = False
        self.dlg = GetMapDialog()     
    # Fetch the currently loaded layers
    layers = QgsProject.instance().layerTreeRoot().children()
    self.dlg.comboBox.clear()
    self.dlg.lineEdit.clear()
    # Populate the comboBox with names of all the loaded layers
    self.dlg.comboBox.addItems([layer.name() for layer in layers])

    selectedLayerIndex = self.dlg.comboBox.currentIndex()
    selectedLayer = layers[selectedLayerIndex].layer()
    fieldnames = selectedLayer.fields() 
    features = selectedLayer.getFeatures()
    dist =[]
    for field in fieldnames:
        if field == 'names':
            for feature in features:
                dist.append(feature)
        else: pass
            
     self.dlg.comboBox_2.clear()
     self.dlg.comboBox_2.addItems(dist)

1 Answer 1

1

I recommend very strongly to consider using a custom QGIS widget for your layer combo box. Instead of a generic QComboBox, you can use a QgsMapLayerComboBox. This custom widget will load automatically all layers loaded in the current project, however you can easily filter these to only show polygon layers using:

self.dlg.comboBox.setFilters(QgsMapLayerProxyModel.PolygonLayer).

It will also handle behind the scenes any case where layers are added or removed from the project, even while your plugin dialog is open, so you don't need to worry about connecting to signals emitted by the project and re-populating your generic combo box.

In a Windows OSGeo4W install, in the bin folder, you will find a batch file called qgis-designer or qgis-ltr-designer.

enter image description here

This batch file will open Qt Designer with all the QGIS custom widgets available. I suggest to open your .ui file, delete the QComboBox and replace it with a QgsMapLayerComboBox as in the screenshot below.

enter image description here

Then you can edit your plugin.py file and copy the code below. Note that I have created one additional method, populate_combobox_2(), and connected it to the layerChanged signal of the QgsMapLayerComboBox, so that the Name combo box (comboBox_2) is updated whenever the layer selected in the layer combo box changes.

You will also need to add the following line to the imports at the top of the file:

from qgis.core import QgsMapLayerProxyModel

Other section of .py file which will populate your combo boxes:

def run(self):
    """Run method that performs all the real work"""

    # Create the dialog with elements (after translation) and keep reference
    # Only create GUI ONCE in callback, so that it will only load when the plugin is started
    if self.first_start == True:
        self.first_start = False
        self.dlg = GetMapDialog()
        # Connect signal to slot which will update comboBox_2 whenever selection in comboBox changes
        self.dlg.comboBox.layerChanged.connect(self.populate_combobox_2)
    self.dlg.comboBox.setFilters(QgsMapLayerProxyModel.PolygonLayer)
    self.populate_combobox_2()
    # show the dialog
    self.dlg.show()


def populate_combobox_2(self):
    self.dlg.comboBox_2.clear()
    selectedLayer = self.dlg.comboBox.currentLayer()
    if selectedLayer:
        self.dlg.comboBox_2.addItems(sorted([i for i in selectedLayer.uniqueValues(selectedLayer.fields().lookupField('names'))]))

Example result:

enter image description here

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.