Python Script with QGis - Python.exe Stopped Working
Question: I purchased [this book called Building Mapping Applications with
QGIS](https://www.packtpub.com/application-development/building-mapping-
applications-qgis) and I am trying to work through one of the exercises. There
is one script that I try to run that crashes python, generating the error
message "python.exe has stopped working".

    
    
    import sys
    import os
    from qgis.core import *
    from qgis.gui import *
    from PyQt4.QtGui import *
    from PyQt4.QtCore import Qt
    
    
    
    #############################################################################
    
    
    class MapViewer(QMainWindow):
        def __init__(self, shapefile):
            QMainWindow.__init__(self)
            self.setWindowTitle("Map Viewer")
    
            canvas = QgsMapCanvas()
            canvas.useImageToRender(False)
            canvas.setCanvasColor(Qt.white)
            canvas.show()
    
            layer = QgsVectorLayer(shapefile, "layer1", "ogr")
            if not layer.isValid():
                raise IOError("Invalid shapefile")
    
            QgsMapLayerRegistry.instance().addMapLayer(layer)
            canvas.setExtent(layer.extent())
            canvas.setLayerSet([QgsMapCanvasLayer(layer)])
    
            layout = QVBoxLayout()
            layout.addWidget(canvas)
    
            contents = QWidget()
            contents.setLayout(layout)
            self.setCentralWidget(contents)
    
    #############################################################################
    
    
    def main():
        """  Our main program.
        """
        QgsApplication.setPrefixPath(os.environ['QGIS_PREFIX'], True)
        QgsApplication.initQgis()
    
        app = QApplication(sys.argv)
    
        viewer = MapViewer("C:/folder/shapefile.shp")
        viewer.show()
    
        app.exec_()
    
        QgsApplication.exitQgis()
    
    #############################################################################
    
    if __name__ == "__main__":
        main()
    

I don't know a whole lot about Python with QGIS so I'm not too sure what is
causing python to crash. I am positive that all of the modules are importing
correctly because if I define my paths and then import the modules in the
script using the OSGeo4W Shell, there are no error messages.

This is how my paths are defined:

    
    
    SET OSGEO4W_ROOT=C:\OSGeo4W64
    SET QGIS_PREFIX=%OSGEO4W_ROOT%\apps\qgis
    SET PATH=%PATH%;%QGIS_PREFIX%\bin
    SET PYTHONPATH=%QGIS_PREFIX%\python;%PYTHONPATH%
    

Given all of this, I think there has to be something wrong in the script.
However, when I check the script using <http://pep8online.com/> there are no
errors that I can fix that will result in python not crashing.

Note that I have tried I have tried `SET PATH=%QGIS_PREFIX%\bin;%PATH%`
instead of `SET PATH=%PATH%;%QGIS_PREFIX%\bin` with no success.


Answer: One thing that seems suspect is that you're creating a gui element without
giving it a parent - `QgsMapCanvas()` \- and then trying to manually `show()`
it before adding it to a layout. You should never have to call `show()` on
subwidgets, and all subwidgets should be parented to the main widget (or one
of its other subwidgets).

Also, you should store persistent references to the python objects; otherwise,
it's possible the underlying C++ object with get garbage collected and cause
your program to crash. You do this by assigning your widgets and layouts to an
attribute on `self`

Ex.

    
    
    self.layout = QVBoxLayout(...
    self.layer = ...
    

You should be adding the canvas like this, you should not need to call
`.show()`

    
    
    self.canvas = QgsMapCanvas(self)
    layout.addWidget(self.canvas)
    

