2

I have simplified my original code. My code is very similar to Pyqgis' cookbook. I am simply loading one VALID layer to QgsMapCanvas and then displaying it. Everything is displayed corectly etc. Problem is, everytime I exit out of the QgsMapCanvas GUI, my code then shows a segmentation fault (core dumped) message. How can I prevent this from happening?

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


def main():
    # initiate canvas for debugging purposes
    # supply path to qgis install location
    QgsApplication.setPrefixPath('/usr', True)
    # create a reference to the QgsApplication, setting the
    # second argument to False disables the GUI
    app = QgsApplication([], True)
    # load providers
    app.initQgis()

    # create Qt mapCanvas object
    canvas = QgsMapCanvas()
    canvas.setCanvasColor(Qt.transparent)
    # enable this for smooth rendering
    canvas.enableAntiAliasing(True)

    # create vector layer object
    layer = QgsVectorLayer('BUAARE.shp', 'layer', 'ogr')

    if layer.isValid():
        QgsMapLayerRegistry.instance().addMapLayer(layer)
        canvas.setExtent(layer.extent())
        canvas.setLayerSet([QgsMapCanvasLayer(layer)])

    canvas.show()
    app.exec_()

    # exit qgis
    app.exitQgis()
main()
3

Something isn't being cleaned up from memory right...

If I have a main routine that creates a QgsApplication, works with a canvas, and then calls exitQgis, then I get a seg fault after calling it. Note that I don't do any layer stuff here, which simplifies things to:

def badmain():
    app = QgsApplication([],True)
    app.setPrefixPath("/usr", True)
    app.initQgis()
    canvas = QgsMapCanvas()
    canvas.show()
    app.exec_()
    app.exitQgis()
    print "exited"
badmain()
print "Ending"

It prints "exited" but not "Ending".

But if I create a QgsApplication object and pass it to a function, it doesn't seg fault:

def okmain(app):
    app.setPrefixPath("/usr", True)
    app.initQgis()
    canvas = QgsMapCanvas()
    canvas.show()
    app.exec_()
    print "exited"

app = QgsApplication([], True)
okmain(app)
app.exitQgis()
print "Ending"

I can even put the app.exitQgis() inside the function, as long as I don't create it in the function.

Weirdly, I can create an app in a function and pass it to another function:

def main():
    app = QgsApplication([], True)
    okmain(app) # as above
    app.exitQgis()
    print "Ending"

main()

and this works without seg faults. How much of okmain I need to pull into main to recreate the crash with badmain I don't yet know... But a quick test seems to indicate its to do with the scope of the canvas.

So I suspect that when your main exits something tries to clean up the canvas object because it hasn't noticed that it's gone out of scope, but then why does my last example work, since canvas is out of scope when okmain returns? This might be some terribly subtle bug somewhere, but hopefully this will give you something to work round it. Certainly if you take your code out of a main function and just have it with indent=0 as a script, it runs fine.

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.