1

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 Apr 15 '12 at 11:27
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"

qgis.utils.iface.mapCanvas().selectionChanged.connect(test)

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.

Example:

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

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
    self.tree=Tree()
    self.progressBar=ProgressBarWindow(True,True)
    self.progressBar.setMaximumOverall(4)
    self.ui_tree=MainWindowAlbero(iface)

def selectedChanged(self,t):
    self.ui_tree.etichetta.setText(t)

def run(self):
    self.iface.mapCanvas().selectionChanged.connect(self.selectedChanged("selected"))

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 Apr 20 '12 at 2:09
0

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

0

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

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

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.