def __init__(self, parent):
    vLayout = qt.QVBoxLayout(parent)
    hLayout = qt.QHBoxLayout()

    self.icon = qt.QLabel()
    self.icon.setPixmap(_dialogIcon(qt.QStyle.SP_MessageBoxQuestion))
    hLayout.addWidget(self.icon, 0)

    self.label = qt.QLabel()
    self.label.wordWrap = True
    hLayout.addWidget(self.label, 1)

    vLayout.addLayout(hLayout)

    self.moduleList = qt.QListWidget()
    self.moduleList.selectionMode = qt.QAbstractItemView.NoSelection
    vLayout.addWidget(self.moduleList)

    self.addToSearchPaths = qt.QCheckBox()
    vLayout.addWidget(self.addToSearchPaths)

    self.enableDeveloperMode = qt.QCheckBox()
    self.enableDeveloperMode.text = "Enable developer mode"
    self.enableDeveloperMode.toolTip = "Sets the 'Developer mode' application option to enabled. Enabling developer mode is recommended while developing scripted modules, as it makes the Reload and Testing section displayed in the module user interface."
    self.enableDeveloperMode.checked = True
    vLayout.addWidget(self.enableDeveloperMode)

    self.buttonBox = qt.QDialogButtonBox()
    self.buttonBox.setStandardButtons(qt.QDialogButtonBox.Yes |
                                      qt.QDialogButtonBox.No)
    vLayout.addWidget(self.buttonBox)
Exemple #2
0
    def __init__(self, parent, dicomDatabase=None, detailsPopup=None):
        if dicomDatabase:
            self.dicomDatabase = dicomDatabase
        else:
            self.dicomDatabase = slicer.dicomDatabase
        self.detailsPopup = detailsPopup
        self.recentSeries = []
        self.widget = qt.QWidget(parent)
        self.widget.name = 'recentActivityWidget'
        self.layout = qt.QVBoxLayout()
        self.widget.setLayout(self.layout)

        self.statusLabel = qt.QLabel(self.widget)
        self.layout.addWidget(self.statusLabel)
        self.statusLabel.text = 'No inserts in the past hour'

        self.scrollArea = qt.QScrollArea()
        self.layout.addWidget(self.scrollArea)
        self.listWidget = qt.QListWidget()
        self.listWidget.name = 'recentActivityListWidget'
        self.scrollArea.setWidget(self.listWidget)
        self.scrollArea.setWidgetResizable(True)
        self.listWidget.setProperty('SH_ItemView_ActivateItemOnSingleClick', 1)
        self.listWidget.connect('activated(QModelIndex)', self.onActivated)

        self.refreshButton = qt.QPushButton(self.widget)
        self.layout.addWidget(self.refreshButton)
        self.refreshButton.text = 'Refresh'
        self.refreshButton.connect('clicked()', self.update)

        self.tags = {}
        self.tags['seriesDescription'] = "0008,103e"
        self.tags['patientName'] = "0010,0010"
