2

I am currently working on a PyQgis based standalone application and I need to add various QgsRubberBand to my Canvas.

I made a subclass of it : LineAnnotation.

The problem is that when I use the method "QgsMapCanvas.itemAt(event.pos() )" on a "canvasPressEvent", it returns a "qgis._gui.QgsRubberBand" object, not a "LineAnnotation".

Did I do something wrong ? The rest of my program can't work if it doesn't recognize that it's a LineAnnotation as it contains several new methods that I need to use.

Also I can't interact with the item at all, if I try to use one of the methods from QgsRubberBand, the application crashes.

Here is the code with the problem:

from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge, QgsRubberBand
from qgis.core import QgsApplication, QgsProject, QgsPointXY, QgsGeometry
from qgis.PyQt.QtGui import QColor
import sys

class LineAnnotation(QgsRubberBand):
    def __init__(self, canvas):
        QgsRubberBand.__init__(self, canvas)
        self.setColor(QColor("red") )
        self.setWidth(10)

class Interface(QgsMapCanvas):
    def __init__(self):
        QgsMapCanvas.__init__(self)
        self.setCanvasColor(QColor("#182F36") )
        project_path = "project_path"

        project = QgsProject.instance()
        project.read(project_path)
        layer_tree = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas=self)
        layer_tree.setAutoSetupOnFirstLayer(False)
        self.zoomToFeatureExtent(project.mapLayersByName('layer_name')[0].extent() )
        self.enableAntiAliasing(True)
        self.setAcceptDrops(True)
        self.setParallelRenderingEnabled(True)

        p1 = QgsPointXY(524670.46860305720474571, 5470375.41737424582242966)
        p2 = QgsPointXY(589864.10151600651443005, 5487531.63656186405569315)

        r = LineAnnotation(self)
        r.setToGeometry(QgsGeometry.fromPolylineXY([p1, p2]) )

    def mousePressEvent(self, event) -> None:
        item = self.itemAt(event.pos() )
        print(type(item) ) 
        # Output is "<class 'qgis._gui.QgsRubberBand'>"
        # Expected: "<class 'LineAnnotation'>"

class StackOverflow:
    def __init__(self):
        qgs = QgsApplication([], True)
        qgs.setDoubleClickInterval(250)
        qgs.initQgis()

        graphicUI = Interface()
        graphicUI.showMaximized()

        sys.exit(qgs.exec_() )

if __name__ == '__main__':
    app = StackOverflow()


> output: \<class 'qgis.\_gui.QgsRubberBand'\>
> Desired output: \<class 'lineAnnotation.LineAnnotation'\>
Eggdrasil
  • 21
  • 4
  • Please provide a [mre]. – musicamante Dec 08 '22 at 17:16
  • Please consider rephrasing the title of your question as your problem ist not with `isinstance()`. The type of `item` is not what you expect and you should work on that. Once you get an item of the correct type, `isinstace()` will happily return `True`. – SebDieBln Dec 08 '22 at 17:53
  • @SebDieBln You're right, I changed it. – Eggdrasil Dec 09 '22 at 09:49
  • @musicamante I just added the code that reproduces the problem – Eggdrasil Dec 09 '22 at 09:50
  • @Eggdrasil I cannot help you on this specific problem as I don't use QGis, but it *might* be related to [this report](https://github.com/qgis/QGIS/issues/48471). It seems to be fixed in version 3.26, do you have at least that version? – musicamante Dec 09 '22 at 14:31
  • @musicamante Sorry for the delay, I was using Qgis ltr Version 3.20. Problem was solved after updating latest version (Qgis 3.28). Thanks for your help – Eggdrasil Dec 13 '22 at 08:50

1 Answers1

0

Problem seems to occur in versions prior to Qgis 3.26, my problem was solved after updating to latest version (3.28).

Eggdrasil
  • 21
  • 4