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.