0

I am implementing a stand alone version of the answer to this question How to programatically check for a mouse click in QGIS

My code is below. The code compiles without error, and the toolbar button "GetCoordinates Tool" runs the class init for PointTool.

The problem is that the canvasReleaseEvent does not seem to fire when clicking the canvas.. in fact nothing happens when I click the canvas.

Any pointers?

# OurApp.py

from PyQt4.QtGui import *
from qgis.core import *

from ourmainwindow import OurMainWindow

app = QApplication([])
# set up QGIS
QgsApplication.setPrefixPath('/usr', True)
QgsApplication.initQgis()

# set the main window and show it
mw = OurMainWindow()
mw.show()

app.exec_()

mw = None
# clean up QGIS
QgsApplication.exitQgis()

#ourmainwindow.py

import os

from PyQt4.QtGui import *

from qgis.gui import *
from qgis.core import *

import resources
from PyQt4.QtGui import QAction, QMainWindow
from PyQt4.QtCore import SIGNAL, Qt

import sys, os


  from lxml.html.builder import CENTER
  from PyQt4.QtCore import SIGNAL, Qt, QString

  class OurMainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.setupGui()

    self.add_ogr_layer('/data/alaska.shp')
    self.map_canvas.zoomToFullExtent()
    mCanvas = QgsMapCanvas()
    self.map_canvas = mCanvas


#def canvasPressEvent(self, e):
#    self.startPoint = self.toMapCoordinates(e.pos())
#    self.endPoint = self.startPoint
#    self.isEmittingPoint = True
#    self.showRect(self.startPoint, self.endPoint)

def setupGui(self):
    frame = QFrame(self)
    self.setCentralWidget(frame)
    self.grid_layout = QGridLayout(frame)

    self.map_canvas = QgsMapCanvas()
    extentBox = self.map_canvas.extent()
    xCoMin = extentBox.xMinimum()
    xCoM = extentBox.xMaximum()

    self.map_canvas.setCanvasColor(QColor(255, 255, 255))
    self.grid_layout.addWidget(self.map_canvas)

    # setup action(s)
    self.zoomin_action = QAction(
        QIcon(":/ourapp/zoomin_icon"),
        "Zoom In",
        self)

    self.identify2_action = QAction( QString("GetCoordinates tool"), self)
    self.identify2_action.setCheckable(True)
    self.identify2_action.setChecked(True)
    # create toolbar
    self.toolbar = self.addToolBar("Map Tools")
    self.toolbar.addAction(self.identify2_action)
    self.identify2_action.setCheckable(True)


    # connect the tool(s)

    self.identify2_action.triggered.connect(self.identify2)

                    # create the map tool(s)

    self.tool_identify2 = QgsMapToolIdentify(self.map_canvas)

def add_ogr_layer(self, path):
    #(name, ext) = os.path.basename(path).split('.')
    #layer = QgsVectorLayer(path, name, 'ogr')
    #QgsMapLayerRegistry.instance().addMapLayer(layer)
    layer = QgsVectorLayer('/home/Documents/Data/pyqgis_data/alaska.shp','alaska','ogr')
    QgsMapLayerRegistry.instance().addMapLayer(layer)

    canvas_layer = QgsMapCanvasLayer(layer)
    self.map_canvas.setLayerSet([canvas_layer])

def identify2(self):
    #self.map_canvas.setMapTool(self.tool_zoomin)
    mCanvas = self.map_canvas
    self.canvas = mCanvas
    QgsMapToolEmitPoint.__init__(self, self.canvas)
    #RectangleMapTool(mCanvas)
    #PointTool(mCanvas)
    tool = PointTool(self.map_canvas)
    self.map_canvas.setMapTool(tool)
    #tool = PointTool(self, self.map_canvas)
    #QMessageBox.warning(None, test2)


class PointTool(QgsMapTool):   
    def __init__(self, canvas):
        QgsMapTool.__init__(self, canvas)
        self.canvas = canvas    

    def canvasPressEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()

        point = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)
    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
0

2 Answers 2

4

Nothing happpens, because you are doing not much within your PointTool. Also your PointTool does not look good (looks like you copied it from C++ or something else...)! I would rewrite it to:

class PointTool(QgsMapToolEmitPoint):
def __init__(self, canvas):
    QgsMapToolEmitPoint.__init__(self, canvas)

def canvasReleaseEvent(self, mouseEvent):
    qgsPoint = self.toMapCoordinates(mouseEvent.pos())
    print('x:', qgsPoint.x(), ', y:', qgsPoint.y())

which in a first step simply prints out x and y (in map coordinates) when clicking on the canvas. In the setupGui() function you should write:

self.tool_identify2 = PointTool(self.map_canvas)

And finally, identify2 function should simply do:

self.map_canvas.setMapTool(self.tool_identify2)

After all, you should really take a deep look into the cookbook chapter about MapCanvas - there are a few good examples!

1
  • The reason it doesn't do much is Im just trying to hit a break point for now. I replaced the code as suggested (I believe so anyway) with the result that clicking the button now converts the cursor to a cross, which I take to mean that the tool is now active. However the canvasReleaseEvent still does not run on click?
    – AnserGIS
    Jun 10, 2016 at 13:09
1

With a little bit of tinkering to remove the iface elements I found this solution effective

How to link my QGIS plugin main class to mouse events from a custom Tool?

Thanks

Not the answer you're looking for? Browse other questions tagged or ask your own question.