3

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:
        self.addElement1()
    if self.iface.activeLayer() == layer2:
        self.addElement2()

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).

addElement1() and addElement2() both start editing, set active layers, and trigger actionAddFeature for respective layers.

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

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)
    self.addFeatureTool = QgsMapToolEmitPoint(self.canvas)
...

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

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

def setMyMapTool(self):
    self.canvas.setMapTool(self.addVanneTool)

def addMyFeature(self):
    self.iface.actionAddFeature().trigger()

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.

4
  • What does does add element look like?
    – Nathan W
    Commented Jul 11, 2014 at 23:43
  • @Nathan W I just added the addElement1() function code to my post
    – user25976
    Commented Jul 11, 2014 at 23:51
  • First just try calling self.iface.actionAddFeature().trigger() from the Python console. What does it do?
    – Nathan W
    Commented Jul 12, 2014 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
    Commented Jul 12, 2014 at 1:17

2 Answers 2

5

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() )
1
  • 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
    Commented Aug 7, 2014 at 1:05
1

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.

1
  • 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. Commented Feb 10, 2015 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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