1

Here's my sample code that shows the problem - apologies if this is a big load of code but this is as minimal as I can get it:

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

app = QgsApplication([], True)
app.setPrefixPath("/usr", True)
app.initQgis()

class OgrLayer(QgsVectorLayer):
    def __init__(self, path, name, connect_remove):
        QgsVectorLayer.__init__(self, path, name, 'ogr')
        if connect_remove:
            QgsMapLayerRegistry.instance().layerRemoved.connect(self.layerRemoved)
    def layerRemoved(self, id):
        print "removed ",id

layer1 = QgsVectorLayer(sys.argv[2],'layer1','ogr')
layer2 = OgrLayer(sys.argv[3],'layer2', sys.argv[1]=="break")

if not layer1.isValid():
    raise ValueError("layer 1 not valid")
if not layer2.isValid():
    raise ValueError("layer 2 not valid")

QgsMapLayerRegistry.instance().addMapLayer(layer1)
QgsMapLayerRegistry.instance().addMapLayer(layer2)

canvas = QgsMapCanvas()
canvas.setLayerSet([QgsMapCanvasLayer(layer1), QgsMapCanvasLayer(layer2)])
canvas.show()

app.exec_()

When run as:

python layertest.py ok shape1.shp shape2.shp

it runs, presents an empty canvas window (because I've not bothered to set the extent) and quits cleanly when I close the window.

When run as:

python layertest.py break shape1.shp shape2.shp

it runs as before, but on closing the window I get a segmentation violation. The only difference is the attachment of the layerRemoved signal to the map layer registry within my OgrLayer class.

If I define the OgrLayer class in a Qgis application python console, it all works and Qgis quits cleanly on exit. Its only when running from a standalone python script that this code segfaults on exit.

Is something not initialised properly? Is something in the QApplication exit code trying to access a layer that has been deleted from memory?

The real situation I have is in trying to use a plugin that defines layers in this way with connections - so any solution would ideally not involve "don't connect the signal" since that would mean editing that plugin (and probably breaking it).

I can disconnect the signal after creating the layer and that seems to work, but that's a bit ugly. I'd rather find out what the underlying problem is.

Obviously seg faults on exit aren't as much of a problem as seg faults in the middle of a program, but I'd like to know what the underlying problem is and fix it.

1

It looks like you forgot to match your call to app.initQgis() with a call to app.exitQgis(). Add that after the call to app.exec_() and the segfault disappears.

  • Doh! Maybe we need a context manager to handle the init and exit steps... – Spacedman Jul 16 '16 at 7:31

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.