One of the attributes/features of my layer contains an email address. I'd like to be able to open the default mail client by clicking on the mail address from the Attribute Table.

After some initial investigation I've found, what seems to be, two different possibilities.

1) I could make an action 'Layer Properties/Actions', or

2) perhaps I could change the fields 'Edit widget' in Layer 'Properties/Fields' to a 'Web view', and that would take care of it(?)

On option 1) I'm a bit unsure how to create an action programmatically using PyQGIS. I've found that a QgsVectorLayer has a function actions() that returns a QgsAttributeAction object. The QgsAttributeAction has an addAction function, so I should be able to use it like this...

layer = iface.activeLayer()
aa = layer.actions()

but I'm not a 100% on the arguments. From the documentation:

addAction(QgsAction::ActionType type, QString name, QString action, bool capture=false)

Anyone done this before that could give a few hints?


Here's a slight refinement to dakcarto's approach. Instead of using QgsAction, you can use a QgsMapLayerAction. This has a few advantages:

  • QgsMapLayerActions aren't shown in the layer property's action tab, and can't be modified or removed by users
  • QgsMapLayerActions can be connected directly to an existing python function in your plugin

Here's a example of creating a QgsMapLayerAction:

l = iface.activeLayer()
#attach a QgsMapLayerAction to the active layer:
openMailAction = qgis.gui.QgsMapLayerAction( "Send an email" , iface, l );
#add the action to the QGIS gui, so that it appears as an action for the layer
#connect to action trigger

def send_email(layer,feature):
    #layer is a reference to the layer the actions was triggered on, feature
    #is a reference to the feature the action was triggered for
    print feature['EMAIL']

Obviously, you'd still need to insert some python code for opening Outlook and creating an email to the send_email function.

  • @dakcarto @ndawson I can get it to fill the recipients (To:) field with the name of the attribute i.e., address but not substitute the name with the actual value/mail address. Any ideas to what the problem could be?
    – user28233
    May 2 '14 at 13:11
  • The only time that happened to me was when the field name was not exactly the same. Or, maybe you defined the action to the wrong layer. Use the Action dialog's Insert field to create the [% "FIELD" %] text to verify field name.
    – dakcarto
    May 2 '14 at 17:57
  • @ndawson I'm wondering how to set up the imports. I tried from qgis.gui import *. I get AttributeError when trying qgis.gui.QgsMapLayerAction. QgsMapLayerAction by itself gives me NameError. from qgis.gui import QgsMapLayerAction gives ImportError. This is in the python console using QGIS 2.0
    – user25976
    Jul 9 '14 at 19:00
  • 1
    @user25976 this feature was introduced in 2.2 - it's not available in 2.0.
    – ndawson
    Jul 9 '14 at 19:44

Adding an Open action (i.e. open url) is probably what you want:

enter image description here

You can do this programmatically via PyQGIS (would create action above):

l = iface.activeLayer()  # get reference to a layer
aa = l.actions()  # these are the QgsAttributeAction(s) for the layer
aa.addAction(QgsAction.OpenUrl, 'Email', 'mailto:[% "EMAIL" %]')
iface.actionSaveProject().trigger()  # save project, so new action is saved

The action types are listed here.

If you want some validation for the email address, you will probably want to switch the action type over to Python (i.e. QgsAction.GenericPython type) and craft something similar to this:

from PyQt4.QtCore import QUrl
from PyQt4.QtGui import QDesktopServices
email = '[% "EMAIL" %]'

# code to validate email

  • Thank you for an exemplary reply. It sort of works for me. Activating the action opens Outlook with a new mail window, but the email address is not filled in. Am I missing something to pass the address along?
    – user28233
    Apr 30 '14 at 19:59
  • In this example, [% "EMAIL" %] is the (sample) attribute field name whose value will be substituted. You will need to change that to whatever your field's name is.
    – dakcarto
    May 1 '14 at 5:14
  • Yes, I figured that out and did substitute EMAIL with my own attribute field name (in this case address). Still, the problem persist.
    – user28233
    May 1 '14 at 6:33
  • @dakcarto how do you clear the action properly? i've included the addAction in a function tied to a button click. my issue is that I keep adding the same action every time this button is clicked.
    – user25976
    Jan 21 '15 at 19:20
  • 1
    @user25976 You will need to listActions() and iterate through them until you find if there is already an action in there that you want to delete, then removeAction(index), or add it if it doesn't exist. See QgsAttributeAction class
    – dakcarto
    Jan 22 '15 at 0:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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