1

I'm attempting to use ScriptRunner to output a jpeg of a red rectangle using QGIS Composer to understand the QgsComposerShape. Everything works except QGIS crashes when the symbol is applied. The output image is correctly produced but QGIS crashes. If I remove the symbol portion of the code it draws the rectangle outline and doesn't crash. If I run the same code line by line in the QGIS Python console everything works without crashing.

I just don't understand why using the ScriptRunner plug-in results in a crash. Looking around GIS-SE I can't find this exact problem but there seems to be other issues with plug-ins and symbols. Is there some workaround for this issue?

Here is the ScriptRunner script. The layer isn't rendered but you need a map renderer in order to use the shape object:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *


def run_script(iface):
    """Print a simple map with a rectangle"""
    lyr = QgsVectorLayer("/Users/joellawhead/qgis_data/ms/Mississippi.shp", "Mississippi", "ogr") 
    reg = QgsMapLayerRegistry.instance()
    reg.addMapLayer(lyr)
    c = QgsComposition(iface.mapCanvas().mapRenderer())
    c.setPlotStyle(QgsComposition.Print)
    c.setPaperSize(215.9, 279.4)
    w, h = c.paperWidth(), c.paperHeight()
    x = 0
    y = ((h * .2) * -1) / 2 
    composerMap = QgsComposerMap(c,x,y,w,h)
    c.addItem(composerMap)
    dpi = c.printResolution()
    c.setPrintResolution(dpi)
    dpmm = dpi / 25.4
    width = int(dpmm * c.paperWidth())
    height = int(dpmm * c.paperHeight())

    red = {'color':'255,0,0,255','color_border':'0,0,255,255'}
    redsym = QgsFillSymbolV2.createSimple(red)
    shape1 = QgsComposerShape(10,50,10,25,c)
    shape1.setShapeType(1)
    shape1.setUseSymbolV2(True)
    shape1.setShapeStyleSymbol(redsym)
    c.addItem(shape1)

    # create output image and initialize it
    image = QImage(QSize(width, height), QImage.Format_ARGB32)
    image.setDotsPerMeterX(dpmm * 1000)
    image.setDotsPerMeterY(dpmm * 1000)
    image.fill(0)

    # render the composition
    imagePainter = QPainter(image)
    sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
    targetArea = QRectF(0, 0, width, height)
    c.render(imagePainter, targetArea, sourceArea)
    imagePainter.end()

    image.save("/Users/joellawhead/qgis_data/map.jpg", "jpg")
2

It's caused by a bug in QGIS 2.4 (fixed for 2.6). The crash is caused when python cleans up the redsym symbol. To workaround it, make sure redsym is stored somewhere where python won't automatically clean it (eg, store it in a global variable).

  • Outstanding - that totally explained it and fixed it. – GeospatialPython.com Oct 27 '14 at 2:54
2

I just tested the script and works fine also by ScriptRunner. The only thing that I had to change to the above code was initializing the QgsFillSymbolV2 class ;-):

redsym = QgsFillSymbolV2()
redsym.createSimple(red)

Anyway, we are going to get another great release on 31th :)

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.