To expand a little on the answer of @Fran Raga, a very quick way to add all the project vector layers to your layer combo box is to use a list comprehension:
vector_names = [l.name() for l in QgsProject().instance().mapLayers().values() if isinstance(l, QgsVectorLayer)]
self.dlg.cbLayer.addItems(vector_names)
However, I would really recommend looking into using the custom QGIS widgets QgsMapLayerComboBox()
and QgsFieldComboBox().
Once you start using them I don't think you will look back. A QgsMapLayerComboBox
shows all project layers by default, but it is ridiculously easy to filter to only vector layers, raster layers, layers which have geometry or any geometry type.
QgsFieldComboBox
has a method setLayer()
which filters the fields shown to fields belonging to that layer. This makes it very simple to connect the setLayer()
method to the layerChanged()
signal of a QgsMapLayerComboBox
object and set the layer for the field combo box to the currentLayer()
of the map layer combo box so that whenever the layer combo box selection changes, the fields in the field combo box are updated dynamically.
As an added bonus you also get the nice little raster and vector icons next to the combo box items. You can also show the CRS of each layer.
try out this small snippet in the Python console in a project with a few different layers loaded. You should quickly get the idea of how it works and be able to adapt it into your plugins:
class Dlg(QDialog):
def __init__(self):
QDialog.__init__(self)
self.setGeometry(100, 100, 300, 200)
self.layout = QVBoxLayout(self)
self.cb_layer = QgsMapLayerComboBox(self)
self.layout.addWidget(self.cb_layer)
self.cb_layer.setFilters(QgsMapLayerProxyModel.VectorLayer)
self.cb_layer.setShowCrs(True)
self.cb_fields = QgsFieldComboBox(self)
self.layout.addWidget(self.cb_fields)
self.cb_fields.setLayer(self.cb_layer.currentLayer())
self.cb_layer.layerChanged.connect(lambda: self.cb_fields.setLayer(self.cb_layer.currentLayer()))
Win = Dlg()
Win.show()
The custom widgets should be available in the QtDesigner which comes with QGIS. If you are on Windows & used the OSGeo4W installer you will find, in C:\OSGeo4W64\bin
, a batch file called either qgis-designer
or qgis-ltr-designer
depending on which version or versions you have installed. Double clicking on this batch file should launch QtDesigner with QGIS custom widgets.
If you can't access them through Designer for any reason, a workaround is to create and add them in your plugin_dialog.py
file. For example, add an empty layout in Designer, then create the combo box objects in plugin_dialog.py
like:
from qgis.gui import QgsMapLayerComboBox, QgsFieldComboBox
Then in __init__()
method, after self.setupUi(self)
something like:
self.cbLayer = QgsMapLayerComboBox(self)
self.cbFields = QgsFieldComboBox(self)
self.verticalLayout_1.addWidget(self.cbLayer)
self.verticalLayout_1.addWidget(self.cbFields)
You should then be able to access and work with them in the initGui()
method of your main plugin.py
file e.g.
self.dlg.cbLayer.setFilters(QgsMapLayerProxyModel.VectorLayer)