Exemple #3
0
    def __init__(self, parent):
        vLayout = qt.QVBoxLayout(parent)
        hLayout = qt.QHBoxLayout()

        self.icon = qt.QLabel()
        self.icon.setPixmap(_dialogIcon(qt.QStyle.SP_MessageBoxQuestion))
        hLayout.addWidget(self.icon, 0)

        self.label = qt.QLabel()
        self.label.wordWrap = True
        hLayout.addWidget(self.label, 1)

        vLayout.addLayout(hLayout)

        self.moduleList = qt.QListWidget()
        self.moduleList.selectionMode = qt.QAbstractItemView.NoSelection
        vLayout.addWidget(self.moduleList)

        self.addToSearchPaths = qt.QCheckBox()
        vLayout.addWidget(self.addToSearchPaths)

        self.buttonBox = qt.QDialogButtonBox()
        self.buttonBox.setStandardButtons(qt.QDialogButtonBox.Yes
                                          | qt.QDialogButtonBox.No)
        vLayout.addWidget(self.buttonBox)
    def __init__(self):
        '''
        Constructor
        '''
        """
        path=slicer.modules.usguidedprocedure.path
        modulePath=os.path.dirname(path)
        loadedDataGUIfile=os.path.join(modulePath,"USGuidedWizard/loadedData.ui")
        f = qt.QFile(loadedDataGUIfile)
        #f = qt.QFile('C:/Users/Usuario/devel/slicelets/USGuidedProcedure/USGuidedWizard/fiducials.ui')
        f.open(qt.QFile.ReadOnly)
        loader = qt.QUiLoader()
        self.loadedDataWidget = loader.load(f)
        f.close()
        """
        self.volumesFrame = qt.QFrame()
        self.volumesFrame.setLayout(qt.QHBoxLayout())
        self.volumesFrameLayout = self.volumesFrame.layout()
        self.listWidget = qt.QListWidget()

        self.volumesLabel = qt.QLabel("Volumes:")
        print("Constructor of VolumeRenderingViewer executed")
        #self.listWidget.show()
        self.currentItem = None

        self.volumeButtonsFrame = qt.QFrame()
        self.volumeButtonsFrame.setLayout(qt.QVBoxLayout())
        self.volumeButtonsLayout = self.volumeButtonsFrame.layout()

        self.exploreVolumeButton = qt.QPushButton("Explore")
        self.exploreVolumeButton.toolTip = "Show the selected volume"
        self.exploreVolumeButton.setEnabled(False)
        self.exploreVolumeButton.connect('clicked(bool)',
                                         self.onExploreVolumeClicked)

        self.hideVolumeButton = qt.QPushButton("Hide")
        self.hideVolumeButton.toolTip = "Hide the volume"
        self.hideVolumeButton.setEnabled(False)
        self.hideVolumeButton.connect('clicked(bool)',
                                      self.onHideVolumeClicked)

        self.resliceVolumeButton = qt.QPushButton("Reslice")
        self.resliceVolumeButton.toolTip = "Reslice the volume with a driver"
        self.resliceVolumeButton.setEnabled(False)
        self.resliceVolumeButton.connect('clicked(bool)',
                                         self.onResliceVolumeClicked)

        self.volumeButtonsLayout.addWidget(self.volumesLabel)
        self.volumeButtonsLayout.addWidget(self.exploreVolumeButton)
        self.volumeButtonsLayout.addWidget(self.hideVolumeButton)
        self.volumeButtonsLayout.addWidget(self.resliceVolumeButton)

        self.volumesFrameLayout.addWidget(self.listWidget)
        self.volumesFrameLayout.addWidget(self.volumeButtonsFrame)
    def setup(self):

        self.studyLabel = qt.QLabel(self.studyDescription)
        self.studyLabel.setAlignment(qt.Qt.AlignCenter)
        self.petLabel = qt.QLabel("PET Image Series")
        self.petLabel.setAlignment(qt.Qt.AlignCenter)
        self.ctLabel = qt.QLabel("CT Image Series")
        self.ctLabel.setAlignment(qt.Qt.AlignCenter)
        self.petList = qt.QListWidget()
        self.petList.addItems(self.petDescriptions)
        self.petList.setCurrentRow(self.petSelection)
        self.ctList = qt.QListWidget()
        self.ctList.addItems(self.ctDescriptions)
        self.ctList.setCurrentRow(self.ctSelection)
        self.button = qt.QPushButton("Ok")

        self.layout.addWidget(self.studyLabel, 0, 0, 1, 2)
        self.layout.addWidget(self.petLabel, 1, 0, 1, 1)
        self.layout.addWidget(self.ctLabel, 1, 1, 1, 1)
        self.layout.addWidget(self.petList, 2, 0, 1, 1)
        self.layout.addWidget(self.ctList, 2, 1, 1, 1)
        self.layout.addWidget(self.button, 3, 0, 1, 2)

        self.button.connect('clicked()', self.parent.close)
