Програматично перевірити клацання миші в PyQGIS?


19

Я хочу знати, як перевірити наявність клацання миші в QGIS. Я намагаюся написати плагін python і хочу надати функціонал, подібний до інструменту "Вибрати єдину функцію", який вже існує в QGIS.

Я перевірив документи api QGIS і виявив

QgsMapCanvas::CanvasProperties::mouseButtonDown

Це звучить перспективно. У мене є об'єкт QgsMapCanvas, але я не бачу, як отримати доступ до атрибута mouseButtonDown.

Я абсолютно новий в API QGIS.

Відповіді:


23

Найкращий спосіб створити новий інструмент, як інструмент "Виділити одну функцію" - це успадкувати від 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вгорі
Nathan W

Останнє запитання ... Як потім вимкнути цей інструмент?
Роберт

Встановіть Maptool на щось інше або на None. Я б врятував те, що обрав користувач, використовуючи QgsMapCanvas.mapTool()відновлення його після завершення.
Nathan W

@NathanW "Щоб встановити maptool на щось інше", це означає, що я натискаю "Панорама" на панелі інструментів, правда?
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)синтаксис для підключення до сигналів, оскільки він набагато чистіший.
Натан Ш
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.