Developing Slicer modules in Visual Studio / Visual Studio Code?

There is no difference. Originally, we added SlicerPython, but then we realized then PyCharm only accept interpreter name if it starts with “python”. We kept “SlicerPython” for backward compatibility but probably we’ll remove it at some point.

Note that autocomplete, breakpoints, step-by-step debugging, stack walking, running local commands, inspecting and modifying variables, etc. all already works perfectly if you attach Python debugger to a running Slicer and put a breakpoint into the method that you are editing. So, all that we are trying to achieve here would just offer some additional convenience.

I agree with you debugger features are better than python config in VS Code…

If anyone want just to fix VS Code in Windows as we have been talking about can follow these steps:

1º - Open Slicer Python Interector and install pylint, rope and autopep8:
slicer.util.pip_install(“pylint rope autopep8”)

2º - Open Visual Studio Code settings.json (located in C:\Users\“user”\AppData\Roaming\Code\User)

3º - Items to add:

{
“python.pythonPath”: “C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\bin\SlicerPython.exe”,
“python.linting.pylintPath”: “C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\Lib\site-packages\pylint\”,
“python.formatting.autopep8Path”: “C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\Scripts\autopep8.exe”,
“python.autoComplete.extraPaths”: [
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\QtPlugins\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Slicer-4.11\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\Scripts\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\Lib\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\Lib\site-packages\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\lib\Python\Lib\site-packages\pylint\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\bin\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\bin\Python\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\bin\Lib\site-packages\”,
“C:\Users\“user”\AppData\Local\NA-MIC\Slicer 4.11.0-2019-12-02\bin\Lib\site-packages\vtkmodules\”,
],
“python.linting.enabled”: true,
“git.autofetch”: true
}

Thanks so much for your support…

1 Like

I’ve created a script that collects all the above paths from the current Slicer instance and updates Visual Studio Code settings file automatically:

import os
import json

# Make sure all required packages are installed
slicer.util.pip_install("pylint rope autopep8 jedi")

binPath = slicer.app.applicationDirPath()  # 'C:/Users/(username)/AppData/Local/NA-MIC/Slicer (version)/bin'
appPath = os.path.dirname(slicer.app.applicationDirPath())  # 'C:/Users/(username)/AppData/Local/NA-MIC/Slicer (version)'
pythonHomePath = os.getenv('PYTHONHOME')  # 'C:/Users/(username)/AppData/Local/NA-MIC/Slicer (version)/lib/Python'
vsCodeUserSettingsFilePath = os.path.join(os.getenv("APPDATA"),"Code/User/settings.json")

# Read VS code settings file
with open(vsCodeUserSettingsFilePath) as vsCodeUserSettingsFile:
    vsCodeUserSettings = json.load(vsCodeUserSettingsFile)

# Update settings

vsCodeUserSettings["python.pythonPath"] = os.path.normpath(os.path.join(binPath, "SlicerPython.exe"))

vsCodeUserSettings["python.linting.pylintPath"] = os.path.normpath(os.path.join(pythonHomePath, "Scripts/pylint.exe"))
vsCodeUserSettings["python.linting.enabled"] = True

vsCodeUserSettings["python.formatting.autopep8Path"] = os.path.normpath(os.path.join(pythonHomePath, "Scripts/autopep8.exe"))

vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(appPath))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(binPath))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(pythonHomePath))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(os.path.join(pythonHomePath, "Scripts")))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(os.path.join(pythonHomePath, "Lib")))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(os.path.join(pythonHomePath, "Lib/site-packages")))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(os.path.join(pythonHomePath, "Lib/site-packages/pylint")))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(os.path.join(binPath, "Lib/site-packages/vtkmodules")))
vsCodeUserSettings["python.autoComplete.extraPaths"].append(os.path.normpath(os.path.join(appPath, "lib/QtPlugins")))
# Remove duplicates
vsCodeUserSettings["python.autoComplete.extraPaths"] = list(set(vsCodeUserSettings["python.autoComplete.extraPaths"]))

# Write VS code settings file
with open(vsCodeUserSettingsFilePath, "w") as vsCodeUserSettingsFile:
    json.dump(vsCodeUserSettings, vsCodeUserSettingsFile, indent=4)

Unfortunately, it does not do much for me. For example, if I type:

import vtkSegmentationCore as sc
s = sc.vtkSegmentation()

then methods of object s do not show up. If anybody can make VTK, MRML, CTK, or Qt method name auto-complete work in VS Code then please let me know.

4 Likes

C++ Tips: Using the CMake Tool by Microsoft really helped as it also provides the option to add generated build files to intellisense automatically (also need to have the c++ extension by microsoft installed). I’ve also attached my tasks.json and launch.json that launches slicer with my loadable c++ extension by pressing F5.

I open vscode in the base directory of my extension
Make sure to change to your extensions name to launch correctly

launch.json

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(Linux) Launch Extension",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/build/SlicerWith<NAME OF EXTENSION>",
      "args": [
        "--attach-process"
      ],
      "preLaunchTask": "(Linux) build",
      "stopAtEntry": true,
      "cwd": "${workspaceFolder}",
      "launchCompleteCommand": "exec-run",
      "linux": {
        "MIMode": "gdb",
        "miDebuggerPath": "/usr/bin/gdb"
      },
      "symbolLoadInfo": {
        "loadAll": true,
        "exceptionList": ""
      },
      "environment": [],
      "externalConsole": true,
      "additionalSOLibSearchPath": "${workspaceFolder}/build/lib/Slicer-4.11/qt-loadable-modules;<PATH TO SLICER BUILD>/Slicer-build/lib/Slicer-4.11/qt-loadable-modules"
    }
  ]
}

tasks.json

{
  "tasks": [
    {
      "label": "(Linux) build",
      "type": "shell",
      "command": "cmake --build ${workspaceFolder}/build --config Debug --target all -- -j <NUMBER OF CORES> ../"
    }
  ],
  "version": "2.0.0"
}

Notes

  • Make sure to change all instances with angle brackets inside to match your computers settings.
  • I’m still trying to figure out how to debug cpp with vscode instead of having to use gdb. As of now, you will have to open gdb separately in a terminal after starting the above code (basically running your extension ./SlicerWith(Extension Name) --atach-process) to get your process id. Then in a new terminal:
gdb -p <process_id>
(gdb) # place breakpoints
(gdb) continue # to run

I have followed the conversation and have set up my settings.json as such:

“python.pythonPath”: “C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\bin\PythonSlicer.exe”,
“python.linting.pylintPath”: “C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Python\Scripts\pylint.exe”,
“python.formatting.autopep8Path”: “C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Python\Scripts\autopep8.exe”,
“python.autoComplete.extraPaths”: [
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\bin\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Python\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\QtPlugins\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Slicer-5.4\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Python\Scripts\”,
],
“python.linting.enabled”: true,
“git.autofetch”: true,
“python.analysis.extraPaths”: [
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\bin\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Python\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\QtPlugins\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Slicer-5.4\”,
“C:\Users\smoudour\AppData\Local\slicer.org\Slicer 5.4.0\lib\Python\Scripts\”
],
“editor.fontLigatures”: false

Problems are:

  1. it still doesn’t work. Do I need to instal slicer using conda for this to work?
  2. python.pythonPath, python.linting.pylinPath and some other keywords in vscode settings.json are labelled as “Unknown configuration setting”, so that’s why it probably does not work. Any help with this?