4

I started to develop a plugin for QGIS in python and I need to list postgres layers in a QgsMapLayerComboBox. I used a QgsMapLayerProxyModel to show only vector layers from canvas:

self.dlg.comboBox.setCurrentIndex(-1)
self.dlg.comboBox.setFilters(QgsMapLayerProxyModel.VectorLayer)

It's possible to show only vector layers from a postgres connection?

SOLVED:

def updateMapLayerComboBox(self):
        excepted = self.dlg.comboBox.exceptedLayerList()
        mapLayers = QgsMapLayerRegistry.instance().mapLayers().values()
        for layer in mapLayers:
            if hasattr(layer, 'providerType') and layer.providerType() != 'postgres':
                excepted.append( layer )
        self.dlg.comboBox.setExceptedLayerList( excepted )


QgsMapLayerRegistry.instance().layersAdded.connect(self.updateMapLayerComboBox)
QgsMapLayerRegistry.instance().layersRemoved.connect(self.updateMapLayerComboBox)
1
  • Actually, you don't need to iterate through all map layers each time you add/remove a layer. My answer avoids just that. Mar 14, 2017 at 15:07

2 Answers 2

6

In QGIS 2.x you'd need to pass a list of layers not coming from PostgreSQL:

excepted = []
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
    if hasattr(layer, 'providerType') and layer.providerType() != 'postgres':
        excepted.append( layer )
self.dlg.comboBox.setExceptedLayerList( excepted )

In QGIS 3.x you'll pass a list of providers to exclude:

providers = QgsProviderRegistry.instance().providerList()
providers.remove('postgres')
self.dlg.comboBox.setExcludedProviders( providers )

EDIT: As a workaround in QGIS 2.x, you can run the following code. Last line updates your ComboBox for existing layers, whereas the second to last line makes sure you'll get your combobox updated when new layers are added.

def updateMapLayerComboBox( mapLayers ):
    excepted = self.dlg.comboBox.exceptedLayerList()
    for layer in mapLayers:
        if hasattr(layer, 'providerType') and layer.providerType() != 'postgres':
            excepted.append( layer )
    self.dlg.comboBox.setExceptedLayerList( excepted )

QgsMapLayerRegistry.instance().layersAdded.connect( updateMapLayerComboBox )
updateMapLayerComboBox( QgsMapLayerRegistry.instance().mapLayers().values() ) #Initialize
4
  • +1. But I think the design of the interface is confusing. I'd expect to specify the layers I want to include, not the layers I want to ignore. ('Accept', rather than 'Except').
    – Steven Kay
    Mar 12, 2017 at 23:45
  • 1
    I tend to agree with you. Perhaps even better if you could specify either of them, e.g., setAcceptedProviders / setExcludedProviders. Mar 13, 2017 at 0:02
  • the first answer works... but if You add another layer to map canvas (for example a shapefile) it appears automatically in the combobox. So I don't know how to resolve this problem. Mar 13, 2017 at 8:55
  • Then the solution in QGIS 3.x is much better. As a workaround for QGIS 2.x, you can connect QgsMapLayerRegistry.layersAdded SIGNAL to a custom function where you update the exceptedLayerList every time a layer is added. Mar 13, 2017 at 12:25
1

You can create your own combobox with layers:

combo = QtGui.QComboBox()
lst = []
layers = QgsMapLayerRegistry.instance().mapLayers().values()
for i in layers:
    if i.type() == QgsMapLayer.VectorLayer and i.providerType == 'postgres':
        lst.append(i.name())
combo.addItems(lst)

For each layer fron the registry you need to check provider type and if it is equal to 'postgres' add it to the combobox.

Also there is a new method in QgsMapLayerComboBox:

setExcludedProviders()

But it seems to be hard to type all available provides without the postgres.

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.