2

Code to add polygon layer when a button is pressed in my plugin:

            # Add polygon layer
        self.poly_layer = QgsVectorLayer("Polygon", "target_polygons", "memory")
        # Set polygon color and opacity
        myRenderer  = self.poly_layer.renderer()
        mySymbol1 = QgsFillSymbol.createSimple({'color':'255,0,0,50',
            'color_border':'#000000',
            'width_border':'0.6'})
        myRenderer.setSymbol(mySymbol1)
        iface.layerTreeView().refreshLayerSymbology(self.poly_layer.id())
        QgsProject.instance().addMapLayer(self.poly_layer)
        
        # Enter editing mode
        self.poly_layer.startEditing()
        iface.actionAddFeature().trigger()

After adding a few polygons, I have arrow buttons that should iterate through each feature and zoom in on it, this works for polygon layers that I import, and for point layers, but not for this homemade polygon layer. Is it because the polygons have no attributes? if I open the attribute table and try to click on each polygon I cannot select it (strangely, "select all" still works).

attribute table

I also want to ask, is it possible to auto add atttributes in pyqgis so that whenever a polygon is digitized the window does not pop up to ask for the info. If I use this code then a popup will open with each polygon created and I want to avoid that:

pr = self.poly_layer.dataProvider()
pr.addAttributes( [ QgsField("name", QVariant.String)])

UPDATE: let me provide some more code for clarity. I have tried tow different approaches for committing changes to the polygons. one is by having an "ok" button when the user is done adding polygons that will do this code:

iface.mainWindow().findChild(QAction, 'mActionToggleEditing').trigger()

Even after pressing ok (which will prompt the user to save changes), I still cannot select polys from the attribute table or zoom to the selected one using my arrow buttons. Another approach is to auto commit changes after each polygon is created;

self.poly_layer.featureAdded.connect(self.feature_added)

    def feature_added(self):
        self.poly_features = [feature for feature in 
        self.poly_layer.getFeatures()]
        self.TotalLabelPoly.setText(str(len(self.poly_features)))
        self.current_selection_poly = len(self.poly_features)
        #self.poly_layer.commitChanges()
        iface.actionSaveEdits().trigger()

the last two lines of that function are what I have tried and neither seem to solve my issue, the commitChanges() function actually makes qgis crash. Here is the code where I attempt to zoom in on selected geometry:

def right_arrow_poly(self):
    if self.current_selection_poly < len(self.poly_features):
        self.current_selection_poly += 1
        self.AttributeNumberPolyBox.setText(str(self.current_selection_poly))
        self.poly_layer.selectByIds([self.current_selection_poly])
        box = self.poly_layer.boundingBoxOfSelected()
        iface.mapCanvas().setExtent(box)
        iface.mapCanvas().refresh()

def left_arrow_poly(self):
    if self.current_selection_poly > 1:
        self.current_selection_poly -= 1
        self.poly_layer.selectByIds([self.current_selection_poly])
        box = self.poly_layer.boundingBoxOfSelected()
        iface.mapCanvas().setExtent(box)
        iface.mapCanvas().refresh()
        self.AttributeNumberPolyBox.setText(str(self.current_selection_poly))

I use very similar functions for a different layer that has point geometry and it works great.

1 Answer 1

2

Regarding your first problem I can only assume that you forgot to commit your changes to the underlying data provider.

This could be an issue if you iterate through each feature and zoom to it's location using the feature id, because the real feature id is only assigned after saving changes. You could include some of your code which you are using to zoom to a feature in your question in order for me to give a more focused reply.

Saving the feature could be achieved by manually saving through the UI or with layer.commitChanges() or iface.actionSaveEdits().trigger().

Addressing your second issue:
Hiding the attribute form is possible by configuring the QgsEditFormConfig of a layer the following way:

poly_layer.dataProvider().addAttributes([QgsField("name", QVariant.String, 'string')])
poly_layer.updateFields()

formConfig = poly_layer.editFormConfig()
formConfig.setSuppress(QgsEditFormConfig.SuppressOn)
poly_layer.setEditFormConfig(formConfig)
4
  • Thanks for that info, I added an update on my question with more details and more code if you could please take a look. As for the adding attributes, I will give that a try, thank you.
    – tbob
    May 3, 2022 at 14:53
  • Ok so I added that second piece for the attributes, and after pushing my "ok" button and hitting save, now my arrow buttons work for selecting and zooming onto each feature. But I tried adding the commitChanges() to the feature added function so that I don't have to push "ok" to use the arrow buttons and the app still crashes, any idea why?
    – tbob
    May 3, 2022 at 15:12
  • 1
    @tbob It turns out that commiting the changes leads to an emit of featureAdded signals which in turn is causing a recursion error because your then stuck in an infinite loop. QGIS therefore crashes. You can avoid that by disconnecting your function from the signal by adding self.poly_layer.featureAdded.disconnect(self.feature_added) as first line of your feature_added function.
    – CodeBard
    May 3, 2022 at 15:45
  • Perfect, it all works now. Thank you!
    – tbob
    May 3, 2022 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.