Skip to content

Instantly share code, notes, and snippets.

Last active Jul 14, 2021
What would you like to do?
Launch 3D Slicer from web browser to view 3D image file
# This 3D Slicer module allows launching 3D Slicer from the web browser and load an image file, for example from NRRD format.
# It uses a custom URL, which launches 3D Slicer and contains the download URL as query parameter (with percent encoding).
# See discussion at
# Setup:
# - save this file as "" in an empty folder.
# - add the folder to additional module paths in Slicer
# To test, open a terminal and execute this command:
# start slicer://viewer/?
import os
import unittest
import logging
import vtk, qt, ctk, slicer
from slicer.ScriptedLoadableModule import *
from slicer.util import VTKObservationMixin
# LoadRemoteFile
class LoadRemoteFile(ScriptedLoadableModule):
"""Uses ScriptedLoadableModule base class, available at:
def __init__(self, parent):
ScriptedLoadableModule.__init__(self, parent)
self.parent.title = "Load Remote File"
self.parent.categories = ["Utilities"]
self.parent.dependencies = []
self.parent.contributors = ["ASH", "Andras Lasso (PerkLab)"]
self.parent.helpText = """
This module loads NRRD files from custom URLs such as:
See more information <a href="">here</a>.
self.parent.acknowledgementText = """
This file was originally developed by Andras Lasso, PerkLab and ASH.
# Initilize self.sampleDataLogic. At this point, Slicer modules are not initialized yet, so we cannot instantiate the logic yet.
self.sampleDataLogic = None"urlReceived(QString)", self.onURLReceived)
def reportProgress(self, message):
# Print progress in the console
print(f"Loading... {self.sampleDataLogic.downloadPercent}%")
# Abort download if cancel is clicked in progress bar
if self.progressWindow.wasCanceled:
raise Exception("download aborted")
# Update progress window
# Process events to allow screen to refresh
def onURLReceived(self, urlString):
"""Process DICOM view requests. Example:
""""URL received: {urlString}")
# Check if we understand this URL
url = qt.QUrl(urlString)
if url.authority().lower() != "viewer":
query = qt.QUrlQuery(url)
queryMap = {}
for key, value in query.queryItems(qt.QUrl.FullyDecoded):
queryMap[key] = qt.QUrl.fromPercentEncoding(value)
if not "download" in queryMap:
# Get the download link and node name from URL
downloadUrl = qt.QUrl(queryMap["download"])
nodeName, ext = os.path.splitext(os.path.basename(downloadUrl.path()))"Download URL detected - get the file from {downloadUrl} and load it now")
# Generate random filename to avoid reusing/overwriting older downloaded files that may have the same name
import uuid
filename = f"{nodeName}-{uuid.uuid4().hex}{ext}"
# Ensure sampleData logic is created
if not self.sampleDataLogic:
import SampleData
self.sampleDataLogic = SampleData.SampleDataLogic()
self.progressWindow = slicer.util.createProgressDialog()
self.sampleDataLogic.logMessage = self.reportProgress
loadedNodes = self.sampleDataLogic.downloadFromURL(nodeNames=nodeName, fileNames=filename, uris=downloadUrl.toString())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment