3

I'm writing a plugin (based on Plugin Builder 3 "tool button with dialog") to allow complex annotation in QGIS 3.10.5, and whilst I can add annotations OK, as soon as there's more than one, I can't remove them without crashing QGIS.

Annotation is added by

# Do something useful here - delete the line containing pass and
# substitute with your code.
marker = QgsMarkerSymbol.createSimple({"size":"0.1","color":"blue"})
layer = self.iface.activeLayer()
for feature in layer.selectedFeatures():
    attrs = feature.attributes()
    geom = feature.geometry()
    point = geom.asPoint()
    easting = point.x()
    northing = point.y()
    html = "<table><tbody><tr><td>{int(attrs[1])}</td><td>{attrs[2]}</td></tr>"
    html += "<tr><td>{int(attrs[5])} cas</td><td>{int(attrs[6])} veh</td></tr>"
    html += "</tbody></table>"
    htmlData = eval("f'"+html+"'")   # substitutes the layer attributes into the html text string

    content = QTextDocument()
    content.setHtml(htmlData)

    annot = QgsTextAnnotation()
    annot.setFrameSizeMm(QSizeF(25, 12))
    annot.setMapLayer(layer)
    annot.setFrameOffsetFromReferencePointMm(QPoint(15, 15))
    annot.setMapPositionCrs(QgsCoordinateReferenceSystem(layer.crs()))
    annot.setMapPosition(QgsPointXY(easting, northing))
    annot.setMarkerSymbol(marker)
    annot.setDocument(content)
    QgsProject.instance().annotationManager().addAnnotation(annot)

That creates the annotation items OK 2 map features annotated

To remove the annotation, I'm doing...

def clear_annotations(self):
    annotations = QgsProject.instance().annotationManager().annotations()
    for annot in annotations:
        QgsProject.instance().annotationManager().removeAnnotation(annot)
    #
    # or, by swapping what's commented out...
    #
    #QgsProject.instance().annotationManager().clear()

I've tried deleting them both individually, and by clearing all annotation, and whilst it works OK if I've only created a single annotation item, QGIS crashes as soon as there are more than one. Adding QMessageBoxes leads me to believe that the crash is on the second call to the annotationManager.

Using the python console instead doesn't help, and if I try to remove the annotations manually using the toolbar Annotation tool, I can delete the first annotation item, but I get "Access violation - no RTTI data!" as soon as I click on the next, and have to kill QGIS.

Has anyone any idea what I'm doing wrong?

ThomasG77 has provided the correct answer

1
  • Dumb question: did you try to set initial annotationManager = QgsProject.instance().annotationManager() in def clear_annotations(self): and then everywhere make a call using this reference?
    – ThomasG77
    Commented Jul 14, 2020 at 22:01

1 Answer 1

3

You just need to move your marker = QgsMarkerSymbol.createSimple({"size":"0.1","color":"blue"}) declaration within the loop (tested). Then when cleaning, no problem. It was crashing because you were trying to remove a reference to a marker already cleaned with the first annotation removal. See below correction

# Do something useful here - delete the line containing pass and
# substitute with your code.
layer = self.iface.activeLayer()
for feature in layer.selectedFeatures():
    attrs = feature.attributes()
    geom = feature.geometry()
    point = geom.asPoint()
    easting = point.x()
    northing = point.y()
    html = "<table><tbody><tr><td>{int(attrs[1])}</td><td>{attrs[2]}</td></tr>"
    html += "<tr><td>{int(attrs[5])} cas</td><td>{int(attrs[6])} veh</td></tr>"
    html += "</tbody></table>"
    htmlData = eval("f'"+html+"'")   # substitutes the layer attributes into the html text string

    content = QTextDocument()
    content.setHtml(htmlData)

    annot = QgsTextAnnotation()
    annot.setFrameSizeMm(QSizeF(25, 12))
    annot.setMapLayer(layer)
    annot.setFrameOffsetFromReferencePointMm(QPoint(15, 15))
    annot.setMapPositionCrs(QgsCoordinateReferenceSystem(layer.crs()))
    annot.setMapPosition(QgsPointXY(easting, northing))
    marker = QgsMarkerSymbol.createSimple({"size":"0.1","color":"blue"})
    annot.setMarkerSymbol(marker)
    annot.setDocument(content)
    QgsProject.instance().annotationManager().addAnnotation(annot)
1
  • Thank you.- works perfectly
    – Andrew_S
    Commented Jul 15, 2020 at 9:35

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.