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
2 Answers 2
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!
-
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– AnserGIS2016年06月10日 13:09:07 +00:00Commented Jun 10, 2016 at 13:09
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