La clase abstracta de C++ en qgis.gui: QgsRendererV2Widget

En el artículo pasado contemplamos la manera de instanciar objetos de clases abstractas de C++ pertenecientes a qgis.core: QgsFeatureRendererV2. En el presente post también nos dedicaremos a las clase abstractas de C++ pero, en este caso, pertenecientes a la interface gráfica de QGIS (qgis.gui). Mi objetivo primario es la implementación de un objeto QgsCategorizedSymbolRendererV2Widget, sin embargo, como el “PyQGIS Developer Cookbook” también tiene una porción de código para un objeto similar (QgsRendererV2Widget), en la sección de renderizados personalizados, me encomendé entonces a la tarea de hacerlo funcionar.

El código del post anterior, la implementación del Widget, su adición al registro y el programa principal los incluyo todos en un mismo sitio; tal como se presenta a continuación:

from qgis.core import *
from qgis.gui import *
from PyQt4.QtGui import *
from PyQt4.QtCore import *

import utils
reload(utils)
from utils import RandomRenderer

import random

class RandomRenderer(QgsFeatureRendererV2):
  def __init__(self, syms=None):
    QgsFeatureRendererV2.__init__(self, "RandomRenderer")
    self.syms = syms if syms else [QgsSymbolV2.defaultSymbol(QGis.Point),
                                   QgsSymbolV2.defaultSymbol(QGis.Point),
                                   QgsSymbolV2.defaultSymbol(QGis.Point)]
                                   
    
    for i in range(3):
        self.syms[i].setSize(5)
    
  def symbolForFeature(self, feature):
    return random.choice(self.syms)

  def startRender(self, context, vlayer):
    for s in self.syms:
      s.startRender(context)

  def stopRender(self, context):
    for s in self.syms:
      s.stopRender(context)

  def usedAttributes(self):
    return []

  def clone(self):
    return RandomRenderer(self.syms)

class RandomRendererWidget(QgsRendererV2Widget):
    
  def __init__(self, layer, style, renderer):
    QgsRendererV2Widget.__init__(self, layer, style)
    
    if renderer is None or renderer.type() != "RandomRenderer":
      self.r = RandomRenderer()
      
    else:
      self.r = renderer
      
    # setup UI
    self.btn1 = QgsColorButtonV2(None, "Color 1")
    self.btn1.setColor(self.r.syms[0].color())
    self.btn1.move(150, 20)
    
    self.vbox = QVBoxLayout()
    self.vbox.addWidget(self.btn1)
    self.vbox.heightForWidth(1000)
    self.vbox.setMargin(30)
    self.setLayout(self.vbox)
    
    self.connect(self.btn1, SIGNAL("clicked()"), self.setColor1)
    
  def setColor1(self):
    color = QColorDialog.getColor(self.r.syms[0].color(), self)
    
    if not color.isValid(): 
        return
        
    self.r.syms[0].setColor(color);
    self.btn1.setColor(self.r.syms[0].color())

  def renderer(self):
    return self.r

class RandomRendererMetadata(QgsRendererV2AbstractMetadata):
    
  def __init__(self):
    QgsRendererV2AbstractMetadata.__init__(self, "RandomRenderer", "Random renderer")

  def createRenderer(self, element):
    return RandomRenderer()
    
  def createRendererWidget(self, layer, style, renderer):
    return RandomRendererWidget(layer, style, renderer)

#The main program starts here

QgsRendererV2Registry.instance().addRenderer(RandomRendererMetadata())

layer = iface.activeLayer()

renderer = RandomRenderer()

style = QgsStyleV2().defaultStyle()

w= RandomRendererWidget(layer, style, renderer)
w.setWindowTitle('QgsRendererV2Widget')
w.resize(300,100)
w.move(250,300)

lbl1 = QLabel("Color 1", w)
lbl1.move(180, 35)

w.show()

layer.setRendererV2(renderer)
layer.triggerRepaint()

Con relación a la simbología, volví modificar la clase ‘RandomRenderer’ para incrementar el tamaño del símbolo y hacerlo más visible porque las imágenes de los resultados de ejecución del script las pongo en contexto con el Widget y quiero que resalten.

Cuando se ejecuta el código anterior en la Python Console tres veces consecutivas se obtuvieron los siguientes resultados:

widget1

widget2

widget3

Se observa como el Color 1 se asigna a través del botón del Widget en el renderizado del vectorial. Sin embargo, el Widget debería contener los otros dos botones para los dos grupos faltantes: Color 2 y Color 3 (no programados aquí). Por otra parte, en la imagen siguiente se visualiza como ‘Random Renderer’ ha sido incorporado al registro de símbolos. Sin embargo, como fue ejecutado desde la Python Console no tiene implementada interface gráfica en ‘Layer Properties’ y, por tanto, no puede ser aplicado.

widget4

Esta entrada fue publicada en PyQGIS, QGIS, SIG, Software Libre. Guarda el enlace permanente.

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s