2016-06-22 3 views
1

Ich kaufte this book called Building Mapping Applications with QGIS und ich versuche, eine der Übungen durchzuarbeiten. Es gibt ein Skript, das ich ausführen möchte, das Python abstürzt und die Fehlermeldung "python.exe funktioniert nicht mehr" erzeugt.Python-Skript mit QGis - Python.exe gestoppt

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() 

Ich weiß nicht, eine ganze Menge über Python mit QGIS so bin ich nicht sicher, was Python zum Absturz verursacht. Ich bin sicher, dass alle Module korrekt importiert werden, da es keine Fehlermeldungen gibt, wenn ich meine Pfade definiere und dann die Module mit der OSGeo4W Shell in das Skript importiere. Diese

ist, wie meine Pfade definiert:

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

dies alles gegeben, ich glaube, es ist etwas falsch in dem Skript sein muss. Jedoch, wenn ich das Skript unter Verwendung http://pep8online.com/ überprüfe, gibt es keine Fehler, die ich beheben kann, die dazu führen, dass Python nicht abstürzt.

Beachten Sie, dass ich versucht habe, habe ich SET PATH=%QGIS_PREFIX%\bin;%PATH% anstelle von ohne Erfolg versucht.

Antwort

3

Ich hatte das Glück, in Kontakt treten mit dem Autor des Buches anrufen müssen, damit ich seine Antwort teilen hier:

ich weiß ich vermuten kann, was das Problem ist ... nach in mehr Tiefe auf der dies Leser Probleme suchen, habe ich entdeckt, dass etwas hat in neueren Versionen von QGIS geändert, und der Beispielcode nicht mehr funktioniert so, wie es geschrieben wird. In technischer Hinsicht scheint es, dass Sie jetzt das QApplication Objekt instanziiert müssen vor dem Aufruf von QgsApplication.initQgis machen() - das Beispielprogramm in dem Buch instanziiert das QApplication Objekt nach QgsApplication.initQgis() aufgerufen, die bewirkt, dass das Programm abstürzt. Um dieses Problem zu beheben, ändern Sie die main() Funktion wie folgt aussehen:

def main(): 
    """ Our main program. 
    """ 
    app = QApplication(sys.argv) 
    QgsApplication.setPrefixPath(os.environ['QGIS_PREFIX'],True) 
    QgsApplication.initQgis() 

    viewer = MapViewer("C:/folder/shapefile.shp") 
    viewer.show() 

    app.exec_() 

    QgsApplication.exitQgis() 

Wie Sie sehen können, habe ich die "app = QApplication (sys.argv)" bewegt Linie die Spitze.

Wichtiger Hinweis: Vergewissern Sie sich, dass vorwärts Schrägstriche in viewer = MapViewer("C:/folder/shapefile.shp") verwendet werden - einen Backslash in einer Fehlermeldung wird die besagt, dass die Shape-Datei ungültig ist.

Ich dachte auch, es wäre erwähnenswert, dass keine der oben genannten Korrekturen (Kommentare zu der Frage) notwendig waren. So funktioniert das Skript, wenn die Pfade sind wie folgt definiert:

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

Dann wird das gesamte Skript wie folgt aussieht:

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. 
    """ 
    app = QApplication(sys.argv) 
    QgsApplication.setPrefixPath(os.environ['QGIS_PREFIX'],True) 
    QgsApplication.initQgis() 

    viewer = MapViewer("C:/folder/shapefile.shp") 
    viewer.show() 

    app.exec_() 

    QgsApplication.exitQgis() 

############################################################################# 

if __name__ == "__main__": 
    main() 

ausführen es in der OSGeo4W Shell mit dem folgenden Befehl:

Schließlich, zum Zeitpunkt der Erstellung dieses Skripts, das Skript ordnungsgemäß funktioniert und startet einen Viewer zeigt die Shapefile verwiesen, aber re schaltet sie ein paar Fehler in der Schale, die nicht als problematisch erscheinen:

ERROR: Opening of authentication db FAILED 
ERROR: Unable to establish authentication database connection 
ERROR: Auth db could not be created and opened 
QSqlDatabasePrivate::database: unable to open database: "unable to open database file Error opening database" 
ERROR: Opening of authentication db FAILED 

Vielen Dank an den Autor Erik Westra mit dieser Lösung für die Bereitstellung von mir.

1

Eine Sache, die verdächtig scheint, ist, dass Sie ein GUI-Element sind zu erstellen, ohne ihm einen Elternteil zu geben - QgsMapCanvas() - und dann manuell show() es versuchen, bevor es zu einem Layout hinzufügen. Sie sollten niemals show() für Subwidgets aufrufen, und alle Subwidgets sollten an das Hauptwidget (oder eines seiner anderen Subwidgets) übergeben werden.

Außerdem sollten Sie persistente Verweise auf die Python-Objekte speichern; Andernfalls ist es möglich, dass das zugrundeliegende C++ - Objekt mit Garbage gesammelt wird und zum Absturz Ihres Programms führt. Dazu ordnen Sie Ihre Widgets und Layouts einem Attribut unter self

zu.

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

Sie sollten die Leinwand wie diese werden hinzufügen, sollten Sie nicht .show()

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

Nur als ein FYI habe ich dieses Skript nicht geschrieben, es ist eine direkte Kopie aus dem Buch, das funktionieren sollte, ohne irgendwelche Änderungen vorzunehmen. Es sieht so aus, als müssten mehrere Änderungen am Skript vorgenommen werden, um diese Probleme zu beheben. Ich habe einen Stich gemacht, aber ich komme nicht weiter. Wenn Sie andere Ideen für die Beratung haben, würde ich mich sehr freuen. Oder wenn Sie dafür bereit sind, würde ich gerne Ihre modifizierte Version des Skripts ausprobieren! – ge0m3try