class SegmentStatisticsWidget(ScriptedLoadableModuleWidget): """Uses ScriptedLoadableModuleWidget base class, available at: https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py """ def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = SegmentStatisticsLogic() self.grayscaleNode = None self.labelNode = None self.parameterNode = None self.parameterNodeObserver = None # Instantiate and connect widgets ... # # Parameter set selector self.parameterNodeSelector = slicer.qMRMLNodeComboBox() self.parameterNodeSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"] self.parameterNodeSelector.addAttribute("vtkMRMLScriptedModuleNode", "ModuleName", "SegmentStatistics") self.parameterNodeSelector.selectNodeUponCreation = True self.parameterNodeSelector.addEnabled = True self.parameterNodeSelector.renameEnabled = True self.parameterNodeSelector.removeEnabled = True self.parameterNodeSelector.noneEnabled = False self.parameterNodeSelector.showHidden = True self.parameterNodeSelector.showChildNodeTypes = False self.parameterNodeSelector.baseName = "SegmentStatistics" self.parameterNodeSelector.setMRMLScene(slicer.mrmlScene) self.parameterNodeSelector.setToolTip("Pick parameter set") self.layout.addWidget(self.parameterNodeSelector) # Inputs inputsCollapsibleButton = ctk.ctkCollapsibleButton() inputsCollapsibleButton.text = "Inputs" self.layout.addWidget(inputsCollapsibleButton) inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton) # Segmentation selector self.segmentationSelector = slicer.qMRMLNodeComboBox() self.segmentationSelector.nodeTypes = ["vtkMRMLSegmentationNode"] self.segmentationSelector.addEnabled = False self.segmentationSelector.removeEnabled = True self.segmentationSelector.renameEnabled = True self.segmentationSelector.setMRMLScene(slicer.mrmlScene) self.segmentationSelector.setToolTip( "Pick the segmentation to compute statistics for") inputsFormLayout.addRow("Segmentation:", self.segmentationSelector) # Scalar volume selector self.scalarSelector = slicer.qMRMLNodeComboBox() self.scalarSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.scalarSelector.addEnabled = False self.scalarSelector.removeEnabled = True self.scalarSelector.renameEnabled = True self.scalarSelector.noneEnabled = True self.scalarSelector.showChildNodeTypes = False self.scalarSelector.setMRMLScene(slicer.mrmlScene) self.scalarSelector.setToolTip( "Select the scalar volume for intensity statistics calculations") inputsFormLayout.addRow("Scalar volume:", self.scalarSelector) # Output table selector outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) self.outputTableSelector = slicer.qMRMLNodeComboBox() self.outputTableSelector.noneDisplay = "Create new table" self.outputTableSelector.setMRMLScene(slicer.mrmlScene) self.outputTableSelector.nodeTypes = ["vtkMRMLTableNode"] self.outputTableSelector.addEnabled = True self.outputTableSelector.selectNodeUponCreation = True self.outputTableSelector.renameEnabled = True self.outputTableSelector.removeEnabled = True self.outputTableSelector.noneEnabled = True self.outputTableSelector.setToolTip( "Select the table where statistics will be saved into") self.outputTableSelector.setCurrentNode(None) outputFormLayout.addRow("Output table:", self.outputTableSelector) # Parameter set parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Advanced" parametersCollapsibleButton.collapsed = True self.layout.addWidget(parametersCollapsibleButton) self.parametersLayout = qt.QFormLayout(parametersCollapsibleButton) # Edit parameter set button to open SegmentStatisticsParameterEditorDialog # Note: we add the plugins' option widgets to the module widget instead of using the editor dialog #self.editParametersButton = qt.QPushButton("Edit Parameter Set") #self.editParametersButton.toolTip = "Editor Statistics Plugin Parameter Set." #self.parametersLayout.addRow(self.editParametersButton) #self.editParametersButton.connect('clicked()', self.onEditParameters) # add caclulator's option widgets self.addPluginOptionWidgets() # Apply Button self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Calculate Statistics." self.applyButton.enabled = False self.parent.layout().addWidget(self.applyButton) # Add vertical spacer self.parent.layout().addStretch(1) # connections self.applyButton.connect('clicked()', self.onApply) self.scalarSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.segmentationSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.outputTableSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.parameterNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.parameterNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onParameterSetSelected) self.parameterNodeSelector.setCurrentNode( self.logic.getParameterNode()) self.onNodeSelectionChanged() self.onParameterSetSelected() def enter(self): """Runs whenever the module is reopened """ if self.parameterNodeSelector.currentNode() is None: parameterNode = self.logic.getParameterNode() slicer.mrmlScene.AddNode(parameterNode) self.parameterNodeSelector.setCurrentNode(parameterNode) if self.segmentationSelector.currentNode() is None: segmentationNode = slicer.mrmlScene.GetFirstNodeByClass( "vtkMRMLSegmentationNode") self.segmentationSelector.setCurrentNode(segmentationNode) def cleanup(self): if self.parameterNode and self.parameterNodeObserver: self.parameterNode.RemoveObserver(self.parameterNodeObserver) def onNodeSelectionChanged(self): self.applyButton.enabled = ( self.segmentationSelector.currentNode() is not None and self.parameterNodeSelector.currentNode() is not None) if self.segmentationSelector.currentNode(): self.outputTableSelector.baseName = self.segmentationSelector.currentNode( ).GetName() + ' statistics' def onApply(self): """Calculate the label statistics """ if not self.outputTableSelector.currentNode(): newTable = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLTableNode") self.outputTableSelector.setCurrentNode(newTable) # Lock GUI self.applyButton.text = "Working..." self.applyButton.setEnabled(False) slicer.app.processEvents() # set up parameters for computation self.logic.getParameterNode().SetParameter( "Segmentation", self.segmentationSelector.currentNode().GetID()) if self.scalarSelector.currentNode(): self.logic.getParameterNode().SetParameter( "ScalarVolume", self.scalarSelector.currentNode().GetID()) else: self.logic.getParameterNode().UnsetParameter("ScalarVolume") self.logic.getParameterNode().SetParameter( "MeasurementsTable", self.outputTableSelector.currentNode().GetID()) # Compute statistics self.logic.computeStatistics() self.logic.exportToTable(self.outputTableSelector.currentNode()) # Unlock GUI self.applyButton.setEnabled(True) self.applyButton.text = "Apply" self.logic.showTable(self.outputTableSelector.currentNode()) def onEditParameters(self, pluginName=None): """Open dialog box to edit plugin's parameters""" if self.parameterNodeSelector.currentNode(): SegmentStatisticsParameterEditorDialog.editParameters( self.parameterNodeSelector.currentNode(), pluginName) def addPluginOptionWidgets(self): self.pluginEnabledCheckboxes = {} self.parametersLayout.addRow( qt.QLabel("Enabled segment statistics plugins:")) for plugin in self.logic.plugins: checkbox = qt.QCheckBox(plugin.name + " Statistics") checkbox.checked = True checkbox.connect('stateChanged(int)', self.updateParameterNodeFromGui) optionButton = qt.QPushButton("Options") from functools import partial optionButton.connect('clicked()', partial(self.onEditParameters, plugin.name)) editWidget = qt.QWidget() editWidget.setLayout(qt.QHBoxLayout()) editWidget.layout().margin = 0 editWidget.layout().addWidget(checkbox, 0) editWidget.layout().addStretch(1) editWidget.layout().addWidget(optionButton, 0) self.pluginEnabledCheckboxes[plugin.name] = checkbox self.parametersLayout.addRow(editWidget) # embed widgets for editing plugin' parameters #for plugin in self.logic.plugins: # pluginOptionsCollapsibleButton = ctk.ctkCollapsibleGroupBox() # pluginOptionsCollapsibleButton.setTitle( plugin.name ) # pluginOptionsFormLayout = qt.QFormLayout(pluginOptionsCollapsibleButton) # pluginOptionsFormLayout.addRow(plugin.optionsWidget) # self.parametersLayout.addRow(pluginOptionsCollapsibleButton) def onParameterSetSelected(self): if self.parameterNode and self.parameterNodeObserver: self.parameterNode.RemoveObserver(self.parameterNodeObserver) self.parameterNode = self.parameterNodeSelector.currentNode() if self.parameterNode: self.logic.setParameterNode(self.parameterNode) self.parameterNodeObserver = self.parameterNode.AddObserver( vtk.vtkCommand.ModifiedEvent, self.updateGuiFromParameterNode) self.updateGuiFromParameterNode() def updateGuiFromParameterNode(self, caller=None, event=None): if not self.parameterNode: return for plugin in self.logic.plugins: pluginName = plugin.__class__.__name__ parameter = pluginName + '.enabled' checkbox = self.pluginEnabledCheckboxes[plugin.name] value = self.parameterNode.GetParameter(parameter) == 'True' if checkbox.checked != value: previousState = checkbox.blockSignals(True) checkbox.checked = value checkbox.blockSignals(previousState) def updateParameterNodeFromGui(self): if not self.parameterNode: return for plugin in self.logic.plugins: pluginName = plugin.__class__.__name__ parameter = pluginName + '.enabled' checkbox = self.pluginEnabledCheckboxes[plugin.name] self.parameterNode.SetParameter(parameter, str(checkbox.checked))
class SegmentStatisticsWidget(ScriptedLoadableModuleWidget): """Uses ScriptedLoadableModuleWidget base class, available at: https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py """ def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = SegmentStatisticsLogic() self.grayscaleNode = None self.labelNode = None self.parameterNode = None self.parameterNodeObserver = None # Instantiate and connect widgets ... # # Parameter set selector self.parameterNodeSelector = slicer.qMRMLNodeComboBox() self.parameterNodeSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"] self.parameterNodeSelector.addAttribute( "vtkMRMLScriptedModuleNode", "ModuleName", "SegmentStatistics" ) self.parameterNodeSelector.selectNodeUponCreation = True self.parameterNodeSelector.addEnabled = True self.parameterNodeSelector.renameEnabled = True self.parameterNodeSelector.removeEnabled = True self.parameterNodeSelector.noneEnabled = False self.parameterNodeSelector.showHidden = True self.parameterNodeSelector.showChildNodeTypes = False self.parameterNodeSelector.baseName = "SegmentStatistics" self.parameterNodeSelector.setMRMLScene( slicer.mrmlScene ) self.parameterNodeSelector.setToolTip( "Pick parameter set" ) self.layout.addWidget(self.parameterNodeSelector) # Inputs inputsCollapsibleButton = ctk.ctkCollapsibleButton() inputsCollapsibleButton.text = "Inputs" self.layout.addWidget(inputsCollapsibleButton) inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton) # Segmentation selector self.segmentationSelector = slicer.qMRMLNodeComboBox() self.segmentationSelector.nodeTypes = ["vtkMRMLSegmentationNode"] self.segmentationSelector.addEnabled = False self.segmentationSelector.removeEnabled = True self.segmentationSelector.renameEnabled = True self.segmentationSelector.setMRMLScene( slicer.mrmlScene ) self.segmentationSelector.setToolTip( "Pick the segmentation to compute statistics for" ) inputsFormLayout.addRow("Segmentation:", self.segmentationSelector) # Scalar volume selector self.scalarSelector = slicer.qMRMLNodeComboBox() self.scalarSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.scalarSelector.addEnabled = False self.scalarSelector.removeEnabled = True self.scalarSelector.renameEnabled = True self.scalarSelector.noneEnabled = True self.scalarSelector.showChildNodeTypes = False self.scalarSelector.setMRMLScene( slicer.mrmlScene ) self.scalarSelector.setToolTip( "Select the scalar volume for intensity statistics calculations") inputsFormLayout.addRow("Scalar volume:", self.scalarSelector) # Output table selector outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) self.outputTableSelector = slicer.qMRMLNodeComboBox() self.outputTableSelector.noneDisplay = "Create new table" self.outputTableSelector.setMRMLScene(slicer.mrmlScene) self.outputTableSelector.nodeTypes = ["vtkMRMLTableNode"] self.outputTableSelector.addEnabled = True self.outputTableSelector.selectNodeUponCreation = True self.outputTableSelector.renameEnabled = True self.outputTableSelector.removeEnabled = True self.outputTableSelector.noneEnabled = True self.outputTableSelector.setToolTip("Select the table where statistics will be saved into") self.outputTableSelector.setCurrentNode(None) outputFormLayout.addRow("Output table:", self.outputTableSelector) # Parameter set parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Advanced" parametersCollapsibleButton.collapsed = True self.layout.addWidget(parametersCollapsibleButton) self.parametersLayout = qt.QFormLayout(parametersCollapsibleButton) # Edit parameter set button to open SegmentStatisticsParameterEditorDialog # Note: we add the plugins' option widgets to the module widget instead of using the editor dialog #self.editParametersButton = qt.QPushButton("Edit Parameter Set") #self.editParametersButton.toolTip = "Editor Statistics Plugin Parameter Set." #self.parametersLayout.addRow(self.editParametersButton) #self.editParametersButton.connect('clicked()', self.onEditParameters) # add caclulator's option widgets self.addPluginOptionWidgets() # Apply Button self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Calculate Statistics." self.applyButton.enabled = False self.parent.layout().addWidget(self.applyButton) # Add vertical spacer self.parent.layout().addStretch(1) # connections self.applyButton.connect('clicked()', self.onApply) self.scalarSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.segmentationSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.outputTableSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.parameterNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onNodeSelectionChanged) self.parameterNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onParameterSetSelected) self.parameterNodeSelector.setCurrentNode(self.logic.getParameterNode()) self.onNodeSelectionChanged() self.onParameterSetSelected() def enter(self): """Runs whenever the module is reopened """ if self.parameterNodeSelector.currentNode() is None: parameterNode = self.logic.getParameterNode() slicer.mrmlScene.AddNode(parameterNode) self.parameterNodeSelector.setCurrentNode(parameterNode) if self.segmentationSelector.currentNode() is None: segmentationNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLSegmentationNode") self.segmentationSelector.setCurrentNode(segmentationNode) def cleanup(self): if self.parameterNode and self.parameterNodeObserver: self.parameterNode.RemoveObserver(self.parameterNodeObserver) def onNodeSelectionChanged(self): self.applyButton.enabled = (self.segmentationSelector.currentNode() is not None and self.parameterNodeSelector.currentNode() is not None) if self.segmentationSelector.currentNode(): self.outputTableSelector.baseName = self.segmentationSelector.currentNode().GetName() + ' statistics' def onApply(self): """Calculate the label statistics """ if not self.outputTableSelector.currentNode(): newTable = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLTableNode") self.outputTableSelector.setCurrentNode(newTable) # Lock GUI self.applyButton.text = "Working..." self.applyButton.setEnabled(False) slicer.app.processEvents() # set up parameters for computation self.logic.getParameterNode().SetParameter("Segmentation", self.segmentationSelector.currentNode().GetID()) if self.scalarSelector.currentNode(): self.logic.getParameterNode().SetParameter("ScalarVolume", self.scalarSelector.currentNode().GetID()) else: self.logic.getParameterNode().UnsetParameter("ScalarVolume") self.logic.getParameterNode().SetParameter("MeasurementsTable", self.outputTableSelector.currentNode().GetID()) # Compute statistics self.logic.computeStatistics() self.logic.exportToTable(self.outputTableSelector.currentNode()) # Unlock GUI self.applyButton.setEnabled(True) self.applyButton.text = "Apply" self.logic.showTable(self.outputTableSelector.currentNode()) def onEditParameters(self, pluginName=None): """Open dialog box to edit plugin's parameters""" if self.parameterNodeSelector.currentNode(): SegmentStatisticsParameterEditorDialog.editParameters(self.parameterNodeSelector.currentNode(),pluginName) def addPluginOptionWidgets(self): self.pluginEnabledCheckboxes = {} self.parametersLayout.addRow(qt.QLabel("Enabled segment statistics plugins:")) for plugin in self.logic.plugins: checkbox = qt.QCheckBox(plugin.name+" Statistics") checkbox.checked = True checkbox.connect('stateChanged(int)', self.updateParameterNodeFromGui) optionButton = qt.QPushButton("Options") from functools import partial optionButton.connect('clicked()',partial(self.onEditParameters, plugin.name)) editWidget = qt.QWidget() editWidget.setLayout(qt.QHBoxLayout()) editWidget.layout().margin = 0 editWidget.layout().addWidget(checkbox, 0) editWidget.layout().addStretch(1) editWidget.layout().addWidget(optionButton, 0) self.pluginEnabledCheckboxes[plugin.name] = checkbox self.parametersLayout.addRow(editWidget) # embed widgets for editing plugin' parameters #for plugin in self.logic.plugins: # pluginOptionsCollapsibleButton = ctk.ctkCollapsibleGroupBox() # pluginOptionsCollapsibleButton.setTitle( plugin.name ) # pluginOptionsFormLayout = qt.QFormLayout(pluginOptionsCollapsibleButton) # pluginOptionsFormLayout.addRow(plugin.optionsWidget) # self.parametersLayout.addRow(pluginOptionsCollapsibleButton) def onParameterSetSelected(self): if self.parameterNode and self.parameterNodeObserver: self.parameterNode.RemoveObserver(self.parameterNodeObserver) self.parameterNode = self.parameterNodeSelector.currentNode() if self.parameterNode: self.logic.setParameterNode(self.parameterNode) self.parameterNodeObserver = self.parameterNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGuiFromParameterNode) self.updateGuiFromParameterNode() def updateGuiFromParameterNode(self, caller=None, event=None): if not self.parameterNode: return for plugin in self.logic.plugins: pluginName = plugin.__class__.__name__ parameter = pluginName+'.enabled' checkbox = self.pluginEnabledCheckboxes[plugin.name] value = self.parameterNode.GetParameter(parameter)=='True' if checkbox.checked!=value: previousState = checkbox.blockSignals(True) checkbox.checked = value checkbox.blockSignals(previousState) def updateParameterNodeFromGui(self): if not self.parameterNode: return for plugin in self.logic.plugins: pluginName = plugin.__class__.__name__ parameter = pluginName+'.enabled' checkbox = self.pluginEnabledCheckboxes[plugin.name] self.parameterNode.SetParameter(parameter, str(checkbox.checked))
class SegmentStatisticsParameterEditorDialog(qt.QDialog): """Dialog to edit parameters of segment statistics plugins. Most users will only need to call the static method editParameters(...) """ @staticmethod def editParameters(parameterNode, pluginName=None): """Executes a modal dialog to edit a segment statistics parameter node if a pluginName is specified, only options for this plugin are displayed" """ dialog = SegmentStatisticsParameterEditorDialog( parent=None, parameterNode=parameterNode, pluginName=pluginName) return dialog.exec_() def __init__(self, parent=None, parameterNode=None, pluginName=None): super(qt.QDialog, self).__init__(parent) self.title = "Edit Segment Statistics Parameters" self.parameterNode = parameterNode self.pluginName = pluginName self.logic = SegmentStatisticsLogic( ) # for access to plugins and editor widgets self.logic.setParameterNode(self.parameterNode) self.setup() def setParameterNode(self, parameterNode): """Set the parameter node the dialog will operate on""" if parameterNode == self.parameterNode: return self.parameterNode = parameterNode self.logic.setParameterNode(self.parameterNode) def setup(self): self.setLayout(qt.QVBoxLayout()) self.descriptionLabel = qt.QLabel( "Edit segment statistics plugin parameters:", 0) self.doneButton = qt.QPushButton("Done") self.doneButton.toolTip = "Finish editing." doneWidget = qt.QWidget(self) doneWidget.setLayout(qt.QHBoxLayout()) doneWidget.layout().addStretch(1) doneWidget.layout().addWidget(self.doneButton, 0) parametersScrollArea = qt.QScrollArea(self) self.parametersWidget = qt.QWidget(parametersScrollArea) self.parametersLayout = qt.QFormLayout(self.parametersWidget) self._addPluginOptionWidgets() parametersScrollArea.setWidget(self.parametersWidget) parametersScrollArea.widgetResizable = True parametersScrollArea.setVerticalScrollBarPolicy( qt.Qt.ScrollBarAsNeeded) parametersScrollArea.setHorizontalScrollBarPolicy( qt.Qt.ScrollBarAsNeeded) self.layout().addWidget(self.descriptionLabel, 0) self.layout().addWidget(parametersScrollArea, 1) self.layout().addWidget(doneWidget, 0) self.doneButton.connect('clicked()', lambda: self.done(1)) def _addPluginOptionWidgets(self): description = "Edit segment statistics plugin parameters:" if self.pluginName: description = "Edit " + self.pluginName + " plugin parameters:" self.descriptionLabel.text = description if self.pluginName: for plugin in self.logic.plugins: if plugin.name == self.pluginName: self.parametersLayout.addRow(plugin.optionsWidget) else: for plugin in self.logic.plugins: pluginOptionsCollapsibleButton = ctk.ctkCollapsibleGroupBox( self.parametersWidget) pluginOptionsCollapsibleButton.setTitle(plugin.name) pluginOptionsFormLayout = qt.QFormLayout( pluginOptionsCollapsibleButton) pluginOptionsFormLayout.addRow(plugin.optionsWidget) self.parametersLayout.addRow(pluginOptionsCollapsibleButton)
class SegmentStatisticsParameterEditorDialog(qt.QDialog): """Dialog to edit parameters of segment statistics plugins. Most users will only need to call the static method editParameters(...) """ @staticmethod def editParameters(parameterNode, pluginName=None): """Executes a modal dialog to edit a segment statistics parameter node if a pluginName is specified, only options for this plugin are displayed" """ dialog = SegmentStatisticsParameterEditorDialog(parent=None, parameterNode=parameterNode, pluginName=pluginName) return dialog.exec_() def __init__(self,parent=None, parameterNode=None, pluginName=None): super(qt.QDialog,self).__init__(parent) self.title = "Edit Segment Statistics Parameters" self.parameterNode = parameterNode self.pluginName = pluginName self.logic = SegmentStatisticsLogic() # for access to plugins and editor widgets self.logic.setParameterNode(self.parameterNode) self.setup() def setParameterNode(self, parameterNode): """Set the parameter node the dialog will operate on""" if parameterNode==self.parameterNode: return self.parameterNode = parameterNode self.logic.setParameterNode(self.parameterNode) def setup(self): self.setLayout(qt.QVBoxLayout()) self.descriptionLabel = qt.QLabel("Edit segment statistics plugin parameters:",0) self.doneButton = qt.QPushButton("Done") self.doneButton.toolTip = "Finish editing." doneWidget = qt.QWidget(self) doneWidget.setLayout(qt.QHBoxLayout()) doneWidget.layout().addStretch(1) doneWidget.layout().addWidget(self.doneButton, 0) parametersScrollArea = qt.QScrollArea(self) self.parametersWidget = qt.QWidget(parametersScrollArea) self.parametersLayout = qt.QFormLayout(self.parametersWidget) self._addPluginOptionWidgets() parametersScrollArea.setWidget(self.parametersWidget) parametersScrollArea.widgetResizable = True parametersScrollArea.setVerticalScrollBarPolicy(qt.Qt.ScrollBarAsNeeded ) parametersScrollArea.setHorizontalScrollBarPolicy(qt.Qt.ScrollBarAsNeeded) self.layout().addWidget(self.descriptionLabel,0) self.layout().addWidget(parametersScrollArea, 1) self.layout().addWidget(doneWidget, 0) self.doneButton.connect('clicked()', lambda: self.done(1)) def _addPluginOptionWidgets(self): description = "Edit segment statistics plugin parameters:" if self.pluginName: description = "Edit "+self.pluginName+" plugin parameters:" self.descriptionLabel.text = description if self.pluginName: for plugin in self.logic.plugins: if plugin.name==self.pluginName: self.parametersLayout.addRow(plugin.optionsWidget) else: for plugin in self.logic.plugins: pluginOptionsCollapsibleButton = ctk.ctkCollapsibleGroupBox(self.parametersWidget) pluginOptionsCollapsibleButton.setTitle( plugin.name ) pluginOptionsFormLayout = qt.QFormLayout(pluginOptionsCollapsibleButton) pluginOptionsFormLayout.addRow(plugin.optionsWidget) self.parametersLayout.addRow(pluginOptionsCollapsibleButton)