Thursday 18 April 2019

pyqgis - Executing a standalone QGIS python script on Windows 10


In Windows 10, I currently have two working scripts (.BAT and .PY) which are used to generate PDFs from QGIS based on the solution here.


My goal is to be able to execute the python script without having to call the batch commands each time, but am having trouble getting this to work.


The createQGISmap.bat file contains:



REM Change OSGeo4W_ROOT to point to your install of QGIS.

SET OSGEO4W_ROOT=C:\Program Files\QGIS 2.18
SET QGISNAME=qgis
SET QGIS=%OSGEO4W_ROOT%\apps\%QGISNAME%
set QGIS_PREFIX_PATH=%QGIS%

CALL "%OSGEO4W_ROOT%\bin\o4w_env.bat"

REM Python Setup

set PATH=%OSGEO4W_ROOT%\bin;%QGIS%\bin;%PATH%
SET PYTHONHOME=%OSGEO4W_ROOT%\apps\Python27
set PYTHONPATH=%QGIS%\python;%PYTHONPATH%

ECHO OSGeo path is: %OSGEO4W_ROOT%
ECHO Getting QGIS libs from: %QGIS%
ECHO Python loaded from: %PYTHONHOME%

"C:\Program Files\QGIS 2.18\bin\python.exe" getScreenshot.py


And the beginning of the getScreenshot.py script:


from qgis.core import *  
import sys
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtCore import QFileInfo, QObject
from PyQt4.QtXml import QDomDocument

gui_flag = True
app = QgsApplication(sys.argv, gui_flag)


# Make sure QGIS_PREFIX_PATH is set in your env if needed!
app.initQgis()

# project.qgs
project_path = 'C:/mydata/qgis/autoexport.qgs'

I tried manually specifying the environment variables in Windows (in C: - Properties - Advanced system settings - Environment variables...) as follows:


QGIS = C:\Program Files\QGIS 2.18\apps\qgis
QGIS_PREFIX_PATH = C:\Program Files\QGIS 2.18\apps\qgis
PATH = C:\Program Files\QGIS 2.18\bin

PATH = C:\Program Files\QGIS 2.18\apps\qgis\bin
PYTHONHOME = C:\Program Files\QGIS 2.18\apps\Python27
PYTHONPATH = C:\Program Files\QGIS 2.18\python

But when executing python getScreenshot.py from the OSGeo4W shell, I keep getting


from qgis.core import *
ImportError: No module named qgis.core

I tried following advice from How can I fix "ImportError: No module named qgis.core"? and here without luck. I should point out I have two installations of Python (the one bundled with QGIS and a Python 3 from Anaconda), so I am trying to run the script with the former installation.



Answer




I have been able to replicate your problem on a Windows 7 system using QGIS 2.14 LTR.


Similar to your batch file, the QGIS install includes a python-qgis batch file which you can use to run scripts with the environment pre-configured. As I've tested on 2.14 LTR my batch file is %OSGEO4W_ROOT%\bin\python-qgis-ltr.bat ( depending on your version your file may not have the ltr part: python-qgis.bat). You should find that calling:%OSGEO4W_ROOT%\bin\python-qgis-ltr getScreenshot.py from a command window will run successfully.


The following is a screenshot after opening a command window in the QGIS 2.14\bin directory, running python-gqis-ltr.bat, and then from qgis.core import *


enter image description here


In order to run without the batch file you could try manually setting the environment variables as you have previously, but check against the contents of python-gqis-ltr.bat or python-gqis.bat depending on your version. It's worth noting that when you open the OSGeo4W shell it clears your PATH environment variable - so you will have to reset that if you go this route.


Alternatively, you can skip batch files altogether by including a couple of lines at the top of your script:


import os, sys

# Append QGIS Python library to python search path
sys.path.append(r'C:\Program Files\QGIS 2.14\apps\qgis-ltr\python')


# Append location of DLLs to current system PATH envrionment variable
os.environ['PATH'] += r";C:\Program Files\QGIS 2.14\apps\qgis-ltr\bin;"

# Examine new PATH environment variable
print os.environ['PATH']

# Try the import
from qgis.core import *
print 'Done!'


This ensures the QGIS Python library and DLLs can be found. This will however fail if the DLLs and Python are not using the same architecture i.e. 32-bit versus 64-bit.




Update


The error you mention in your comment is happening due to the location of Python within the QGIS installation directories. A typical Python install has the standard libraries in the Lib directory, itself stored in same directory as the executable e.g. C:\Python27\python.exe and C:\Python27\Lib. When importing modules this Lib folder is found in the search path.


However, as QGIS stores the Python executable in the QGIS\bin directory and the libraries in QGIS\apps\Python27, the standard libraries are not found by default. QGIS sets all of it up through a series of batch files, which is why the script currently runs successfuly in the OSGeo4W shell.


You can use the PYTHONHOME environment variable to specify where these libraries are; this is what QGIS uses - and you have the line in your createQGISmap.bat file.


Since site is automatically imported when you load up Python you need to have this location known to the system beforehand. So, setting this manually should work but will change it for your system and therefore impact other python installations i.e. they will all point to the same PYTHONHOME directory.


If you don't want to change PYTHONHOME permanently, or resort to something convoluted, sticking with a batch file is probably the way to go.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...