# QGIS 2.4: plugin changes map tool canvas click behavior from 2.0

I had created a plugin for QGIS 2.0 to add new features more easily. It involves changing extents and updating snapping options along with triggering the default actionAddFeature(). However, I've decided to update to QGIS 2.4 and now notice that it has changed in behavior, but I cannot figure out why.

I'd created a mapTool to emit a point:

def __init__(self, iface):
...
self.canvas = self.iface.mapCanvas()
self.clickTool = QgsMapToolEmitPoint(self.canvas)
...


I connected the map tool to a function:

def initGui(self):
self.clickTool.canvasClicked.connect(self.zoomTo)


The zoomTo tool zooms into a certain defined rectangle extent and triggers other functions depending on if statements

def zoomTo(self):
...
box = pntBuff.boundingBox()
self.canvas.setExtent(box)
self.canvas.refresh()
if self.iface.activeLayer() == layer1:
if self.iface.activeLayer() == layer2:


My problem lies here: Using my plugin with QGIS 2.0, the first canvas click zoomed to my desired extent (done by zoomTo()) and required a second canvas click to actually add the feature (triggered by addElement1()). Using the plugin in QGIS 2.4, the first canvas click zooms AND adds the feature at the same time without requiring a second mouse click (this means I can't easily control where exactly I'm placing my elements).

def addElement1(self):
if not layer1.isEditable():
self.layer1.startEditing()
self.iface.setActiveLayer(self.layer1)


My run method zooms out to my layer's extent and sets my map tool:

def run(self):
#zoomOut() defined to set to layer's extent--different from zoomTo
self.zoomOut()
self.canvas.setMapTool(self.clickTool)


UPDATE: I'm still trying to target this issue and have created a second map tool to trigger the add feature action (on top of the original click tool). The first click zooms to the area and the second click should simply trigger the feature add action tool (requiring a third click to actually add the feature and open feature form). However, the second click triggers the action AND adds the feature right away (with only one click). While the difficulties of not being zoomed in previously stated is no longer an issue, it is still problematic as 1) the cursor does not change to "add feature" target symbol and 2) the snapping option cross does not show up.

When testing qgis.utils.iface.addFeatureAction().trigger() in the python console, the add feature button is simply toggled. It must be some combination of my emit point map tool with the add feature action. I wonder how I can access the add feature tool in a more detailed way, keeping it from firing in this unexpected way.

def __init__(self, iface):
...
self.canvas = self.iface.mapCanvas()
self.clickTool = QgsMapToolEmitPoint(self.canvas)
...

def initGui(self):
self.clickTool.canvasClicked.connect(self.zoomTo)

def zoomTo(self):
...
box = pntBuff.boundingBox()
self.canvas.setExtent(box)
self.canvas.refresh()
if self.iface.activeLayer() == layer1:
self.setMyMapTool()
...

def setMyMapTool(self):



At this point, I feel like i've tried so many things without success. Just wondering if anyone can tell whether this is some sort of bug, or an error on my part.

• What does does add element look like? – Nathan W Jul 11 '14 at 23:43
• @Nathan W I just added the addElement1() function code to my post – user25976 Jul 11 '14 at 23:51
• First just try calling self.iface.actionAddFeature().trigger() from the Python console. What does it do? – Nathan W Jul 12 '14 at 0:16
• @NathanW From the python console: after setting my layer active and in edit mode, if i'm on another tool (e.g. pan tool) calling qgis.utils.iface.actionAddFeature().trigger() changes the map tool to the add feature tool. If i'm already on this tool, it stays on the add feature tool. This changes cursor to the add feature-type cursor, allowing me to add the feature. – user25976 Jul 12 '14 at 1:17

QgsMapToolEmitPoint implements the method canvasPressEvent while QgsMapToolAddFeature implements the method canvasReleaseEvent to trigger its actions.

CanvasPressEvent is called before canvasReleaseEvent so if you replace the maptool in the first method, the second one will be called on the new map tool.

I would recommend to create a new map tool that does the same as QgsMapToolEmitPoint but in canvasReleaseEvent

class MyMapToolEmitPoint( QgsMapTool ):
canvasClicked = pyqtSignal( ['QgsPoint', 'Qt::MouseButton'] )
def canvasReleaseEvent( self, mouseEvent ):
pnt = self.toMapCoordinates( mouseEvent.pos() )
self.canvasClicked.emit( pnt, mouseEvent.button() )

• Did this change between versions? I'm wondering why I didn't see this issue before. I'm going to accept your answer as soon as I get this working. – user25976 Aug 7 '14 at 1:05

I had similar weird behavior with QGIS 2.4 . I am guessing that it as something to do with multithreading introduction in 2.4. It can affect the execution order. It may explain the WHY part of your question.

• This is very unlikely as user inputs are all processed in the main thread. Without investigating it in detail, it is most likely related to changes in the maptools in question. – Matthias Kuhn Feb 10 '15 at 17:04