Lập trình kiểm tra nhấp chuột trong PyQGIS?


19

Tôi muốn biết làm thế nào để kiểm tra nhấp chuột trong QGIS. Tôi đang cố gắng viết một plugin python và muốn cung cấp chức năng tương tự như công cụ "Chọn tính năng duy nhất" đã tồn tại trong QGIS.

Tôi đã kiểm tra tài liệu api của QGIS và tìm thấy

QgsMapCanvas::CanvasProperties::mouseButtonDown

Điều này nghe có vẻ hứa hẹn. Tôi có một đối tượng QssMapCanvas nhưng tôi không thể xem cách truy cập thuộc tính mouseButtonDown.

Tôi hoàn toàn mới đối với API QGIS.

Câu trả lời:


23

Cách tốt nhất để tạo một công cụ mới như công cụ Chọn một tính năng là kế thừa từ QgsMapToollớp. Khi công cụ của bạn đang hoạt động, có thể được đặt bằng cách sử dụng QgsMapCanvas::setMapTool, mọi bàn phím hoặc nhấp vào các sự kiện mà canvas nhận được sẽ được chuyển vào công cụ tùy chỉnh của bạn.

Đây là một QgsMapToollớp học cơ bản

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

Bạn có thể làm những gì bạn cần canvasReleaseEvent, v.v.

Để thiết lập công cụ này hoạt động, bạn chỉ cần làm:

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

Cảm ơn bạn đã phản hồi của bạn. Đó chính xác là những gì tôi cần. Tuy nhiên, khi tôi thử thực hiện giải pháp này, tôi gặp lỗi sau : class PointTool(QgsMapTool): NameError: name 'QgsMapTool' is not defined. Có ý kiến ​​gì không?
robert

1
Bạn sẽ cần sử dụng from qgis.gui import QgsMapToolở trên cùng
Nathan W

Câu hỏi cuối cùng ... Làm thế nào để bạn hủy kích hoạt công cụ này?
robert

Đặt maptool thành một cái gì đó khác hoặc None. Tôi sẽ lưu những gì người dùng đã chọn bằng cách QgsMapCanvas.mapTool()khôi phục nó sau khi bạn hoàn thành.
Nathan W

@NathanW "Để đặt maptool thành thứ khác" cũng có nghĩa là tôi nhấp vào 'Pan Map' trên thanh công cụ, phải không?
Wannik

3

Tôi nghĩ rằng bạn có thể làm điều này với sự kết hợp của việc sử dụng "canvasClicky" của QGIS nhưng cũng có TÍN HIỆU / SLOTS để đối phó với phản hồi:

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

Không thử nhưng sẽ cung cấp cho bạn thêm một số thông tin để bắt đầu xem xét. Có một hướng dẫn ở đây , nơi ai đó đang sử dụng điều này để xây dựng một plugin rất cơ bản.


1
Họ đang sử dụng lớp dựng sẵn QgsMapToolEmitPointsẽ cung cấp cho bạn sự khởi đầu cơ bản cho một công cụ. Một cách tốt để kết nối với các tín hiệu trong PyQt là sử dụng cú pháp nàyself.clickTool.canvasClicked.connect(self.handleMouseDown)
Nathan W

1

Hãy thử một cái gì đó như thế này (đây là để chọn một điểm):

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 )

Tôi sẽ sử dụng self.clickTool.canvasClicked.connect(self.handleMouseDown)cú pháp để kết nối với các tín hiệu vì nó sạch hơn nhiều.
Nathan W
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.