24 votos

¿Comprobar de forma programada el clic del ratón en PyQGIS?

Quiero saber cómo comprobar un clic del ratón en QGIS. Estoy tratando de escribir un plugin de python y quiero proporcionar una funcionalidad similar a la herramienta "Select Single Feature" que ya existe en QGIS.

He comprobado la documentación de la API de QGIS y he encontrado

QgsMapCanvas::CanvasProperties::mouseButtonDown

Esto parece prometedor. Tengo un objeto QgsMapCanvas pero no veo cómo acceder al atributo mouseButtonDown.

Soy completamente nuevo en la API de QGIS.

24voto

Jauder Ho Puntos 3172

La mejor manera de crear una nueva herramienta, como la herramienta Seleccionar una sola característica, es heredar de la herramienta QgsMapTool clase. Cuando su herramienta está activa, lo que puede establecerse mediante QgsMapCanvas::setMapTool cualquier evento de teclado o de clic que reciba el lienzo será pasado a tu herramienta personalizada.

A continuación, se presenta un esquema básico QgsMapTool clase

class PointTool(QgsMapTool):   
    def __init__(self, canvas):
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas    

    def canvasPressEvent(self, event):
        pass

    def canvasMoveEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)

    def canvasReleaseEvent(self, event):
        #Get the click
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)

    def activate(self):
        pass

    def deactivate(self):
        pass

    def isZoomTool(self):
        return False

    def isTransient(self):
        return False

    def isEditTool(self):
        return True

Puedes hacer lo que necesites en canvasReleaseEvent etc.

Para activar esta herramienta basta con hacer:

tool = PointTool(qgis.iface.mapCanvas())
qgis.iface.mapCanvas().setMapTool(tool)

0 votos

Gracias por su respuesta. Es exactamente lo que necesito. Sin embargo, cuando trato de implementar esta solución obtengo el siguiente error: class PointTool(QgsMapTool): NameError: name 'QgsMapTool' is not defined . ¿Alguna idea?

1 votos

Deberá utilizar from qgis.gui import QgsMapTool en la parte superior

0 votos

Última pregunta... ¿Cómo se desactiva esta herramienta?

4voto

Dan Puntos 326

Creo que se puede hacer esto con una combinación de uso de QGIS "canvasClicked" pero también SIGNAL/SLOTS para tratar la respuesta:

result = QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.handleMouseDown)

No lo he probado, pero debería darte algo más de información para empezar a mirar. Hay un tutorial aquí donde alguien está usando esto para construir un plugin muy básico.

1 votos

Utilizan el sistema integrado de QgsMapToolEmitPoint que le dará el inicio básico de una herramienta. Una buena manera de conectarse a las señales en PyQt es usando esta sintaxis self.clickTool.canvasClicked.connect(self.handleMouseDown)

1voto

Pajushka Puntos 11

Prueba algo así (esto es para seleccionar un punto):

def run(self):
    self.pointEmitter = QgsMapToolEmitPoint(self.iface.mapCanvas())
    QObject.connect( self.pointEmitter, SIGNAL("canvasClicked(const QgsPoint, Qt::MouseButton)"), self.selectNow)
    self.iface.mapCanvas().setMapTool( self.pointEmitter )

def selectNow(self, point, button):
  #QMessageBox.information(None, "Clicked coords", " x: " + str(point.x()) + " Y: " + str(point.y()) )

  layer = self.iface.activeLayer()
  if not layer or layer.type() != QgsMapLayer.VectorLayer:
     QMessageBox.warning(None, "No!", "Select a vector layer")
     return

  width = self.iface.mapCanvas().mapUnitsPerPixel() * 2
  rect = QgsRectangle(point.x() - width,
                      point.y() - width,
                      point.x() + width,
                      point.y() + width)

  rect = self.iface.mapCanvas().mapRenderer().mapToLayerCoordinates(layer, rect)

  layer.select([], rect)
  feat = QgsFeature()

  ids = []
  while layer.nextFeature(feat):
    ids.append( feat.id() )

  layer.setSelectedFeatures( ids )

0 votos

Utilizaría el self.clickTool.canvasClicked.connect(self.handleMouseDown) sintaxis para conectarse a las señales, ya que es mucho más limpio.

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