- 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
- 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}"
}
]
}
- 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
-
Reload the plugin by closing and opening QGIS or by using the plugin "Plugin Reloader". The plugin code is now ready to be attached.
-
In VS Code start debugging using the Python: Remote Attach configuration defined above
-
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 therun()
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()
...
- Set breakpoints in VS Code and use your plugin to hit these breakpoints
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.)