Script Runner — a QGIS plugin for managing scripts

16.02.2012 17:57 ·  GIS  ·  qgis, plugins

Most QGIS users are probably aware of the Python Console, even if they rarely use it. It is a window (accessible from the “Plugins → Python Console” menu) where you can interactively enter commands and access QGIS API functions.

QGIS Python Console
QGIS Python Console

The Console is an extremely useful tool and comes to the rescue in many scenarios, from prototyping plugins to automating repetitive actions.

Obviously, typing commands every time you need to perform some task is inconvenient, so frequently executed code is transformed into scripts, and these scripts are then run from the Console. However, if the number of actively used scripts is large enough, using the console becomes a bit inconvenient. The Script Runner plugin by Gary Sherman was developed to solve this problem. The plugin is available from the official repository, has no dependencies, and can be found in the “Plugins” menu after installation.

The plugin’s interface is simple: a toolbar with large buttons, a list of scripts on the left, and four tabs — “Info”, “Source”, “Help” and “About” — on the right.

Script Runner plugin
Script Runner plugin

The “Add Script” and “Run script” buttons are self-explanatory: the first one adds a script to the list (the list is saved between sessions), the second one runs the selected script.

Clicking the “Script Info” button will populate the “Info” tab with docstrings, function and class names from the selected script, and the script code will be loaded into the “Source” tab in read-only mode.

I think the purpose of the last two buttons, “Reload Script” and “Remove Script” is clear from their names. The first reloads the script (useful for debugging or if you need to tweak the code and run the process again), and the second removes the script from the list (leaving the file on disk).

Script Runner has only one requirement for scripts: they must have an entry point. The entry point is simply a run_script function that takes only one argument, a reference to the qgis.utils.iface object. If such a function is not present in the code, the script will simply not be recognised and loaded by the plugin.

The script logic can be implemented either within the run_script function or in separate functions called from it. It is also possible to use an OOP approach. In this case, you need to create an instance of the class in run_script and call the necessary method(s).

Here is a simple example (the script creates an empty LineString memory layer):

from PyQt4.QtCore import *

def run_script( iface ):
    layer = QgsVectorLayer("LineString", "temporary_lines", "memory")
    provider = layer.dataProvider()
    provider.addAttributes([QgsField("id", QVariant.Int)])
    QgsMapLayerRegistry.instance().addMapLayer(layer)

A more complex example using a class:

from qgis.core import *

class Lister:
    def __init__( self, iface ):
        self.iface = iface

    def listFeatures( self ):
        layer = self.iface.mapCanvas().currentLayer()
        provider = layer.dataProvider()
        allAttrs = provider.attributeIndexes()
        provider.select(allAttrs)

        ft = QgsFeature()
        while provider.nextFeature(ft):
            geom = ft.geometry()
            print "Feature ID %d: " % ft.id(),

            if geom.type() == QGis.Point:
                print "Point: " + str(geom.asPoint())
            elif geom.type() == QGis.Line:
                print "Line: %d points" % len(geom.asPolyline())
            elif geom.type() == QGis.Polygon:
                tmp = geom.asPolygon()
                pNum = 0
                for r in tmp:
                    pNum += len(r)
                print "Polygon: %d rings with %d points" % (len(tmp), pNum)
            else:
                print "Unknown"

            attrs = ft.attributeMap()
            for k, v in attrs.iteritems():
                print "%d: %s" % (k, v.toString())

    def run_script(iface):
        lst = Lister(iface)
        lst.listFeatures()

For me, Script Runner has become a must-have tool, making it much easier to use the 20+ scripts I have.

⮜ Prev
Next ⮞