Exemple #6
0
  def setup(self):
    self.logic = NodeModifiedStatisticsLogic()

    ScriptedLoadableModuleWidget.setup(self)

    # Parameters
    parametersCollapsibleButton = ctk.ctkCollapsibleButton()
    parametersCollapsibleButton.text = "Parameters"
    self.layout.addWidget(parametersCollapsibleButton)
    parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

    self.inputSelector = slicer.qMRMLNodeComboBox()
    self.inputSelector.selectNodeUponCreation = True
    self.inputSelector.addEnabled = False
    self.inputSelector.removeEnabled = False
    self.inputSelector.noneEnabled = False
    self.inputSelector.showHidden = False
    self.inputSelector.showChildNodeTypes = False
    self.inputSelector.setMRMLScene( slicer.mrmlScene )
    parametersFormLayout.addRow("Input Node: ", self.inputSelector)

    self.showHiddenNodesCheckBox = qt.QCheckBox('')
    self.showHiddenNodesCheckBox.checked = False
    parametersFormLayout.addRow('Show Hidden Nodes: ', self.showHiddenNodesCheckBox) 
    
    self.computeStatisticsButton = qt.QPushButton("Compute Statistics")
    self.computeStatisticsButton.enabled = False
    self.computeStatisticsButton.checkable = True
    parametersFormLayout.addRow(self.computeStatisticsButton)

    # Statistics
    statisticsCollapsibleButton = ctk.ctkCollapsibleButton()
    statisticsCollapsibleButton.text = "Statistics"
    self.layout.addWidget(statisticsCollapsibleButton)
    statisticsFormLayout = qt.QFormLayout(statisticsCollapsibleButton)

    self.latestLineEdit = qt.QLineEdit('N/A')
    self.latestLineEdit.setReadOnly(True)
    statisticsFormLayout.addRow("Latest (ms): ", self.latestLineEdit)
    self.averageLineEdit = qt.QLineEdit('N/A')
    self.averageLineEdit.setReadOnly(True)
    self.fpsLineEdit = qt.QLineEdit('N/A')
    self.fpsLineEdit.setReadOnly(True)
    statisticsFormLayout.addRow("Average (updates per second): ", self.fpsLineEdit)
    statisticsFormLayout.addRow("Average (ms): ", self.averageLineEdit)
    self.sdLineEdit = qt.QLineEdit('N/A')
    self.sdLineEdit.setReadOnly(True)
    statisticsFormLayout.addRow("SD (ms): ", self.sdLineEdit)
    self.minLineEdit = qt.QLineEdit('N/A')
    self.minLineEdit.setReadOnly(True)
    statisticsFormLayout.addRow("Min (ms): ", self.minLineEdit)
    self.maxLineEdit = qt.QLineEdit('N/A')
    self.maxLineEdit.setReadOnly(True)
    statisticsFormLayout.addRow("Max (ms): ", self.maxLineEdit)

    self.resetStatisticsButton = qt.QPushButton("Reset Statistics")
    self.resetStatisticsButton.enabled = True
    statisticsFormLayout.addRow(self.resetStatisticsButton)

    self.showSamplesButton = qt.QPushButton("Show Latest Samples")
    self.showSamplesButton.enabled = True
    statisticsFormLayout.addRow(self.showSamplesButton)

    self.sampleList = qt.QListWidget()
    statisticsFormLayout.addRow(self.sampleList)

    # connections
    self.computeStatisticsButton.connect('clicked(bool)', self.onComputeStatisticsClicked)
    self.resetStatisticsButton.connect('clicked(bool)', self.onResetStatisticsClicked)
    self.showSamplesButton.connect('clicked(bool)', self.onShowSamplesClicked)
    self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    self.showHiddenNodesCheckBox.connect('stateChanged(int)', self.onShowHiddenNodesChecked)
        
    # Add vertical spacer
    self.layout.addStretch(1)

    # Refresh Apply button state
    self.onSelect()

    self.lineEdits = [self.latestLineEdit, self.fpsLineEdit, self.averageLineEdit, self.sdLineEdit, self.minLineEdit, self.maxLineEdit]
    def __init__(self):
        '''
        Constructor
        '''
        """
        path=slicer.modules.usguidedprocedure.path
        modulePath=os.path.dirname(path)
        loadedDataGUIfile=os.path.join(modulePath,"USGuidedWizard/loadedData.ui")
        f = qt.QFile(loadedDataGUIfile)
        #f = qt.QFile('C:/Users/Usuario/devel/slicelets/USGuidedProcedure/USGuidedWizard/fiducials.ui')
        f.open(qt.QFile.ReadOnly)
        loader = qt.QUiLoader()
        self.loadedDataWidget = loader.load(f)
        f.close()
        """
        self.volumesFrame = qt.QFrame()
        self.volumesFrame.setLayout(qt.QHBoxLayout())
        self.volumesFrameLayout = self.volumesFrame.layout()
        self.listWidget = qt.QListWidget()
        self.renderingLabel = qt.QLabel("Renderings:")

        print("Constructor of VolumeRenderingViewer executed")
        #self.listWidget.show()
        self.currentItem = None

        self.volumeButtonsFrame = qt.QFrame()
        self.volumeButtonsFrame.setLayout(qt.QVBoxLayout())
        self.volumeButtonsLayout = self.volumeButtonsFrame.layout()

        self.showVolumeRenderingButton = qt.QPushButton("Show")
        self.showVolumeRenderingButton.toolTip = "Show the volume rendering"
        self.showVolumeRenderingButton.setEnabled(False)
        self.showVolumeRenderingButton.connect(
            'clicked(bool)', self.onShowVolumeRenderingButtonClicked)

        self.hideVolumeRenderingButton = qt.QPushButton("Hide")
        self.hideVolumeRenderingButton.toolTip = "Hide the volume rendering"
        self.hideVolumeRenderingButton.setEnabled(False)
        self.hideVolumeRenderingButton.connect(
            'clicked(bool)', self.onHideVolumeRenderingButtonClicked)

        self.modifyVolumeRenderingButton = qt.QPushButton("Modify")
        self.modifyVolumeRenderingButton.toolTip = "Modify the properties of the volume rendering"
        self.modifyVolumeRenderingButton.setEnabled(False)
        self.modifyVolumeRenderingButton.connect(
            'clicked(bool)', self.onModifyVolumeRenderingButtonClicked)

        self.volumeButtonsLayout.addWidget(self.renderingLabel)
        self.volumeButtonsLayout.addWidget(self.showVolumeRenderingButton)
        self.volumeButtonsLayout.addWidget(self.hideVolumeRenderingButton)
        self.volumeButtonsLayout.addWidget(self.modifyVolumeRenderingButton)

        self.volumesFrameLayout.addWidget(self.listWidget)
        self.volumesFrameLayout.addWidget(self.volumeButtonsFrame)

        self.volumeRenderingPropertiesMenu = VolumeRenderingPropertiesMenu()
        self.volumeRenderingPropertiesMenu.threshold.connect(
            'valuesChanged(double,double)', self.onThresholdSliderMoved)
        self.volumeRenderingPropertiesMenu.colorRangeSlider.connect(
            'valuesChanged(double,double)', self.onColorSliderMoved)
        self.volumeRenderingPropertiesMenu.checkBoxVisible3D.connect(
            "stateChanged(int)", self.onVisible3DChanged)

        self.scalarRange = [0., 255.]
