6

I'm working on plugin updating existing shapefile by adding new features to it. And I have a problem with signal that hasn't been emitted by QGIS, when I've added features to layer, using dataProvider().addFeatures(). I'm pretty sure that I have defined correctly connection signal and function, when it is emitted.

layer.committedFeaturesAdded.connect(self.onFeaturesAdded)

Becasue when I add feature using tool in QGIS from Digitizing Toolbar, it works fine and function is running.

The problem is when I add features manually - using python.

def selectFeatures(self,diviLayer, userLayer84):
        self.diviLayer=diviLayer
        self.userLayer84=userLayer84
        features=[]

        Processing.initialize()

        general.runalg('qgis:selectbylocation', self.userLayer84, self.diviLayer, u'intersects',0.000001,0)
        self.userLayer84.invertSelection()
        number=self.userLayer84.selectedFeatureCount()

        for feature in self.userLayer84.selectedFeatures():
            attributes=[feature['Lokaliz'],feature['Zadanie'],feature['Projekt'],feature['Wykonawca'],feature['X'],feature['Y'],feature['h'],feature['Azymut'],feature['Dokl'],feature['KmEt'],feature['Km2Et'],feature['Poloz'],feature['Domiar'],feature['Nr_dz'],feature['Obr'],feature['JE'],feature['Pow'],feature['Woj'],feature['Data'],feature['Czas'],feature['xtrPhtC'],feature['xtrComC'],feature['xtrAudC'],feature['xtrFilC'],feature['NazwaRap'],feature['Sciezka']]
            feat=QgsFeature()
            feat.setAttributes(attributes)
            feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(feature['Y']),float(feature['X']))))
            features.append(feat)

        return [features,number]

    [features,number]=self.selectFeatures(self.diviLayer,self.userLayer84)

    self.diviLayer.startEditing()
    self.diviLayer.dataProvider().addFeatures(features)
    self.diviLayer.commitChanges()

It seems like the signal is not emitted? Has anyone of you had a similar problem? Or maybe you know, where I'm making mistake.

6

According to one of the QGIS developers (@MatthiasKuhn) in his website OPENGIS.ch, he suggests to completely avoid dataProvider() methods as he lists the following (emphasis mine):

  • You cannot undo them easily
  • They generate one request per call what may reduce performance
  • They do not emit internal signals for map redraws and other refreshes of the user interface
  • They do not take uncommitted changes into account so the python changes will get overwritten by the user when he commits the layer changes

I think the third bullet point states that the dataProvider() method will not emit any signals (I could be wrong).


In any case, it is suggested to instead use the with edit(layer): method. So you could try replacing your last three lines:

self.diviLayer.startEditing()
self.diviLayer.dataProvider().addFeatures(features)
self.diviLayer.commitChanges()

With this:

with edit(self.diviLayer):
    self.diviLayer.addFeatures(features)

Note that you may need to import the edit method into your plugin using:

from qgis.core import edit
  • 1
    thank you very much! Now it is working :) And I remember not to use dataProvider() in the future. :) – Olaniag May 5 '17 at 6:33
  • @Olaniag - Most welcome, glad you got it to work! And I also have to remember to try and avoid dataProvider() :) – Joseph May 5 '17 at 9:00

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.