Skip to content

Instantly share code, notes, and snippets.

@thbaumann
Forked from NicolaiLolansen/notes.MD
Created March 10, 2021 07:25
Show Gist options
  • Save thbaumann/73c873d4c49d8c1add8dc97359cebabe to your computer and use it in GitHub Desktop.
Save thbaumann/73c873d4c49d8c1add8dc97359cebabe to your computer and use it in GitHub Desktop.
Debugging QGIS 3.x python plugins on Windows using VS Code

A windows version inspired by this lovely gist: https://gist.github.com/AsgerPetersen/9ea79ae4139f4977c31dd6ede2297f90

Debugging QGIS 3.x python plugins on Windows 10 using VS Code

Plugin

In QGIS install the plugin debugvs.

Python dependencies

The debugvs plugin needs the python module ptvsd to function. This module is not installed by default.

In principle you just pip install ptvsd in the python interpreter used by QGIS.

I am using the OSGEO installation of QGIS, that comes with both ltr and dev versions of QGIS. Installing the plugin is not as straight forward as it might seem, and there are multiple options available to you. I'll share what i did here, it involves changing the settings.json file in the .vscode folder.

Setting up VSCode

Before we set up the debugger configuration, we are going to setup the VScode python interpreter for the project. Firstly my file looks like this:

settings.json

{   
    // I like changing colors for my projects. QGIS projects are usually green. 
    "workbench.colorCustomizations": {
        "titleBar.activeBackground": "#006823",
        "editor.background": "#1c2c2a"
    },
    
    "python.linting.pylintEnabled": true,
    "python.jediEnabled": true,

    // Wait.. this isen't a python interpreter..
    "python.pythonPath": "C:/OSGeo4W64/bin/python-qgis.bat",

    // Some arguments to make pylint behave nicely with PyQt5 and qgis bindinds
    "python.linting.pylintArgs": [
        "--extension-pkg-whitelist=PyQt5,qgis,db_manager",
        "--disable=all",
        "--enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode"
    ],

    // Replicate the QGIS environment on the terminal
    // {{INSERT_YOUR_USER}} or any path really should be replaced with your own installation path
    "terminal.integrated.env.windows": {
        // Path
        "PATH": "C:\\Program Files\\Git\\cmd;C:\\Users\\{{INSERT_YOUR_USER}}\\AppData\\Local\\GitHubDesktop\\bin;C:\\OSGEO4~1\\apps\\qgis\\bin;C:\\OSGEO4~1\\apps\\Python37;C:\\OSGEO4~1\\apps\\Python37\\Scripts;C:\\OSGEO4~1\\apps\\qt5\\bin;C:\\OSGEO4~1\\apps\\Python27\\Scripts;C:\\OSGEO4~1\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\system32\\WBem;C:\\OSGEO4~1\\apps\\Python37\\lib\\site-packages\\pywin32_system32;C:\\OSGEO4~1\\apps\\Python37\\lib\\site-packages\\numpy\\.libs",
        // Python
        "PYTHONHOME": "C:\\OSGEO4~1\\apps\\Python37",
        "PYTHONPATH": "C:\\OSGEO4~1\\apps\\qgis\\python;%PYTHONPATH%",
        // GDAL
        "GDAL_DATA": "C:\\OSGEO4~1\\share\\gdal",
        "GDAL_DRIVER_PATH": "C:\\OSGEO4~1\\bin\\gdalplugins",
        "GDAL_FILENAME_IS_UTF8": "YES",
        // GeoTIFF
        "GEOTIFF_CSV": "C:\\OSGEO4~1\\share\\epsg_csv",
        // Qt
        "O4W_QT_BINARIES": "C:/OSGEO4~1/apps/Qt5/bin",
        "O4W_QT_DOC": "C:/OSGEO4~1/apps/Qt5/doc",
        "O4W_QT_HEADERS": "C:/OSGEO4~1/apps/Qt5/include",
        "O4W_QT_LIBRARIES": "C:/OSGEO4~1/apps/Qt5/lib",
        "O4W_QT_PLUGINS": "C:/OSGEO4~1/apps/Qt5/plugins",
        "O4W_QT_PREFIX": "C:/OSGEO4~1/apps/Qt5",
        "O4W_QT_TRANSLATIONS": "C:/OSGEO4~1/apps/Qt5/translations",
        "QT_PLUGIN_PATH": "C:\\OSGEO4~1\\apps\\qgis\\qtplugins;C:\\OSGEO4~1\\apps\\qt5\\plugins",
        // QGIS
        "QGIS_PREFIX_PATH": "C:/OSGEO4~1/apps/qgis",
        // Cache
        "VSI_CACHE": "TRUE",
        "VSI_CACHE_SIZE": "1000000"
    },
    "python.languageServer": "Jedi", // PyLancer just came out recently, but i havent tested it out with this configuration
}

The bread and butter of this configuration is "python.pythonPath": "C:/OSGeo4W64/bin/python-qgis.bat", which sets all the correct paths and bindings for us. I don't really know why it works to refer a .bat file as python interpreter, but apparently it's fine and fixes alot of linting issues.

The "terminal.integrated.env.windows": { configuration is basically the same idea, but i have copied alot of the contents from this file C:/OSGeo4W64/bin/python-qgis.bat. It makes the terminal in VScode aware of the QGIS python interpreter.

Now you can reload your VSCode window, and once the terminal starts up it will ask you to allow this terminal configuration to modify your terminal, press yes. After this happens you should now be able to get the exact same python interpreter that the OSGEO version of QGIS uses. If you use the ltr version, change all references to the ltr files.

Now you can pip install ptvsd inside your terminal. It's a good idea to verify the interpreter first by doing python to get an interactive session.

Launch.json

The default remote debugger configuration in VS Code looks like this

{
    "name": "Python: Remote Attach",
    "type": "python",
    "request": "attach",
    "port": 5678,
    "host": "localhost",
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "."
        }
    ]
},

I had to do two things to make plugin development work. I create a symlink between my Git folder and the plugin folder like this:

  • Open an elevated cmd.exe
  • Create a symlink mklink /D "C:\Users\---\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\your_plugin" "C:\Github\your_plugin_workspace\your_plugin"

Now you dont have to open VSCode inside the plugin folder ( you can if you want... )

Now change the pathMappings so the remote debugger knows where your files live

{
    "name": "Python: Remote Attach",
    "type": "python",
    "request": "attach",
    "port": 5678,
    "host": "localhost",
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}/your_plugin", // path to your plugin where you are developing
            "remoteRoot": "C:\\Users\\---\\AppData\\Roaming\\QGIS\\QGIS3\\profiles\\default\\python\\plugins\\your_plugin" // path to where the QGIS plugin folder lives 
        }
    ]
},

Now you should be ready to debug!

Debugging

  • In QGIS click Plugins -> Enable Debug for Visual Studio -> Enable Debug for Visual Studio
  • You should now see a message in the QGIS message bar saying something like DebugVS : Run the Debug in Visual Studio(Python:Attach)
  • In VS Code start debugging using the Python: Remote Attach configuration defined above.

Now you should be able to set breakpoints in VS Code.

Thanks to AsgerPetersen for his guide: https://gist.github.com/AsgerPetersen/9ea79ae4139f4977c31dd6ede2297f90

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment