PythonExperience

From wiki
Jump to navigationJump to search

Libraries to include

 from __main__ import vtk, qt, ctk, slicer

Class of the module's definition

 class LengthStat:
        def __init__(self, parent):
               parent.title = "Length Cleaning"
               parent.categories = [""]
               parent.contributors = ["Jean-Baptiste Berger"]
               self.parent = parent
  • This step will just define where the module will be stored (categories) in the list of all modules in Slicer and how it will be called (title).

Class of the module's qt widget

 class LengthStatWidget:
        def __init__(self, parent=None):
               if not parent:
                       self.parent = slicer. qMRMLWidget()
                       self.parent.setLayout(qt.QVBoxLayout())
                       self.parent.setMRMLScene(slicer.mrmlScene)
               else:
                       self.parent = parent
               self.distanceTable = list()
               self.outputNode = None
               if not parent:
                       self.setup()
                       self.vtkSelector.setMRMLScene(slicer.mrmlScene)
                       self.outputSelector.setMRMLScene(slicer.mrmlScene)
                       self.parent.show()
  • Here you just initialise the main left layout and set the scene to be the mrml scene of Slicer. The setup function that will be define below will be the one that define all module's widgets (on the left panel) in Slicer.

Setup function

 def setup(self):
               self.vtkSelectorFrame = qt.QFrame(self.parent)
               self.vtkSelectorFrame.setLayout(qt.QHBoxLayout())
               self.parent.layout().addWidget(self.vtkSelectorFrame)
 
               self.vtkSelectorLabel = qt.QLabel("Input Fiber Bundle: ", self.vtkSelectorFrame)
               self.vtkSelectorFrame.layout().addWidget(self.vtkSelectorLabel)
 	
               self.vtkSelector = slicer.qMRMLNodeComboBox(self.vtkSelectorFrame)
               self.vtkSelector.nodeTypes = ("vtkMRMLFiberBundleNode","vtkMRMLFiberBundleNode")
               self.vtkSelector.selectNodeUponCreation = False
               self.vtkSelector.addEnabled = False
               self.vtkSelector.removeEnabled = False
               self.vtkSelector.noneEnabled = True
               self.vtkSelector.setMRMLScene(slicer.mrmlScene)
               self.vtkSelector.setToolTip("Select the Fiber Bundle to read")
               self.vtkSelectorFrame.layout().addWidget(self.vtkSelector)
 		
               self.outputSelectorFrame = qt.QFrame(self.parent)
               self.outputSelectorFrame.setLayout(qt.QHBoxLayout())
               self.parent.layout().addWidget(self.outputSelectorFrame)
 		
               self.outputSelectorLabel = qt.QLabel("Output Fiber Bundle: ", self.outputSelectorFrame)
               self.outputSelectorFrame.layout().addWidget(self.outputSelectorLabel)
 		
               self.outputSelector = slicer.qMRMLNodeComboBox(self.outputSelectorFrame)
               self.outputSelector.nodeTypes = ("vtkMRMLFiberBundleNode","vtkMRMLFiberBundleNode")
               self.outputSelector.selectNodeUponCreation = False
               self.outputSelector.addEnabled = True
               self.outputSelector.removeEnabled = True
               self.outputSelector.noneEnabled = True
               self.outputSelector.setMRMLScene(slicer.mrmlScene)
               self.outputSelector.setToolTip("Select the Fiber Bundle to write on")
               self.outputSelectorFrame.layout().addWidget(self.outputSelector)
 		
               self.thresholdFrame = qt.QFrame(self.parent)
               self.thresholdFrame.setLayout(qt.QHBoxLayout())
               self.parent.layout().addWidget(self.thresholdFrame)
 		
               self.thresholdMinLabel = qt.QLabel("Min: ",self.thresholdFrame)
               self.thresholdFrame.layout().addWidget(self.thresholdMinLabel)
 		
               self.thresholdMin = qt.QSpinBox(self.thresholdFrame)
               self.thresholdMin.setSingleStep(1)
               self.thresholdMin.setRange(0,1000)
               self.thresholdMin.setValue(0)
               self.thresholdMin.enabled = False
               self.thresholdFrame.layout().addWidget(self.thresholdMin)
 		
               self.thresholdMaxLabel = qt.QLabel("Max: ",self.thresholdFrame)
               self.thresholdFrame.layout().addWidget(self.thresholdMaxLabel)
 		
               self.thresholdMax = qt.QSpinBox(self.thresholdFrame)
               self.thresholdMax.setSingleStep(1)
               self.thresholdMax.setRange(0,1000)
               self.thresholdMax.setValue(1)
               self.thresholdMax.enabled = False
               self.thresholdFrame.layout().addWidget(self.thresholdMax)
 		
               self.calculateLengthButton = qt.QPushButton("Calculate Length")
               self.calculateLengthButton.enabled = False
               self.parent.layout().addWidget(self.calculateLengthButton)
 		
               self.applyThresholdButton = qt.QPushButton("Apply Threshold")
               self.applyThresholdButton.enabled = False
               self.parent.layout().addWidget(self.applyThresholdButton)
 		
               self.parent.layout().addStretch(1)
 		
               self.calculateLengthButton.connect('clicked()', self.onCalculateLength)
               self.applyThresholdButton.connect('clicked()',self.onApplyThreshold)
               self.vtkSelector.connect('nodeActivated(vtkMRMLNode*)',self.onVtkSelect)
               self.outputSelector.connect('nodeActivated(vtkMRMLNode*)',self.onOutputSelect)
  • Basically all widgets are created using the qt namespace (previously added on the first line of the file) and calling the constructor of each class as usual. Each function associated are those listed in the qt documention. Sometimes there are some differences though. To see those differences you can use the python interactor of Slicer (view->python interactor) and type "help(vtk.vtkPolyData)" for instance. However, sometimes the documentation is not available.
  • Each time you want to use a new layout, just create a new QFrame and set a empty layout :
               self.vtkSelectorFrame = qt.QFrame(self.parent)
               self.vtkSelectorFrame.setLayout(qt.QHBoxLayout())
  • Then use the layout to add widget :
               self.vtkSelectorFrame.layout().addWidget(self.vtkSelector)
  • When your done with this frame just add it to the main layout :
               self.parent.layout().addWidget(self.vtkSelectorFrame)

Adding your module to Slicer

  • To add your script to the list of module in Slicer4 simply copy and past the .py file in /lib/Slicer4.1/qt-scripted-module in the Slicer build directory