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()
1 Answer 1
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.