带有 QGis 的 Python 脚本 - Python.exe 停止工作

标签 python python-2.7 pyqt pyqt4 qgis

我购买了 this book called Building Mapping Applications with QGIS我正在尝试完成其中一项练习。我尝试运行一个使 python 崩溃的脚本,生成错误消息“python.exe 已停止工作”。

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

我对使用 QGIS 的 Python 了解不多,所以我不太确定是什么导致 python 崩溃。我确信所有模块都正确导入,因为如果我定义我的路径,然后使用 OSGeo4W Shell 在脚本中导入模块,则不会出现错误消息。

我的路径是这样定义的:

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

鉴于所有这些,我认为脚本中一定有问题。但是,当我使用 http://pep8online.com/ 检查脚本时没有我可以修复的错误会导致 python 不崩溃。

请注意,我已经试过了> 没有成功。

最佳答案

我有幸与这本书的作者取得联系,所以我将在这里分享他的回应:

I suspect I may know what the problem is...after looking at this reader's problems in more depth, I've discovered that something has changed in newer versions of QGIS, and the example code no longer works as it is written. In technical terms, it seems that you now need to instantiate the QApplication object before making the call to QgsApplication.initQgis() -- the example program in the book instantiates the QApplication object after calling QgsApplication.initQgis(), which causes the program to crash. To fix this, change the main() function to look like the following:

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

As you can see, I've moved the "app = QApplication(sys.argv)" line to the top.

重要提示:确保在 viewer = MapViewer("C:/folder/shapefile. shp") - 使用反斜杠将导致一条错误消息,指出 shapefile 无效。

我还认为值得一提的是,上述修复(对问题的评论)都不是必需的。因此,如果路径定义如下,脚本将起作用:

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

然后,整个脚本如下所示:

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

使用以下命令在 OSGEO4W Shell 中执行它:

python "C:\script.py"

最后,请注意,在撰写本文时,脚本可以正常运行并启动显示引用的 shapefile 的查看器,但会在 shell 中返回一些似乎没有问题的错误:

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

非常感谢作者 Erik Westra 为我提供了这个解决方案。

关于带有 QGis 的 Python 脚本 - Python.exe 停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37957100/

相关文章:

python - 不和谐.错误.禁止 : 403 FORBIDDEN (error code: 50013): Missing Permissions

python - 停止递归生成器和排列

python - Jupyter 笔记本中的 Imagegrid

python - 提取数据框中第一项的关键错误

python - 根据命名约定,使用 Python 在 Windows 中删除文件

python - 在 PyQt 中刷新 QTextEdit

Python 基类可以是没有 __mro_entries__ 的对象

python-2.7 - 计算键字典中元组列表的部分数量

python - QProxyStyle 与 QStyleSheet

python - PyQt 和 QtreeView : How get the path from the selected file