Exemple #8
0
    def setup(self):
        # Instantiate and connect widgets ...

        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "MurineTrial Reload"
        self.layout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)

        # reload and test button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadAndTestButton = qt.QPushButton("Reload and Test")
        self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
        self.layout.addWidget(self.reloadAndTestButton)
        self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

        # Collapsible button
        measurementsCollapsibleButton = ctk.ctkCollapsibleButton()
        measurementsCollapsibleButton.text = "Materials"
        self.layout.addWidget(measurementsCollapsibleButton)

        # Layout within the measurements collapsible button
        measurementsFormLayout = qt.QFormLayout(measurementsCollapsibleButton)

        # list of materials in the trial
        measurementsFormLayout.addWidget(qt.QLabel("Individual Segmentations"))
        self.materialsScrollArea = qt.QScrollArea()
        measurementsFormLayout.addWidget(self.materialsScrollArea)
        self.materialsListWidget = qt.QListWidget()
        self.materialsScrollArea.setWidget(self.materialsListWidget)
        self.materialsScrollArea.setWidgetResizable(True)
        self.materialsListWidget.setProperty(
            'SH_ItemView_ActivateItemOnSingleClick', 1)
        self.materialsListWidget.connect('activated(QModelIndex)',
                                         self.onMaterialActivated)
        # populate it
        materialKeys = self.logic.materials.keys()
        materialKeys.sort()
        for materialKey in materialKeys:
            self.materialsListWidget.addItem(materialKey)

        # list of sampleIDs in the trial
        measurementsFormLayout.addWidget(
            qt.QLabel("Segmentation Comparisions"))
        self.sampleIDsScrollArea = qt.QScrollArea()
        measurementsFormLayout.addWidget(self.sampleIDsScrollArea)
        self.sampleIDsListWidget = qt.QListWidget()
        self.sampleIDsScrollArea.setWidget(self.sampleIDsListWidget)
        self.sampleIDsScrollArea.setWidgetResizable(True)
        self.sampleIDsListWidget.setProperty(
            'SH_ItemView_ActivateItemOnSingleClick', 1)
        self.sampleIDsListWidget.connect('activated(QModelIndex)',
                                         self.onSampleIDActivated)
        # populate it
        for sampleID in self.logic.gigSegComparisonSampleIDs():
            self.sampleIDsListWidget.addItem(sampleID)

        # list of retestIDs in the trial
        measurementsFormLayout.addWidget(qt.QLabel("Repeatability Tests"))
        self.retestIDsScrollArea = qt.QScrollArea()
        measurementsFormLayout.addWidget(self.retestIDsScrollArea)
        self.retestIDsListWidget = qt.QListWidget()
        self.retestIDsScrollArea.setWidget(self.retestIDsListWidget)
        self.retestIDsScrollArea.setWidgetResizable(True)
        self.retestIDsListWidget.setProperty(
            'SH_ItemView_ActivateItemOnSingleClick', 1)
        self.retestIDsListWidget.connect('activated(QModelIndex)',
                                         self.onRetestActivated)
        # populate it
        for retestID in self.logic.retestComparisonSampleIDs():
            self.retestIDsListWidget.addItem(retestID)

        # process all  button
        processAllButton = qt.QPushButton("Process All")
        processAllButton.toolTip = "Loads all subjecs at all timepoints."
        measurementsFormLayout.addWidget(processAllButton)
        processAllButton.connect('clicked(bool)', self.logic.processAll)

        # results area
        self.resultsView = qt.QWebView()
        self.resultsView.minimumSize = qt.QSize(100, 100)
        policy = qt.QSizePolicy()
        policy.setHorizontalPolicy(qt.QSizePolicy.Ignored)
        self.resultsView.setSizePolicy(policy)
        self.layout.addWidget(self.resultsView)

        # Add vertical spacer
        self.layout.addStretch(1)
    def setup(self):
        #Instantiate and Connect Widgets
        #################################################
        #HeterogeneityCAD Inputs Collapsible Button

        self.inputHeterogeneityCADCollapsibleButton = ctk.ctkCollapsibleButton(
        )
        self.inputHeterogeneityCADCollapsibleButton.text = "HeterogeneityCAD Input"
        self.layout.addWidget(self.inputHeterogeneityCADCollapsibleButton)
        self.inputHeterogeneityCADLayout = qt.QFormLayout(
            self.inputHeterogeneityCADCollapsibleButton)

        ##Input Volume as a PET/CT/MRI image or parameter map converted to a volume
        self.inputVolHetFrame = qt.QFrame(
            self.inputHeterogeneityCADCollapsibleButton)
        self.inputVolHetFrame.setLayout(qt.QHBoxLayout())
        self.inputHeterogeneityCADLayout.addRow(self.inputVolHetFrame)
        # label for selecting individual node
        self.inputVolHet = qt.QLabel("Input Node: ", self.inputVolHetFrame)
        self.inputVolHetFrame.layout().addWidget(self.inputVolHet)
        # select individual nodes
        self.inputSelectorVolHet = slicer.qMRMLNodeComboBox(
            self.inputVolHetFrame)
        self.inputSelectorVolHet.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.inputSelectorVolHet.selectNodeUponCreation = False
        self.inputSelectorVolHet.addEnabled = False
        self.inputSelectorVolHet.removeEnabled = False
        self.inputSelectorVolHet.setMRMLScene(slicer.mrmlScene)
        self.inputVolHetFrame.layout().addWidget(self.inputSelectorVolHet)
        # add Data Node button
        self.addDataNodeButton = qt.QPushButton("Add Node",
                                                self.inputVolHetFrame)
        self.addDataNodeButton.objectName = 'AddDataNodeButton'
        self.addDataNodeButton.setToolTip("Add a Node to Queue")
        self.addDataNodeButton.connect('clicked()',
                                       self.onAddDataNodeButtonClicked)
        self.inputVolHetFrame.layout().addWidget(self.addDataNodeButton)

        ## data nodes Frame
        self.dataNodesFrame = ctk.ctkCollapsibleGroupBox(
            self.inputHeterogeneityCADCollapsibleButton)
        self.dataNodesFrame.title = "Nodes List"
        self.dataNodesFrame.collapsed = False
        self.dataNodesFrame.setLayout(qt.QVBoxLayout())
        # all buttons frame
        self.allButtonsFrame = qt.QFrame(
            self.inputHeterogeneityCADCollapsibleButton)
        self.allButtonsFrame.objectName = 'AllButtonsFrameButton'
        self.allButtonsFrame.setLayout(qt.QVBoxLayout())
        self.inputHeterogeneityCADLayout.addRow(self.dataNodesFrame,
                                                self.allButtonsFrame)
        # Data Nodes view
        # Use list view here with scroll area widget.
        self.dataScrollArea = qt.QScrollArea()
        self.dataNodesListWidget = qt.QListWidget()
        self.dataNodesListWidget.name = 'dataNodesListWidget'
        self.dataScrollArea.setWidget(self.dataNodesListWidget)
        self.dataNodesListWidget.resize(350, 100)
        self.dataNodesFrame.layout().addWidget(self.dataScrollArea)
        #self.listWidget.setProperty('SH_ItemView_ActivateItemOnSingleClick', 1)
        #self.listWidget.connect('activated(QModelIndex)', self.onActivated)
        # add all Data Nodes from scene button
        self.addAllDataNodesButton = qt.QPushButton("Add All Nodes From Scene",
                                                    self.allButtonsFrame)
        self.addAllDataNodesButton.objectName = 'AddAllDataNodesButton'
        self.addAllDataNodesButton.setToolTip(
            "Add all Nodes from the Scene to Queue")
        self.addAllDataNodesButton.connect('clicked()',
                                           self.onAddAllDataNodesButtonClicked)
        self.allButtonsFrame.layout().addWidget(self.addAllDataNodesButton)
        # remove single Data Node
        self.removeDataNodeButton = qt.QPushButton("Remove Node",
                                                   self.allButtonsFrame)
        self.removeDataNodeButton.objectName = 'RemoveDataNodeButton'
        self.removeDataNodeButton.setToolTip(
            "Removes Selected Node from the Queue.")
        self.removeDataNodeButton.connect('clicked()',
                                          self.onRemoveDataNodeButtonClicked)
        self.allButtonsFrame.layout().addWidget(self.removeDataNodeButton)
        # remove all Data Nodes button
        self.removeAllDataNodesButton = qt.QPushButton("Remove All Nodes",
                                                       self.allButtonsFrame)
        self.removeAllDataNodesButton.objectName = 'RemoveAllDataNodesButton'
        self.removeAllDataNodesButton.setToolTip(
            "Removes All Nodes from the Queue.")
        self.removeAllDataNodesButton.connect(
            'clicked()', self.onRemoveAllDataNodesButtonClicked)
        self.allButtonsFrame.layout().addWidget(self.removeAllDataNodesButton)

        # Use Label Map as ROI(segmentation output or user-selected ROI)
        self.inputLabelROIFrame = qt.QFrame(
            self.inputHeterogeneityCADCollapsibleButton)
        self.inputLabelROIFrame.setLayout(qt.QHBoxLayout())
        self.inputHeterogeneityCADLayout.addRow(self.inputLabelROIFrame)
        # Enable Input Label Map as ROI
        self.inputLabelROI = qt.QLabel("Label Map ROI: ",
                                       self.inputLabelROIFrame)
        self.inputLabelROIFrame.layout().addWidget(self.inputLabelROI)
        # Select Input Label Map as ROI
        self.inputSelectorLabel = slicer.qMRMLNodeComboBox(
            self.inputLabelROIFrame)
        self.inputSelectorLabel.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "")
        self.inputSelectorLabel.selectNodeUponCreation = False
        self.inputSelectorLabel.renameEnabled = True
        self.inputSelectorLabel.removeEnabled = False
        self.inputSelectorLabel.noneEnabled = True
        self.inputSelectorLabel.addEnabled = False
        self.inputSelectorLabel.setMRMLScene(slicer.mrmlScene)
        self.inputLabelROIFrame.layout().addWidget(self.inputSelectorLabel)

        #End HeterogeneityCAD Inputs Collapsible Button
        #################################################
        #HeterogeneityCAD Features Collapsible Button

        self.HeterogeneityCADCollapsibleButton = ctk.ctkCollapsibleButton()
        self.HeterogeneityCADCollapsibleButton.text = "HeterogeneityCAD Features Selection"
        self.layout.addWidget(self.HeterogeneityCADCollapsibleButton)
        self.featuresHeterogeneityCADLayout = qt.QFormLayout(
            self.HeterogeneityCADCollapsibleButton)

        # auto-generate QTabWidget Tabs and QCheckBoxes (subclassed in FeatureWidgetHelperLib)
        self.tabsFeatureClasses = FeatureWidgetHelperLib.CheckableTabWidget()
        self.featuresHeterogeneityCADLayout.addRow(self.tabsFeatureClasses)

        gridWidth, gridHeight = 3, 9
        for featureClass in self.featureClassKeys:
            # by default, features from the following features classes are checked:
            if featureClass in [
                    "Node Information", "First-Order Statistics",
                    "Morphology and Shape", "Texture: GLCM", "Texture: GLRL"
            ]:
                check = True
            else:
                check = False
            tabFeatureClass = qt.QWidget()
            tabFeatureClass.setLayout(qt.QGridLayout())
            #featureList = (feature for feature in self.featureClassKeys[featureClass])
            gridLayoutCoordinates = ((row, col) for col in range(gridWidth)
                                     for row in range(gridHeight))
            for featureName in self.featureClassKeys[featureClass]:
                row, col = next(gridLayoutCoordinates, None)
                if featureName is None or row is None or col is None:
                    break
                featureCheckboxWidget = FeatureWidgetHelperLib.FeatureWidget()
                featureCheckboxWidget.Setup(featureName=featureName,
                                            checkStatus=check)

                tabFeatureClass.layout().addWidget(featureCheckboxWidget, row,
                                                   col)
                self.featureWidgets[featureClass].append(featureCheckboxWidget)
            self.tabsFeatureClasses.addTab(tabFeatureClass,
                                           featureClass,
                                           self.featureWidgets[featureClass],
                                           checkStatus=check)

        self.tabsFeatureClasses.setCurrentIndex(1)

        # note: try using itertools list merging with lists of GLRL diagonal
        self.heterogeneityFeatureWidgets = list(
            itertools.chain.from_iterable(self.featureWidgets.values()))
        self.classes = list(self.featureWidgets.keys())
        # or reduce(lambda x,y: x+y, self.featureWidgets.values())

        ########## Parameter options
        # add parameters for top-level feature classes
        self.tabsFeatureClasses.addParameter("Geometrical Measures",
                                             "Extrusion Parameter 1")
        self.tabsFeatureClasses.addParameter("Texture: GLCM",
                                             "GLCM Matrix Parameter 1")
        self.tabsFeatureClasses.addParameter("Texture: GLRL",
                                             "GLRL Matrix Parameter 1")

        # compile dict of feature classes with parameter names and values
        self.featureClassParametersDict = collections.OrderedDict()
        for featureClassWidget in self.tabsFeatureClasses.getFeatureClassWidgets(
        ):
            featureClassName = featureClassWidget.getName()
            self.featureClassParametersDict[
                featureClassName] = collections.OrderedDict()
            self.updateFeatureClassParameterDict(0, featureClassWidget)
            for parameterName in featureClassWidget.widgetMenu.parameters:
                featureClassWidget.getParameterEditWindow(
                    parameterName).connect(
                        'intValueChanged(int)',
                        lambda intValue, featureClassWidget=featureClassWidget:
                        self.updateFeatureClassParameterDict(
                            intValue, featureClassWidget))

        # add parameters for individual features
        for featureWidget in self.heterogeneityFeatureWidgets:
            if featureWidget.getName() == "Voxel Count":
                featureWidget.addParameter("Example Parameter 1")
                featureWidget.addParameter("Example Parameter 2")
            if featureWidget.getName() == "Gray Levels":
                featureWidget.addParameter("Example Parameter 1-GL")
                featureWidget.addParameter("Example Parameter 2-GL")

        # compile dict of features with parameter names and values
        self.featureParametersDict = collections.OrderedDict()
        for featureWidget in self.heterogeneityFeatureWidgets:
            featureName = featureWidget.getName()
            self.featureParametersDict[featureName] = collections.OrderedDict()
            self.updateFeatureParameterDict(0, featureWidget)
            for parameterName in featureWidget.widgetMenu.parameters:
                featureWidget.getParameterEditWindow(parameterName).connect(
                    'intValueChanged(int)',
                    lambda intValue, featureWidget=featureWidget: self.
                    updateFeatureParameterDict(intValue, featureWidget)
                )  #connect intvaluechanged signals to updateParamaterDict function
        ##########

        # Feature Buttons Frame and Layout
        self.featureButtonFrame = qt.QFrame(
            self.HeterogeneityCADCollapsibleButton)
        self.featureButtonFrame.setLayout(qt.QHBoxLayout())
        self.featuresHeterogeneityCADLayout.addRow(self.featureButtonFrame)

        # HeterogeneityCAD Apply Button
        self.HeterogeneityCADButton = qt.QPushButton("Apply HeterogeneityCAD",
                                                     self.featureButtonFrame)
        self.HeterogeneityCADButton.toolTip = "Analyze input volume using selected Heterogeneity Features."
        self.featureButtonFrame.layout().addWidget(self.HeterogeneityCADButton)
        self.HeterogeneityCADButton.connect(
            'clicked()', self.onHeterogeneityCADButtonClicked)

        # Save Button
        self.saveButton = qt.QPushButton("Save to File",
                                         self.featureButtonFrame)
        self.saveButton.toolTip = "Save analyses to CSV file"
        self.saveButton.enabled = False
        self.featureButtonFrame.layout().addWidget(self.saveButton)
        self.saveButton.connect('clicked()', self.onSave)

        #End HeterogeneityCAD Features Collapsible Button
        #################################################
        #Feature Summary Chart

        #Complete chart options, export list of user-selected options identified via connections to labelstatistics module
        self.chartOptions = ("Count", "Volume mm^3", "Volume cc", "Min", "Max",
                             "Mean", "StdDev")
        self.StatisticsChartCollapsibleButton = ctk.ctkCollapsibleButton()
        self.StatisticsChartCollapsibleButton.text = "HeterogeneityCAD Features Summary"
        self.layout.addWidget(self.StatisticsChartCollapsibleButton)
        self.StatisticsChartLayout = qt.QFormLayout(
            self.StatisticsChartCollapsibleButton)
        self.StatisticsChartCollapsibleButton.collapsed = False

        #Table View to display Label statistics
        self.view = qt.QTableView(self.StatisticsChartCollapsibleButton)
        self.view.sortingEnabled = True
        self.StatisticsChartLayout.addWidget(self.view)
        self.view.minimumHeight = 175