Программно проверить наличие щелчка мыши в 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.