I've tried going through IRC to see if people can help me out with this, but the medium seems a little clumsy for making any answers clear, so I'm going to try this instead.
I would like to program a standalone application using PyQGIS the way I can already program standalone applications using ArcPy.
PyQGIS itself is straightforward. I have had no difficulty using running Python scripts within the QGIS console editor. However, in order to use the Python bindings in a standalone script, I am advised I must change the environment settings using a batch script (I'm using Windows Vista at home, so we're talking batch scripting for Windows). This has resulted in a mess on my end, as I don't really understand batch scripting, and I don't like the idea that I'm resetting an environment that needs to be a certain way for other applications I run.
I'm having difficulty understanding why the instructions for creating these settings are so unnecessarily complicated, and why they don't amount to one line of code saying "go to where the bindings are, make the libraries I want available for this program to use). Certainly ArcPy doesn't require people to mess around with the computer's environmental settings, so I'm having difficulty understanding why PyQGIS does. It seems to me people will simply give up rather than teach themselves Windows Batch Scripting Language.
Now, I notice that when I run a script in QGIS's console editor, it works. Granted, it also makes the rest of QGIS unusable after the script runs, so I have to restart QGIS again afterwards, but the script works exactly as I programmed it to work. But when I do so outside of the QGIS application, it does not. The issue does not appear to be that I have failed to import some Python package automatically imported by the QGIS application (qgis.core and qgis.utils) - I have those import statements in my standalone script, along with all the other package imports the script requires. This leads me to believe that the difference is that the QGIS application correctly sets external environment variables, but those variables are not set properly when I run it as a standalone script.
Additionally, when I run the script as a standalone script, it gets through all of the code without throwing an error; it simply does not do what the code commands. When I run the script in the console editor, it does it all correctly. When I run it as a standalone, it creates a window, then immediately destroys it, while throwing no errors. So the intepreter understands everything I'm asking the script to do - it just won't do it.
Here is the script:
from PyQt4 import *
from PyQt4 import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from qgis.utils import *
import Tkinter
from Tkinter import *
import sys
import os
qgishome = "c:/OSGeo4W/apps/qgis/"
app = QgsApplication([], True)
QgsApplication.setPrefixPath(qgishome, True)
QgsApplication.initQgis()
canvas = QgsMapCanvas()
canvas.setCanvasColor(Qt.yellow)
canvas.enableAntiAliasing(True)
canvas.show()
layer = QgsVectorLayer(r"c:/GIS Data/fed308/cpc.shp", "Ridings", "ogr")
reg = QgsMapLayerRegistry.instance()
reg.addMapLayer(layer)
canvas.setExtent(layer.extent())
canvas.setLayerSet([QgsMapCanvasLayer(layer)])
QgsApplication.exitQgis()
Please...is there some way I can run this script outside of QGIS and have it work as it does within QGIS (ideally without shutting things down at the very end)?
QGIS is a wonderful program, and PyQGIS seems as intuitive as ArcPy does and would be a real advantage for an open source software to have - but if people have to go through all the hoops I have gone through already, and still not have standalone application access to PyQGIS libraries the way they do have access to ArcPy, it seems to me PyQGIS won't be of much use to people. I hope I'm wrong and this is easier than it thus far has been. Does anyone have a solution?
Answer
You have to start the Qt event loop using:
app.exec_()
I would remove QgsApplication.exitQgis(). It should ideally be handled in a slot that is connected to lastWindowClosed() signal of the application.
No comments:
Post a Comment