I am developing a plugin for QGIS in Python, I need to connect the sselectionChanged signal emitted when a feature of the layer is selected, I could not find any examples on internet, here is what I have done so far:

QObject.connect(self.iface.mapCanvas(),SIGNAL("selectionChanged(QgsMapLayer)"), self.test)

In the logs of QGIS I get this warning:

Warning: Object::connect: (receiver name: 'MainWindow')

can you help me?

  • Please post all relevant code lines.
    – underdark
    Commented Apr 15, 2012 at 11:27

4 Answers 4


arpho, this new style PyQt connection works for me in PyQGIS Console (Mac OS X 10.7.3, with QGIS 1.7.4)...

def test(layer): print "selection changed"


I had to hit return at an empty prompt to see the printed "selection changed" messages. If I changed the selection multiple times, those would show up upon hitting return.

The only thing I can see that might cause that error is if your 'self' object hasn't had the iface reference assigned. Is this in your __init__() method of your plugin's class?:

self.iface = iface

Or, that iface hasn't been passed to your plugin's class. Check your __ini__.py file for your plugin to make sure it's being passed as an argument to your plugin's class in the def classFactory() method.


def classFactory(iface):
    from my_plugin import MyPlugin
    return MyPlugin(iface)

Hi thanks for your answer; I did what you said in the python console of qgis and it works; I tried to make it work on my plugin. this is an extract of my code:

def __init__(self, iface):
    # Save reference to the QGIS interface
    self.iface = iface

def selectedChanged(self,t):

def run(self):

when I launch the plugin I get this error

TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'

why my function is a NoneType?> is not the first time I connect a signal to a method, I do not understand the problem

  • Your slot needs to be just a callable (i.e. self.selectedChanged instead of self.selectedChanged("selected"), note my example ). If you want to pass arguments (not necessary here) use lambda or the partial function module (examples online). The selectionChanged signal passes the QgsMapLayer that had a selection change. So, your slot should look like selectedChanged(self, layer). If you want to get what's changed, in your slot test for layer type and get its selected features.
    – dakcarto
    Commented Apr 20, 2012 at 2:09

You are just missing an asterisk (*) there. It's SIGNAL("selectionChanged(QgsMapLayer *)") (notice the asterisk * after QgsMapLayer)

In C++ the asterisk refers to a pointer, and this is what the signal expects, compare http://qgis.org/api/2.4/classQgsMapCanvas.html#signals

  • I think you missed that this question is about Python, while your answer is about C++ …
    – TheEagle
    Commented Aug 12, 2021 at 21:10

You can connect the selectionChanged signal emitted when a feature of the layer (in this case defined as class property and named my_layer) is selected like this:

QObject.connect(self.my_layer, SIGNAL("selectionChanged(const QgsFeatureIds&, const QgsFeatureIds&, const bool)"), self.test)

In class you also have to define associated method which has the same number of arguments (in this case 3):

def test(self, fselected, fdeselected, p):

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.