3 votos

La eliminación programada de los elementos de anotación se estrella con QGIS 3.10

Estoy escribiendo un plugin (basado en el Plugin Builder 3 "botón de herramienta con diálogo") para permitir anotaciones complejas en QGIS 3.10.5, y aunque puedo añadir anotaciones OK, en cuanto hay más de una, no puedo eliminarlas sin que se cuelgue QGIS.

La anotación se añade mediante

# 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)

Eso crea los elementos de anotación OK 2 map features annotated

Para eliminar la anotación, estoy haciendo...

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()

He probado a eliminarlas tanto individualmente como borrando todas las anotaciones, y aunque funciona bien si sólo he creado un único elemento de anotación, QGIS se bloquea en cuanto hay más de uno. La adición de QMessageBoxes me hace pensar que el fallo se produce en la segunda llamada al annotationManager.

Usar la consola de python no ayuda, y si intento eliminar las anotaciones manualmente usando la herramienta de Anotaciones de la barra de herramientas, puedo eliminar el primer elemento de anotación, pero obtengo "Violación de acceso - ¡no hay datos RTTI!" tan pronto como hago clic en el siguiente, y tengo que matar a QGIS.

¿Tiene alguien alguna idea de lo que estoy haciendo mal?

ThomasG77 ha proporcionado la respuesta correcta

0 votos

Pregunta tonta: ¿Intentaste poner en marcha el annotationManager = QgsProject.instance().annotationManager() en def clear_annotations(self): y luego en todas partes hacer una llamada utilizando esta referencia?

3voto

BWW Puntos 302

Sólo tienes que mover tu marker = QgsMarkerSymbol.createSimple({"size":"0.1","color":"blue"}) dentro del bucle (probado). Luego, al limpiar, no hay problema. Se bloqueaba porque se intentaba eliminar una referencia a un marcador ya limpiado con la primera eliminación de la anotación. Véase la siguiente corrección

# 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)

0 votos

Gracias. Funciona perfectamente

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X