Программно проверить наличие щелчка мыши в PyQGIS?

19

Я хочу знать, как проверить наличие щелчка мыши в QGIS. Я пытаюсь написать плагин Python и хочу предоставить функциональность, аналогичную инструменту «Выбрать одну функцию», который уже существует в QGIS.

Я проверил документы API QGIS и нашел

QgsMapCanvas::CanvasProperties::mouseButtonDown

Это звучит многообещающе. У меня есть объект QgsMapCanvas, но я не вижу, как получить доступ к атрибуту mouseButtonDown.

Я совершенно новичок в QGIS API.

Роберт
источник

Ответы:

23

Лучший способ создать новый инструмент, такой как инструмент Select Single Feature, - это наследовать от QgsMapToolкласса. Когда ваш инструмент активен, и его можно настроить с помощью QgsMapCanvas::setMapToolлюбых событий клавиатуры или щелчка, которые получает холст, они будут переданы в ваш пользовательский инструмент.

Вот основной QgsMapToolкласс

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

Вы можете делать то, что вам нужно canvasReleaseEvent, и т. Д.

Чтобы активировать этот инструмент, просто сделайте:

tool = PointTool(qgis.iface.mapCanvas())
qgis.iface.mapCanvas().setMapTool(tool)
Натан У
источник
Благодарю за ваш ответ. Это именно то, что мне нужно. Однако, когда я пытаюсь реализации этого решения я получаю следующее сообщение об ошибке: class PointTool(QgsMapTool): NameError: name 'QgsMapTool' is not defined. Есть идеи?
Роберт
1
Вам нужно будет использовать from qgis.gui import QgsMapToolнаверху
Натан W
Последний вопрос ... Как вы тогда деактивируете этот инструмент?
Роберт
Установите maptool на что-то другое или на None. Я бы сохранил то, что выбрал пользователь, используя QgsMapCanvas.mapTool()восстановление после того, как вы закончите.
Натан Вт,
@NathanW «Чтобы установить maptool на что-то другое», это также означает, что я нажимаю «Pan Map» на панели инструментов, верно?
wannik
3

Я думаю, что вы можете сделать это с помощью комбинации QGIS "canvasClicked", а также SIGNAL / SLOTS для обработки ответа:

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

Не пытался, но должен дать вам больше информации, чтобы начать смотреть. Здесь есть учебник, где кто-то использует его для создания очень простого плагина.

Дэн
источник
1
Они используют встроенный QgsMapToolEmitPointкласс, который даст вам базовый старт для инструмента. Хороший способ подключиться к сигналам в PyQt - использовать этот синтаксисself.clickTool.canvasClicked.connect(self.handleMouseDown)
Натан В
1

Попробуйте что-то вроде этого (это чтобы выбрать точку):

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 )
Андре Барригинья
источник
Я бы использовал self.clickTool.canvasClicked.connect(self.handleMouseDown)синтаксис для подключения к сигналам, так как он намного чище.
Натан W