2

I am trying to display field names dynamically inside a widget based on the number of fields in vector layer selected in combo box. When i load a raster inside QGIS TOC and a vector layer, it is raising an error as shown below

AttributeError: 'OpenlayersLayer' object has no attribute 'pendingFields'

Below is my code

    def addLayerNames(self):
     self.dlg.comboBox.clear()
     for i in reversed(range(self.dlg.verticalLayout.count())):
        self.dlg.verticalLayout.itemAt(i).widget().setParent(None)
     layers = QgsMapLayerRegistry.instance().mapLayers().values()
     layer_list = []
      for layer in layers:
        if layer.type() == QgsMapLayer.VectorLayer:
            layer_list.append(layer.name())
      self.dlg.comboBox.addItems(layer_list)
      selectedLayerIndex = self.dlg.comboBox.currentIndex()
      print selectedLayerIndex
      selectedLayer = layers[selectedLayerIndex]
      print selectedLayer
      fields = selectedLayer.pendingFields()
      fieldnames = [field.name() for field in fields]
      for i,field in enumerate(fieldnames):
        self.labels = QLabel()
        self.linedit = QLineEdit()
        self.labels.setText(field)
        #self.flay = QFormLayout()
        #self.le = QLineEdit()
        self.linedit.setFixedWidth(200)
        self.dlg.verticalLayout.addRow(field, self.linedit)
        #self.linedit.setFixedWidth(100)
        #self.dlg.verticalLayout.addLayout(self.flay)
        #self.dlg.verticalLayout.addWidget(self.linedit)
        request = QgsFeatureRequest().setFilterFid(0)
        layer.setSelectedFeatures([0])
        self.iface.actionZoomToSelected().trigger()
        feat = layer.getFeatures(request).next()
        self.linedit.setText(str(feat[i]))
        self.linedit.setObjectName(field)
        self.dlg.pushButton.setEnabled(False)
        self.lineedits.append(self.linedit)
1
  • Is the error occurring on selectedLayer b/c it is a raster layer? – artwork21 Dec 11 '17 at 13:57
1

I think the error is arising because you are calling the index value

selectedLayerIndex = self.dlg.comboBox.currentIndex()

and using this to identify the loaded layers

layers = QgsMapLayerRegistry.instance().mapLayers().values()
...
selectedLayer = layers[selectedLayerIndex]

So if you select a layer from your widget which has an index of 2, can you ensure that the layers in the Layer Panel are ordered so that the 3rd layer is not a raster?


Another approach (probably a little safer) is to match the layer by name and not with an index. Perhaps something like:

layers = QgsMapLayerRegistry.instance().mapLayers().values()
layer_list = []
for layer in layers:
if layer.type() == QgsMapLayer.VectorLayer:
    layer_list.append(layer.name())
self.dlg.comboBox.addItems(layer_list)
# Get text of selected layer's name
selectedLayerIndex = self.dlg.comboBox.currentText()
print selectedLayerIndex
# Match selected name with layer from panel
selectedLayer = QgsMapLayerRegistry.instance().mapLayersByName(str(selectedLayerIndex))[0]
print selectedLayer
fields = selectedLayer.pendingFields()

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.