[Qgis-developer] custom map canvas item?

Martin Dobias wonder.sk at gmail.com
Wed Aug 18 15:16:27 EDT 2010


Hi Ricardo

On Fri, Aug 13, 2010 at 6:19 PM, Ricardo Filipe Soares Garcia da
<ricardo.garcia.silva at gmail.com> wrote:
> Hi list
> How could I go about defining a custom Map Canvas Item in Python?
>
> In addition to the current QgsRubberBand and QgsVertexMarker I'd like
> to have a new Map Canvas Item that could write text on the map canvas.
>
> I am thinking about creating a plugin to display a raster's value
> directly on the canvas, as if it were a matrix of numbers, and thought
> that a new Map Canvas Item, kind of like QgsVertexMarker, but that
> would allow for drawing text instead of a symbol, would do the trick.
>
> I tried to subclass QgsVertexMarker and create a new method for
> drawing text, using a QPen object, but it didn't work... I guess I
> have to tell the QPen where to draw, but I don't know how to do it. If
> someone could just give me a small push I think I could manage the
> rest.

It is a better idea to subclass QgsMapCanvasItem as this is the class
intended for subclassing by 3rd parties.

I will add some thoughts on custom map canvas items to the developer
cookbook, in meanwhile here is an example I've just put together -
canvas item for displaying text:

class TextMarker(QgsMapCanvasItem):
  def __init__(self, canvas):
    QgsMapCanvasItem.__init__(self, canvas)
    self.metrics = QFontMetricsF(QFont())
    self.text = "Hello World!"
    self.setMapPosition(QgsPoint(0,0))

  def paint(self, painter, option, widget):
    painter.drawText(0,0, self.text)

  def boundingRect(self):
    return self.metrics.boundingRect(self.text)

  def updatePosition(self):
    self.setMapPosition(self.map_pos)

  def setMapPosition(self, map_pos):
    self.map_pos = map_pos
    self.setPos(self.toCanvasCoordinates(map_pos))

How to use the class:

tm = TextMarker(canvas)
tm.setMapPosition(QgsPoint(x,y))
canvas.update()

Canvas items are basically normal QGraphicsItem objects - they have to
implement paint() and boundingRect() methods. Additionally, the text
marker from the example is going to be "spatially aware" - if you
change canvas extent (zoom/pan), it will change its position
accordingly - this is thanks to the updatePosition() function which is
called by map canvas when the extent has changed.

Hope that helps

Martin


More information about the Qgis-developer mailing list