ตรวจสอบการคลิกเมาส์ใน PyQGIS โดยทางโปรแกรมหรือไม่


19

ฉันต้องการทราบวิธีตรวจสอบการคลิกเมาส์ใน QGIS ฉันกำลังพยายามเขียนปลั๊กอินหลามและต้องการมอบฟังก์ชันการทำงานที่คล้ายกับเครื่องมือ "Select Single Feature" ที่มีอยู่แล้วใน QGIS

ฉันตรวจสอบเอกสาร QGIS api และพบว่า

QgsMapCanvas::CanvasProperties::mouseButtonDown

ฟังดูมีแนวโน้ม ฉันมีวัตถุ QgsMapCanvas แต่ฉันไม่เห็นวิธีการเข้าถึงคุณสมบัติ mouseButtonDown

ฉันยังใหม่กับ QGIS API อย่างสมบูรณ์

คำตอบ:


23

วิธีที่ดีที่สุดในการสร้างเครื่องมือใหม่เช่นเครื่องมือ Select Single Feature คือการสืบทอดจาก QgsMapToolคลาส เมื่อเครื่องมือของคุณเปิดใช้งานซึ่งสามารถตั้งค่าได้โดยใช้QgsMapCanvas::setMapToolแป้นพิมพ์หรือเหตุการณ์การคลิกใด ๆ ที่ Canvas ได้รับจะถูกส่งไปยังเครื่องมือที่กำหนดเองของคุณ

นี่คือ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()การกู้คืนหลังจากคุณทำเสร็จแล้ว
Nathan W

@NathanW "ในการตั้งค่า maptool เป็นอย่างอื่น" ก็หมายความว่าฉันคลิก 'Pan Map' บนแถบเครื่องมือใช่ไหม?
wannik

3

ฉันคิดว่าคุณสามารถทำได้ด้วยการรวมกันของการใช้ QGIS "canvasClicked" แต่ยังมีสัญญาณ / ช่องเพื่อจัดการกับการตอบสนอง:

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

ไม่พยายาม แต่ควรให้ข้อมูลเพิ่มเติมแก่คุณเพื่อเริ่มดู มีการสอนที่นี่ที่มีคนใช้สิ่งนี้เพื่อสร้างปลั๊กอินพื้นฐานมาก


1
พวกเขาใช้QgsMapToolEmitPointคลาสในตัวซึ่งจะทำให้คุณเริ่มต้นขั้นพื้นฐานสำหรับเครื่องมือ วิธีที่ดีในการเชื่อมต่อสัญญาณใน PyQt คือการใช้ไวยากรณ์นี้self.clickTool.canvasClicked.connect(self.handleMouseDown)
Nathan W

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.