Skip to content

Instantly share code, notes, and snippets.

@maximlt
Forked from veuncent/RemoteDebuggingQgisVsCode.md
Last active December 21, 2020 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximlt/9178dca844ff70c73367d9111197faa8 to your computer and use it in GitHub Desktop.
Save maximlt/9178dca844ff70c73367d9111197faa8 to your computer and use it in GitHub Desktop.
Remote debug QGIS with VS Code
  1. Install ptvsd using the same Python interpreter Qgis uses. E.g. on Windows:
C:\OSGeo4W64\apps\Python37\python.exe -m pip install ptvsd==4.3.2 

And on Linux:

pip3 install --user ptvsd
  1. Add a debug configuration to launch.json to VS Code and select the same interpreter as the one used by QGIS:
{
    "name": "Python: Remote Attach",
    "type": "python",
    "request": "attach",
    "port": 5678,
    "host": "localhost",
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "${workspaceFolder}"
        }
    ]
}
  1. Add code that attaches the debugger when your plugin launches:
import sys
import traceback
from qgis.core import QgsMessageLog, Qgis


MESSAGE_CATEGORY = 'Messages'


def enable_remote_debugging():
    try:
        import ptvsd
        if ptvsd.is_attached():
            QgsMessageLog.logMessage("Remote Debug for Visual Studio is already active", MESSAGE_CATEGORY, Qgis.Info)
            return
        ptvsd.enable_attach(address=('localhost', 5678))
        QgsMessageLog.logMessage("Attached remote Debug for Visual Studio", MESSAGE_CATEGORY, Qgis.Info)
    except Exception as e:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        format_exception = traceback.format_exception(exc_type, exc_value, exc_traceback)
        QgsMessageLog.logMessage(str(e), MESSAGE_CATEGORY, Qgis.Critical)        
        QgsMessageLog.logMessage(repr(format_exception[0]), MESSAGE_CATEGORY, Qgis.Critical)
        QgsMessageLog.logMessage(repr(format_exception[1]), MESSAGE_CATEGORY, Qgis.Critical)
        QgsMessageLog.logMessage(repr(format_exception[2]), MESSAGE_CATEGORY, Qgis.Critical)
 
 class MyQgisPlugin:
  def __init__(self, iface):
    enable_remote_debugging()
    # ... the rest of your plugin code
  1. Reload the plugin by closing and opening QGIS or by using the plugin "Plugin Reloader". The plugin code is now ready to be attached.

  2. In VS Code start debugging using the Python: Remote Attach configuration defined above

  3. Debugging tasks / multithreading In order to line-by-line debug code started in another thread, e.g. when running a QTask, add ptvsd.debug_this_thread() after the thread split. E.g. in the run() function of your task (here from a function):

def run(task):
   import ptvsd
   ptvsd.debug_this_thread()
   ...

Processing algorithms are run in their own thread, this method can be used in that case:

def processAlgorithm(self, parameters, context, feedback):
  import ptvsd
  ptvsd.debug_this_thread()
  ...
  1. Set breakpoints in VS Code and use your plugin to hit these breakpoints

Acknowledgement

This gist is based on this gist by veucent which I have slightlty adapted for Linux and added some details. It was originally based on the one written by AsgerPeterson (instead of installing a third-party Qgis plugin for attaching the debugger, veuncent added the code in point 3.)

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