Just a conceptual question... when writing a plugin using Plugin Builder 1.8.3, where does the script get connected to the application instance objects?

As an example (taken from eventlayerplugin.py):

class EventLayerPlugin:
    def __init__(self,  iface):
    self.mIface = iface

def run(self):
    dialog = EventLayerDialog( self.mIface )
    if dialog.exec_() == QDialog.Accepted:
        lineLayer = QgsMapLayerRegistry.instance().mapLayers()[dialog.lineLayer()]
        eventLayer = QgsMapLayerRegistry.instance().mapLayers()[dialog.eventLayer()]

where does iface and QgsMapLayerRegistry get assigned to the actual objects in the running instance of QGIS? From my beginner's perspective they seem to 'magically' refer to those objects already existing in the running instance, yet nowhere do I see them assigned to represent the instance objects. I.e. where in the plugin script are the QGIS objects made known to the script?

Clear as mud? If so, let me know and I'll try to figure out a better way to phrase this.

1 Answer 1


QgisAppInterface (aka 'iface') is assigned via the embedded Python interpreter instantiated by the app on launch, and is then subsequently passed on to Python plugins and the console via the 'qgis.utils' module.

Specifically, when a plugin is loaded and started, it's class factory (in __init__.py) is passed the object reference (pointer) to iface, as a convenience, since it is generally immediately needed by the plugin's initGUI() method to load actions/menus/icons into the GUI for users to access the plugin. If needed, it can then again be passed into the plugin's main class, as, I believe, is the case with Plugin Builder's generated class.

The magical references to running QGIS-internal instances come from the sip bindings (PyQGIS) that allow access to the underlying QGIS C++ API. Those bindings are exposed to Python by importing one of QGIS's modules into your plugins/scripts from within the running app, or externally with some setup that involves launching an app instance, e.g.:

from qgis.core import QgsMapLayerRegistry
print QgsMapLayerRegistry.instance().mapLayers()

If running commands in the console, you can forgo the imports for qgis.core as it is already imported (via from qgis.core import *), so this works same as above:

print QgsMapLayerRegistry.instance().mapLayers()

The master branch has a new Python console with some API code completion and tools to help you. You will have to install a nightly binary or compile it yourself to check that out.

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.