5

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.

5

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.

  • Thanks a lot! This allows to skip the batch file when executed from the OSGeo4W shell. But I can’t get this to work from a different shell (e.g. default windows cmd, or powershell). Is this expected? Should anything else be specified in this “header” so that one could simply execute from a powershell . "C:\Program Files\QGIS 2.18\bin\python.exe" getScreenshot.py. Currently it returns ImportError: No module named site – sc28 Nov 6 '17 at 18:35
  • 2
    @sc28 I've updated my answer to provide some more info on your new error. – Ali Nov 6 '17 at 20:06
  • @Ali, hi! Would you mind updating it for Python 3 and QGIS 3.0? I have done the following: import os, sys # Append QGIS Python library to python search path sys.path.append(r'C:\OSGeo4W64\apps\qgis\python') # Append location of DLLs to current system PATH envrionment variable os.environ['PATH'] += r";C:\OSGeo4W64\apps\qgis\bin;" # Examine new PATH environment variable print(os.environ['PATH']) # Try the import from qgis.core import * print('Done!') (1/2) – veen Mar 19 '18 at 17:50
  • (2/2)...which returns the following error: Traceback (most recent call last): File "<ipython-input-1-49209010db2e>", line 13, in <module> from qgis.core import * File "C:\OSGeo4W64\apps\qgis\python\qgis\__init__.py", line 72, in <module> from qgis.core import QgsFeature, QgsGeometry File "C:\OSGeo4W64\apps\qgis\python\qgis\core\__init__.py", line 34, in <module> from qgis._core import * ImportError: DLL load failed. – veen Mar 19 '18 at 17:51
  • @veen My suspicion is that you're running the script in a 32bit Python version but have 64bit QGIS version (or vice versa). The architectures need to match. – Ali Apr 26 '18 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.