def create(self): super(WindowLevelEffectOptions,self).create() #self.thresholdPaint.hide() #self.paintOver.hide() #self.threshold.hide() #self.thresholdLabel.hide() # add the selection whether it should work as regular w/l control, # or as a rectangle self.normalMode = qt.QRadioButton('Normal mode') self.rectangleMode = qt.QRadioButton('Rectangle mode') self.rectangleMode.setChecked(1) label = qt.QLabel('Mode of operation:') self.frame.layout().addWidget(label) self.viewGroup = qt.QButtonGroup() self.viewGroup.addButton(self.normalMode,1) self.viewGroup.addButton(self.rectangleMode,2) self.frame.layout().addWidget(self.normalMode) self.frame.layout().addWidget(self.rectangleMode) self.viewGroup.connect('buttonClicked(int)',self.updateMRMLFromGUI) label = qt.QLabel('Layers affected:') self.bgSelector = qt.QCheckBox('Background') self.fgSelector = qt.QCheckBox('Foreground') self.bgSelector.checked = 1 self.fgSelector.checked = 1 self.frame.layout().addWidget(label) self.frame.layout().addWidget(self.bgSelector) self.frame.layout().addWidget(self.fgSelector) self.bgSelector.connect('stateChanged(int)',self.updateMRMLFromGUI) self.fgSelector.connect('stateChanged(int)',self.updateMRMLFromGUI) EditorLib.HelpButton(self.frame, "Use this tool to change window/level of background/foreground volumes based on the intensity range of the selected rectangle.\n\nNormal mode: use primary mouse button to adjust window level. Depending on the selection, Foreground, Background or both layers are affected.\n\nRectangle mode: Left Click and Drag: sweep out an outline that will draw when the button is released. The outline will define the rectangle for calculating the new window/level settings for the selected layers.\n\n") # step4Layout.addRow(self.normalMode, rectangleMode) # Add vertical spacer self.frame.layout().addStretch(1) # set effect-specific parameters if self.parameterNode.GetParameter('WindowLevelEffect,wlmode') == '': self.parameterNode.SetParameter('WindowLevelEffect,wlmode', 'Rectangle') if self.parameterNode.GetParameter('WindowLevelEffect,changeBg') == '': self.parameterNode.SetParameter('WindowLevelEffect,changeBg','1') if self.parameterNode.GetParameter('WindowLevelEffect,changeFg') == '': self.parameterNode.SetParameter('WindowLevelEffect,changeFg','1') if self.parameterNode.GetParameter('Effect,scope') == '': self.parameterNode.SetParameter('Effect,scope','')
def create(self, registationState): """Make the plugin-specific user interface""" super(LocalBRAINSFitPlugin, self).create(registationState) self.LocalBRAINSFitMode = "Small" self.VerboseMode = "Quiet" # # Local Refinment Pane - initially hidden # - interface options for linear registration # self.LocalBRAINSFitCollapsibleButton = ctk.ctkCollapsibleButton() self.LocalBRAINSFitCollapsibleButton.text = "Local BRAINSFit" LocalBRAINSFitFormLayout = qt.QFormLayout() self.LocalBRAINSFitCollapsibleButton.setLayout( LocalBRAINSFitFormLayout) self.widgets.append(self.LocalBRAINSFitCollapsibleButton) buttonLayout = qt.QVBoxLayout() self.LocalBRAINSFitModeButtons = {} self.LocalBRAINSFitModes = ("Small", "Large") for mode in self.LocalBRAINSFitModes: self.LocalBRAINSFitModeButtons[mode] = qt.QRadioButton() self.LocalBRAINSFitModeButtons[mode].text = mode self.LocalBRAINSFitModeButtons[mode].setToolTip( "Run the refinement in a %s local region." % mode.lower()) buttonLayout.addWidget(self.LocalBRAINSFitModeButtons[mode]) self.widgets.append(self.LocalBRAINSFitModeButtons[mode]) self.LocalBRAINSFitModeButtons[mode].connect( 'clicked()', lambda m=mode: self.onLocalBRAINSFitMode(m)) self.LocalBRAINSFitModeButtons[self.LocalBRAINSFitMode].checked = True LocalBRAINSFitFormLayout.addRow("Local BRAINSFit Mode ", buttonLayout) buttonLayout = qt.QVBoxLayout() self.VerboseModeButtons = {} self.VerboseModes = ("Quiet", "Verbose") for mode in self.VerboseModes: self.VerboseModeButtons[mode] = qt.QRadioButton() self.VerboseModeButtons[mode].text = mode self.VerboseModeButtons[mode].setToolTip( "Run the refinement in %s mode." % mode.lower()) buttonLayout.addWidget(self.VerboseModeButtons[mode]) self.widgets.append(self.VerboseModeButtons[mode]) self.VerboseModeButtons[mode].connect( 'clicked()', lambda m=mode: self.onVerboseMode(m)) self.VerboseModeButtons[self.VerboseMode].checked = True LocalBRAINSFitFormLayout.addRow("Verbose Mode ", buttonLayout) self.parent.layout().addWidget(self.LocalBRAINSFitCollapsibleButton)
def create(self, registationState): """Make the plugin-specific user interface""" super(AffinePlugin, self).create(registationState) self.linearMode = "Rigid" # # Linear Registration Pane - initially hidden # - interface options for linear registration # - TODO: move registration code into separate plugins # self.linearCollapsibleButton = ctk.ctkCollapsibleButton() self.linearCollapsibleButton.text = "Linear Registration" linearFormLayout = qt.QFormLayout() self.linearCollapsibleButton.setLayout(linearFormLayout) self.widgets.append(self.linearCollapsibleButton) buttonLayout = qt.QVBoxLayout() self.linearModeButtons = {} self.linearModes = ("Rigid", "Similarity", "Affine") for mode in self.linearModes: self.linearModeButtons[mode] = qt.QRadioButton() self.linearModeButtons[mode].text = mode self.linearModeButtons[mode].setToolTip( "Run the registration in %s mode." % mode) buttonLayout.addWidget(self.linearModeButtons[mode]) self.widgets.append(self.linearModeButtons[mode]) self.linearModeButtons[mode].connect( 'clicked()', lambda m=mode: self.onLinearTransform(m)) self.linearModeButtons[self.linearMode].checked = True linearFormLayout.addRow("Registration Mode ", buttonLayout) self.parent.layout().addWidget(self.linearCollapsibleButton)
def createUserInterface(self): font = qt.QFont("Sans Serif", 12, qt.QFont.Bold) self.__layout = qt.QFormLayout(self) self.trayectoriaLibreButton = qt.QRadioButton('Trayectoria libre') self.trayectoriaProgramadaButton = qt.QRadioButton( 'Trayectoria programada') self.__layout.addRow("", qt.QWidget()) self.__layout.addRow("", qt.QWidget()) self.__layout.addRow("", qt.QWidget()) self.trayectoriaLibreButton.setFont(font) self.trayectoriaProgramadaButton.setFont(font) self.__layout.addRow(self.trayectoriaLibreButton) self.__layout.addRow(self.trayectoriaProgramadaButton)
def create(self): super(MorphologyEffectOptions,self).create() # TODO: provide an entry for label to replace with (defaults to zero) self.eightNeighbors = qt.QRadioButton("Eight Neighbors", self.frame) self.eightNeighbors.setToolTip("Treat diagonally adjacent voxels as neighbors.") self.frame.layout().addWidget(self.eightNeighbors) self.widgets.append(self.eightNeighbors) self.fourNeighbors = qt.QRadioButton("Four Neighbors", self.frame) self.fourNeighbors.setToolTip("Do not treat diagonally adjacent voxels as neighbors.") self.frame.layout().addWidget(self.fourNeighbors) self.widgets.append(self.fourNeighbors) # TODO: fill option not yet supported # TODO: iterations option not yet supported self.connections.append( (self.eightNeighbors, 'clicked()', self.updateMRMLFromGUI) ) self.connections.append( (self.fourNeighbors, 'clicked()', self.updateMRMLFromGUI) )
def createUserInterface(self): font =qt.QFont("Sans Serif", 12, qt.QFont.Bold) self.__layout = qt.QFormLayout( self ) self.anadirTrayectoriaButton = qt.QRadioButton('Anadir trayectoria') self.calificarButton = qt.QRadioButton('Calificar trayectoria de alumnos') self.verActividadButton = qt.QRadioButton('Ver actividad de alumnos') self.__layout.addRow("",qt.QWidget()) self.__layout.addRow("",qt.QWidget()) self.__layout.addRow("",qt.QWidget()) self.anadirTrayectoriaButton.setFont(font) self.calificarButton.setFont(font) self.verActividadButton.setFont(font) self.__layout.addRow(self.anadirTrayectoriaButton) self.__layout.addRow(self.calificarButton) self.__layout.addRow(self.verActividadButton)
def makeTransformationTypeWidgets(self): self.trsfTypeTab = qt.QWidget() self.parametersTabWidget.addTab(self.trsfTypeTab, 'Transformation type') trsfTypeLayout = qt.QHBoxLayout(self.trsfTypeTab) self.trsfTypeRadioButtons = [] for trsfType in TRANSFORMATIONS_MAP: radioButton = qt.QRadioButton(trsfType) radioButton.clicked.connect(self.onTransformationTypeChanged) self.trsfTypeRadioButtons.append(radioButton) trsfTypeLayout.addWidget(radioButton) self.trsfTypeRadioButtons[0].setChecked(True)
def createUserInterface(self): font = qt.QFont("Sans Serif", 12, qt.QFont.Bold) self.__layout = qt.QFormLayout(self) self.__layout.addRow(" ", qt.QWidget()) self.__layout.addRow(" ", qt.QWidget()) self.nombreBienvenida = qt.QLabel("Quien eres?") self.nombreBienvenida.setFont(font) self.__layout.addRow(self.nombreBienvenida) self.__layout.addRow(" ", qt.QWidget()) self.__layout.addRow(" ", qt.QWidget()) self.EstudianteButton = qt.QRadioButton('Soy estudiante') self.EstudianteButton.setFont(font) self.ProfesorButton = qt.QRadioButton('Soy profesor') self.ProfesorButton.setFont(font) self.soyNuevoButton = qt.QRadioButton('Soy nuevo') self.soyNuevoButton.setFont(font) self.__layout.addRow(self.EstudianteButton) self.__layout.addRow(" ", qt.QWidget()) self.__layout.addRow(self.ProfesorButton) self.__layout.addRow(" ", qt.QWidget()) self.__layout.addRow(self.soyNuevoButton)
def setup(self): frame = qt.QFrame() frameLayout = qt.QFormLayout() frame.setLayout(frameLayout) self.parent.layout().addWidget(frame) # Choose directory button to choose the folder for saving the registered image self.directoryButton = qt.QPushButton( "Choose folder with the segmented images") self.directoryButton.setFont(qt.QFont(self.font_type, self.font_size)) self.directoryButton.toolTip = "Choose a folder of .nii or .img/.hdr images of the segmented bones." frameLayout.addWidget(self.directoryButton) self.directoryButton.connect('clicked()', self.onDirectoryButtonClick) frameLayout.addRow(self.directoryButton) # Choose the Output folder button to choose the folder for saving the registered image self.outputDirectoryButton = qt.QPushButton( "Choose folder to save the output training data to") self.outputDirectoryButton.setFont( qt.QFont(self.font_type, self.font_size)) self.outputDirectoryButton.toolTip = "Choose a folder to save the output" frameLayout.addWidget(self.outputDirectoryButton) self.outputDirectoryButton.connect('clicked()', self.onOutputDirectoryButtonClick) frameLayout.addRow(self.outputDirectoryButton) # ICP Registration Collapse button self.ICPCollapsibleButton = ctk.ctkCollapsibleButton() self.ICPCollapsibleButton.setFont( qt.QFont(self.font_type, self.font_size)) self.ICPCollapsibleButton.text = "Iterative Closest Point Registration" self.ICPCollapsibleButton.collapsed = True # Default is to not show frameLayout.addWidget(self.ICPCollapsibleButton) # Layout within the ICP collapsible button self.ICPFormLayout = qt.QFormLayout(self.ICPCollapsibleButton) # Slider for Maximum Iteration Number for ICP registration self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Maximum Iteration Number: ") self.label.setToolTip( "Select the maximum iteration number for the ICP registration.") self.IterationSlider = ctk.ctkSliderWidget() self.IterationSlider.setToolTip( "Select the maximum iteration number for the ICP registration.") self.IterationSlider.minimum = 1 self.IterationSlider.maximum = 200 self.IterationSlider.value = 100 self.IterationSlider.singleStep = 5 self.IterationSlider.tickInterval = 1 self.IterationSlider.decimals = 0 self.IterationSlider.connect('valueChanged(double)', self.onIterationSliderChange) self.ICPFormLayout.addRow(self.label, self.IterationSlider) self.IterationNumber = self.IterationSlider.value # Set default value # Slider for Number of Landmarks for ICP self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("ICP Landmark Number: ") self.label.setToolTip( "Select the number of landmarks per surface for the ICP registration." ) self.LandmarkSlider = ctk.ctkSliderWidget() self.LandmarkSlider.setToolTip( "Select the number of landmarks per surface for the ICP registration." ) self.LandmarkSlider.minimum = 50 self.LandmarkSlider.maximum = 1000 self.LandmarkSlider.value = 500 self.LandmarkSlider.singleStep = 10 self.LandmarkSlider.tickInterval = 1 self.LandmarkSlider.decimals = 0 self.LandmarkSlider.connect('valueChanged(double)', self.onLandmarkSliderChange) self.ICPFormLayout.addRow(self.label, self.LandmarkSlider) self.LandmarkNumber = self.LandmarkSlider.value # Set default value # Slider for Maximum RMS Error for ICP self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("ICP Maximum RMS Error: ") self.label.setToolTip( "Select the maximum root mean square (RMS) error for determining the ICP registration convergence." ) self.RMS_Slider = ctk.ctkSliderWidget() self.RMS_Slider.setToolTip( "Select the maximum root mean square (RMS) error for determining the ICP registration convergence." ) self.RMS_Slider.minimum = 0.0001 self.RMS_Slider.maximum = 0.05 self.RMS_Slider.value = 0.01 self.RMS_Slider.singleStep = 0.01 self.RMS_Slider.tickInterval = 0.001 self.RMS_Slider.decimals = 3 self.RMS_Slider.connect('valueChanged(double)', self.onRMS_SliderChange) self.ICPFormLayout.addRow(self.label, self.RMS_Slider) self.RMS_Number = self.RMS_Slider.value # Set default value # Slider for choosing the reference bone self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Reference Bone Label: ") self.label.setToolTip( "Select the label of the bone to keep static. This bone will be registered among all the volunteers. Note: Please choose the folder with the segmented images first." ) self.Ref_Bone_Slider = ctk.ctkSliderWidget() self.Ref_Bone_Slider.setToolTip( "Select the label of the bone to keep static. This bone will be registered among all the volunteers. Note: Please choose the folder with the segmented images first." ) self.Ref_Bone_Slider.minimum = 0 self.Ref_Bone_Slider.maximum = 0 self.Ref_Bone_Slider.value = 0 self.Ref_Bone_Slider.singleStep = 1 self.Ref_Bone_Slider.tickInterval = 1 self.Ref_Bone_Slider.decimals = 0 self.Ref_Bone_Slider.connect('valueChanged(double)', self.onRef_Bone_SliderChange) self.ICPFormLayout.addRow(self.label, self.Ref_Bone_Slider) self.ref_label = int(self.Ref_Bone_Slider.value) # Set default value # Radial buttons for the ICP parameters self.radial_button_1 = qt.QRadioButton("Similarity") self.radial_button_1.setFont(qt.QFont(self.font_type, self.font_size)) self.radial_button_1.toggled.connect(self.onICPModeSelect_1) self.ICPFormLayout.addWidget(self.radial_button_1) self.radial_button_2 = qt.QRadioButton("Rigid") self.radial_button_2.setFont(qt.QFont(self.font_type, self.font_size)) self.radial_button_2.setChecked(True) self.radial_button_2.toggled.connect(self.onICPModeSelect_2) self.ICPFormLayout.addWidget(self.radial_button_2) self.radial_button_3 = qt.QRadioButton("Affine") self.radial_button_3.toggled.connect(self.onICPModeSelect_3) self.ICPFormLayout.addWidget(self.radial_button_3) # Text input for choosing which image labels to use self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Image Labels: ") self.label.setToolTip( "Choose several labels to use for creating the training data. Value of -1 uses the default 1 through 9. Otherwise, input should be similar to '1,2,3' to use labels one, two, and three. " ) self.lineedit = qt.QLineEdit() self.lineedit.setFont(qt.QFont(self.font_type, self.font_size)) self.lineedit.setToolTip( "Choose several labels to use for creating the training data. Value of -1 uses the default 1 through 9. Otherwise, input should be similar to '1,2,3' to use labels one, two, and three. " ) self.ICPFormLayout.addRow(self.label, self.lineedit) self.lineedit.setText("-1") # Bone Smoothing Parameters Collapse Button self.SmoothCollapsibleButton = ctk.ctkCollapsibleButton() self.SmoothCollapsibleButton.setFont( qt.QFont(self.font_type, self.font_size)) self.SmoothCollapsibleButton.text = "Smoothing Options" self.SmoothCollapsibleButton.collapsed = True # Default is to not show frameLayout.addWidget(self.SmoothCollapsibleButton) # Layout within the smoothing options collapsible button self.SmoothFormLayout = qt.QFormLayout(self.SmoothCollapsibleButton) # Slider for choosing the number of iterations for bone smoothing self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Smoothing Iterations: ") self.label.setToolTip( "Select the number of iterations for smoothing the bone surface. Higher iterations will smooth more. Lower iterations will have less smoothing." ) self.Bone_Smoothing_Its_Slider = ctk.ctkSliderWidget() self.Bone_Smoothing_Its_Slider.setToolTip( "Select the number of iterations for smoothing the bone surface. Higher iterations will smooth more. Lower iterations will have less smoothing." ) self.Bone_Smoothing_Its_Slider.minimum = 0 self.Bone_Smoothing_Its_Slider.maximum = 30 self.Bone_Smoothing_Its_Slider.value = 10 self.Bone_Smoothing_Its_Slider.singleStep = 1 self.Bone_Smoothing_Its_Slider.tickInterval = 1 self.Bone_Smoothing_Its_Slider.decimals = 0 self.Bone_Smoothing_Its_Slider.connect( 'valueChanged(double)', self.onBone_Smoothing_Its_SliderChange) self.SmoothFormLayout.addRow(self.label, self.Bone_Smoothing_Its_Slider) self.smoothing_iterations = self.Bone_Smoothing_Its_Slider.value # Set default value # Slider for choosing the smoothing relaxation factor self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Relaxation Factor: ") self.label.setToolTip( "Select the relaxation factor for smoothing the bone surfaces. Higher relaxation will smooth the surface more while a lower factor will have less smoothing." ) self.Bone_Smoothing_Relaxation_Slider = ctk.ctkSliderWidget() self.Bone_Smoothing_Relaxation_Slider.setToolTip( "Select the relaxation factor for smoothing the bone surfaces. Higher relaxation will smooth the surface more while a lower factor will have less smoothing." ) self.Bone_Smoothing_Relaxation_Slider.minimum = 0 self.Bone_Smoothing_Relaxation_Slider.maximum = 1 self.Bone_Smoothing_Relaxation_Slider.value = 0.4 self.Bone_Smoothing_Relaxation_Slider.singleStep = 0.1 self.Bone_Smoothing_Relaxation_Slider.tickInterval = 0.1 self.Bone_Smoothing_Relaxation_Slider.decimals = 2 self.Bone_Smoothing_Relaxation_Slider.connect( 'valueChanged(double)', self.onBone_Smoothing_Relaxation_SliderChange) self.SmoothFormLayout.addRow(self.label, self.Bone_Smoothing_Relaxation_Slider) self.relaxation_factor = self.Bone_Smoothing_Relaxation_Slider.value # Set default value # Slider for choosing the percentage of bone surface decimation self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Surface Decimation: ") self.label.setToolTip( "Select the ratio of verticies to remove from the bone surface. This results in a smoother surface and less points for faster computation. Too much could cause surface artifacts. For example, 0.1 removes 10 percent while 0.9 removes 90 percent of points." ) self.Bone_Decimate_Slider = ctk.ctkSliderWidget() self.Bone_Decimate_Slider.setToolTip( "Select the ratio of verticies to remove from the bone surface. This results in a smoother surface and less points for faster computation. Too much could cause surface artifacts. For example, 0.1 removes 10 percent while 0.9 removes 90 percent of points." ) self.Bone_Decimate_Slider.minimum = 0 self.Bone_Decimate_Slider.maximum = 0.9 self.Bone_Decimate_Slider.value = 0 self.Bone_Decimate_Slider.singleStep = 0.05 self.Bone_Decimate_Slider.tickInterval = 0.05 self.Bone_Decimate_Slider.decimals = 2 self.Bone_Decimate_Slider.connect('valueChanged(double)', self.onBone_Decimate_SliderChange) self.SmoothFormLayout.addRow(self.label, self.Bone_Decimate_Slider) self.decimate_surface = self.Bone_Decimate_Slider.value # Set default value # Debugging Collapse button self.RenderingCollapsibleButton = ctk.ctkCollapsibleButton() self.RenderingCollapsibleButton.setFont( qt.QFont(self.font_type, self.font_size)) self.RenderingCollapsibleButton.text = "Visualization" self.RenderingCollapsibleButton.collapsed = True # Default is to not show frameLayout.addWidget(self.RenderingCollapsibleButton) # Layout within the debug collapsible button self.CollapseFormLayout = qt.QFormLayout( self.RenderingCollapsibleButton) # Show the registered shapes toggle button self.show_registered_shapes = qt.QCheckBox("Show Registered Shapes") self.show_registered_shapes.setFont( qt.QFont(self.font_type, self.font_size)) self.show_registered_shapes.toolTip = "When checked, show each registered bone. Useful for debugging any ICP registration based errors." self.show_registered_shapes.checked = False self.CollapseFormLayout.addWidget(self.show_registered_shapes) # Show the registered shapes toggle button self.show_extracted_shapes = qt.QCheckBox("Show Extracted Shapes") self.show_extracted_shapes.setFont( qt.QFont(self.font_type, self.font_size)) self.show_extracted_shapes.toolTip = "When checked, show the initial surfaces from the images. Useful for debugging errors based on deriving surfaces from the MR images." self.show_extracted_shapes.checked = False self.CollapseFormLayout.addWidget(self.show_extracted_shapes) # Show the loaded images toggle button self.debug_show_images = qt.QCheckBox("Show Loaded Images") self.debug_show_images.setFont(qt.QFont(self.font_type, self.font_size)) self.debug_show_images.toolTip = "When checked, show the loaded images. Useful for debugging if the images are flipped or loading incorrectly." self.debug_show_images.checked = False self.CollapseFormLayout.addWidget(self.debug_show_images) # Debugging Collapse button self.DebugCollapsibleButton = ctk.ctkCollapsibleButton() self.DebugCollapsibleButton.setFont( qt.QFont(self.font_type, self.font_size)) self.DebugCollapsibleButton.text = "Debugging" self.DebugCollapsibleButton.collapsed = True # Default is to not show frameLayout.addWidget(self.DebugCollapsibleButton) # Layout within the debug collapsible button self.CollapseFormLayout = qt.QFormLayout(self.DebugCollapsibleButton) # Show the flip image vertically toggle button self.flip_image_vertically = qt.QCheckBox("Flip Vertically") self.flip_image_vertically.setFont( qt.QFont(self.font_type, self.font_size)) self.flip_image_vertically.toolTip = "When checked, flip the images vertically after loading them." self.flip_image_vertically.checked = False self.CollapseFormLayout.addWidget(self.flip_image_vertically) # Show the flip image horizontally toggle button self.flip_image_horizontally = qt.QCheckBox("Flip Horizontally") self.flip_image_horizontally.setFont( qt.QFont(self.font_type, self.font_size)) self.flip_image_horizontally.toolTip = "When checked, flip the images horizontally after loading them." self.flip_image_horizontally.checked = False self.CollapseFormLayout.addWidget(self.flip_image_horizontally) # Show the save bones separately toggle button self.Save_Extracted_Bones_Separately = qt.QCheckBox( "Save Extracted Bones Separately") self.Save_Extracted_Bones_Separately.setFont( qt.QFont(self.font_type, self.font_size)) self.Save_Extracted_Bones_Separately.toolTip = "When checked, save each bone surface separately after smoothing and before any registration." self.Save_Extracted_Bones_Separately.checked = False self.CollapseFormLayout.addWidget(self.Save_Extracted_Bones_Separately) # Show the save bones separately toggle button self.Save_Registered_Bones_Separately = qt.QCheckBox( "Save Registered Bones Separately") self.Save_Registered_Bones_Separately.setFont( qt.QFont(self.font_type, self.font_size)) self.Save_Registered_Bones_Separately.toolTip = "When checked, save each bone surface separately after smoothing and registration (instead of combining all the bones for each volunteer/position together)." self.Save_Registered_Bones_Separately.checked = False self.CollapseFormLayout.addWidget( self.Save_Registered_Bones_Separately) # Skip the registration self.Skip_Registration = qt.QCheckBox("Skip Registration Steps") self.Skip_Registration.setFont(qt.QFont(self.font_type, self.font_size)) self.Skip_Registration.toolTip = "When checked, extract each bone surface from the image and smooth the surface (this is useful if the user only wishes to extract the bones from the images and smooth them.) Consider using along with the save extracted bones setting." self.Skip_Registration.checked = False self.CollapseFormLayout.addWidget(self.Skip_Registration) # Don't save the reference bone toggle button self.Remove_Ref_Bone = qt.QCheckBox("Remove the reference bone") self.Remove_Ref_Bone.setFont(qt.QFont(self.font_type, self.font_size)) self.Remove_Ref_Bone.toolTip = "When checked, don't save the refernce bone when saving the PLY file. For example, this is useful if using the radius as a reference bone, but if you don't want it to appear in the final model." self.Remove_Ref_Bone.checked = False self.CollapseFormLayout.addWidget(self.Remove_Ref_Bone) # Choose the number of files to load from the given folder self.label = qt.QLabel() self.label.setFont(qt.QFont(self.font_type, self.font_size)) self.label.setText("Number of images: ") self.label.setToolTip( "Select how many images to use from the given folder. (Select the folder first). This is useful if want want to use just the first few images to make sure everything runs correctly." ) self.NumFileSlider = ctk.ctkSliderWidget() self.NumFileSlider.setToolTip( "Select how many images to use from the given folder. (Select the folder first). This is useful if want want to use just the first few images to make sure everything runs correctly." ) self.NumFileSlider.minimum = -1 self.NumFileSlider.maximum = 1 self.NumFileSlider.value = -1 self.NumFileSlider.singleStep = 1 self.NumFileSlider.tickInterval = 1 self.NumFileSlider.decimals = 0 self.NumFileSlider.connect('valueChanged(double)', self.onNumSliderChange) self.CollapseFormLayout.addRow(self.label, self.NumFileSlider) self.num_files = self.NumFileSlider.value # Set default value # Compute button self.computeButton = qt.QPushButton("Create The Training Data") self.computeButton.setFont(qt.QFont(self.font_type, self.font_size)) self.computeButton.toolTip = "Run the module and create the training data for the PCA bone displacement model." frameLayout.addWidget(self.computeButton) self.computeButton.connect('clicked()', self.onCompute) self.computeButton.enabled = False # Progress Bar (so the user knows how much longer it will take) self.progressBar = qt.QProgressBar() self.progressBar.setFont(qt.QFont(self.font_type, self.font_size)) self.progressBar.setValue(0) frameLayout.addWidget(self.progressBar) self.progressBar.hide()
def setup(self): # TODO: The following line is strictly for debug purposes, should be removed when this module is done slicer.tvwidget = self # Collapsible buttons self.parametersCollapsibleButton = ctk.ctkCollapsibleButton() self.parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(self.parametersCollapsibleButton) # Layout within the collapsible button self.parametersFormLayout = qt.QFormLayout(self.parametersCollapsibleButton) # Transform combobox self.transformLabel = qt.QLabel() self.transformLabel.setText("toolCameraToToolTransform: ") self.transformSelector = slicer.qMRMLNodeComboBox() self.transformSelector.nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" ) self.transformSelector.noneEnabled = False self.transformSelector.addEnabled = False self.transformSelector.removeEnabled = False self.transformSelector.setMRMLScene( slicer.mrmlScene ) self.transformSelector.setToolTip("Pick the transform that the camera should follow, e.g. 'cauteryCameraToCauteryTransform'") self.parametersFormLayout.addRow(self.transformLabel, self.transformSelector) # Camera combobox self.cameraLabel = qt.QLabel() self.cameraLabel.setText("Scene Camera: ") self.cameraSelector = slicer.qMRMLNodeComboBox() self.cameraSelector.nodeTypes = ( ("vtkMRMLCameraNode"), "" ) self.cameraSelector.noneEnabled = False self.cameraSelector.addEnabled = False self.cameraSelector.removeEnabled = False self.cameraSelector.setMRMLScene( slicer.mrmlScene ) self.cameraSelector.setToolTip("Pick the camera which should be moved, e.g. 'Default Scene Camera'") self.parametersFormLayout.addRow(self.cameraLabel, self.cameraSelector) # "Camera Control" Collapsible self.cameraControlCollapsibleButton = ctk.ctkCollapsibleButton() self.cameraControlCollapsibleButton.text = "Camera Control" self.layout.addWidget(self.cameraControlCollapsibleButton) # Layout within the collapsible button self.cameraControlFormLayout = qt.QFormLayout(self.cameraControlCollapsibleButton) # "Degrees of Freedom" Collapsible button self.degreesOfFreedomCollapsibleButton = ctk.ctkCollapsibleGroupBox() self.degreesOfFreedomCollapsibleButton.title = "Degrees of Freedom" self.cameraControlFormLayout.addRow(self.degreesOfFreedomCollapsibleButton) # Layout within the collapsible button self.degreesOfFreedomFormLayout = qt.QFormLayout(self.degreesOfFreedomCollapsibleButton) # A series of radio buttons for changing the degrees of freedom self.degreesOfFreedom3Label = qt.QLabel(qt.Qt.Horizontal,None) self.degreesOfFreedom3Label.setText("3DOF: ") self.degreesOfFreedom3RadioButton = qt.QRadioButton() self.degreesOfFreedom3RadioButton.setToolTip("The camera will always look at the target model (or if unselected will act like 5DOF)") self.degreesOfFreedomFormLayout.addRow(self.degreesOfFreedom3Label,self.degreesOfFreedom3RadioButton) self.degreesOfFreedom5Label = qt.QLabel(qt.Qt.Horizontal,None) self.degreesOfFreedom5Label.setText("5DOF: ") self.degreesOfFreedom5RadioButton = qt.QRadioButton() self.degreesOfFreedom5RadioButton.setToolTip("The camera will always be oriented with the selected 'up direction'") self.degreesOfFreedomFormLayout.addRow(self.degreesOfFreedom5Label,self.degreesOfFreedom5RadioButton) self.degreesOfFreedom6Label = qt.QLabel(qt.Qt.Horizontal,None) self.degreesOfFreedom6Label.setText("6DOF: ") self.degreesOfFreedom6RadioButton = qt.QRadioButton() self.degreesOfFreedom6RadioButton.setToolTip("The camera will be virtually attached to the tool, and rotate together with it") self.degreesOfFreedom6RadioButton.setChecked(True) self.degreesOfFreedomFormLayout.addRow(self.degreesOfFreedom6Label,self.degreesOfFreedom6RadioButton) # "Up Direction" Collapsible button self.upDirectionCollapsibleButton = ctk.ctkCollapsibleGroupBox() self.upDirectionCollapsibleButton.title = "Up Direction" self.upDirectionCollapsibleButton.setVisible(False) self.cameraControlFormLayout.addRow(self.upDirectionCollapsibleButton) # Layout within the collapsible button self.upDirectionFormLayout = qt.QFormLayout(self.upDirectionCollapsibleButton) # Radio buttons for each of the anatomical directions self.upDirectionAnteriorLabel = qt.QLabel(qt.Qt.Horizontal,None) self.upDirectionAnteriorLabel.setText("Anterior: ") self.upDirectionAnteriorRadioButton = qt.QRadioButton() self.upDirectionAnteriorRadioButton.setChecked(True) self.upDirectionFormLayout.addRow(self.upDirectionAnteriorLabel,self.upDirectionAnteriorRadioButton) self.upDirectionPosteriorLabel = qt.QLabel(qt.Qt.Horizontal,None) self.upDirectionPosteriorLabel.setText("Posterior: ") self.upDirectionPosteriorRadioButton = qt.QRadioButton() self.upDirectionFormLayout.addRow(self.upDirectionPosteriorLabel,self.upDirectionPosteriorRadioButton) self.upDirectionRightLabel = qt.QLabel(qt.Qt.Horizontal,None) self.upDirectionRightLabel.setText("Right: ") self.upDirectionRightRadioButton = qt.QRadioButton() self.upDirectionFormLayout.addRow(self.upDirectionRightLabel,self.upDirectionRightRadioButton) self.upDirectionLeftLabel = qt.QLabel(qt.Qt.Horizontal,None) self.upDirectionLeftLabel.setText("Left: ") self.upDirectionLeftRadioButton = qt.QRadioButton() self.upDirectionFormLayout.addRow(self.upDirectionLeftLabel,self.upDirectionLeftRadioButton) self.upDirectionSuperiorLabel = qt.QLabel(qt.Qt.Horizontal,None) self.upDirectionSuperiorLabel.setText("Superior: ") self.upDirectionSuperiorRadioButton = qt.QRadioButton() self.upDirectionFormLayout.addRow(self.upDirectionSuperiorLabel,self.upDirectionSuperiorRadioButton) self.upDirectionInferiorLabel = qt.QLabel(qt.Qt.Horizontal,None) self.upDirectionInferiorLabel.setText("Inferior: ") self.upDirectionInferiorRadioButton = qt.QRadioButton() self.upDirectionFormLayout.addRow(self.upDirectionInferiorLabel,self.upDirectionInferiorRadioButton) # "Target Model" Collapsible button self.targetModelCollapsibleButton = ctk.ctkCollapsibleGroupBox() self.targetModelCollapsibleButton.title = "Target Model" self.targetModelCollapsibleButton.setVisible(False) self.cameraControlFormLayout.addRow(self.targetModelCollapsibleButton) # Layout within the collapsible button self.targetModelFormLayout = qt.QFormLayout(self.targetModelCollapsibleButton) # Selection of the target model self.targetModelLabel = qt.QLabel(qt.Qt.Horizontal,None) self.targetModelLabel.text = "Target model: " self.targetModelSelector = slicer.qMRMLNodeComboBox() self.targetModelSelector.nodeTypes = ( ("vtkMRMLModelNode"), "" ) self.targetModelSelector.noneEnabled = False self.targetModelSelector.addEnabled = False self.targetModelSelector.removeEnabled = False self.targetModelSelector.setMRMLScene( slicer.mrmlScene ) self.targetModelSelector.setToolTip("This model be the center of rotation using 3DOF Viewpoint (e.g. tumour)") self.targetModelFormLayout.addRow(self.targetModelLabel,self.targetModelSelector) # "Zoom" Collapsible button self.zoomCollapsibleButton = ctk.ctkCollapsibleGroupBox() self.zoomCollapsibleButton.title = "Zoom" self.cameraControlFormLayout.addRow(self.zoomCollapsibleButton) # Layout within the collapsible button self.zoomFormLayout = qt.QFormLayout(self.zoomCollapsibleButton) # Camera viewing angle (perspective projection only) self.cameraViewAngleLabel = qt.QLabel(qt.Qt.Horizontal,None) self.cameraViewAngleLabel.setText("View angle (degrees): ") self.cameraViewAngleSlider = slicer.qMRMLSliderWidget() self.cameraViewAngleSlider.minimum = self.cameraViewAngleMinDeg self.cameraViewAngleSlider.maximum = self.cameraViewAngleMaxDeg self.cameraViewAngleSlider.value = self.sliderViewAngleDefaultDeg self.cameraViewAngleSlider.singleStep = self.sliderSingleStepValue self.cameraViewAngleSlider.pageStep = self.sliderPageStepValue self.cameraViewAngleSlider.setToolTip("Make the current viewing target look larger/smaller.") self.zoomFormLayout.addRow(self.cameraViewAngleLabel,self.cameraViewAngleSlider) # Camera parallel scale (parallel projection only) self.cameraParallelScaleLabel = qt.QLabel(qt.Qt.Horizontal,None) self.cameraParallelScaleLabel.setText("View scale: ") self.cameraParallelScaleLabel.setVisible(False) self.cameraParallelScaleSlider = slicer.qMRMLSliderWidget() self.cameraParallelScaleSlider.minimum = self.cameraParallelScaleMinDeg self.cameraParallelScaleSlider.maximum = self.cameraParallelScaleMaxDeg self.cameraParallelScaleSlider.value = self.sliderParallelScaleDefaultDeg self.cameraParallelScaleSlider.singleStep = self.sliderSingleStepValue self.cameraParallelScaleSlider.pageStep = self.sliderPageStepValue self.cameraParallelScaleSlider.setToolTip("Make the current viewing target look larger/smaller.") self.cameraParallelScaleSlider.setVisible(False) self.zoomFormLayout.addRow(self.cameraParallelScaleLabel,self.cameraParallelScaleSlider) # "Translation" Collapsible self.translationCollapsibleButton = ctk.ctkCollapsibleGroupBox() self.translationCollapsibleButton.title = "Translation" self.cameraControlFormLayout.addRow(self.translationCollapsibleButton) # Layout within the collapsible button self.translationFormLayout = qt.QFormLayout(self.translationCollapsibleButton) self.cameraXPosLabel = qt.QLabel(qt.Qt.Horizontal,None) self.cameraXPosLabel.text = "Left/Right (mm): " self.cameraXPosSlider = slicer.qMRMLSliderWidget() self.cameraXPosSlider.minimum = self.sliderTranslationMinMm self.cameraXPosSlider.maximum = self.sliderTranslationMaxMm self.cameraXPosSlider.value = self.sliderTranslationDefaultMm self.cameraXPosSlider.singleStep = self.sliderSingleStepValue self.cameraXPosSlider.pageStep = self.sliderPageStepValue self.translationFormLayout.addRow(self.cameraXPosLabel,self.cameraXPosSlider) self.cameraYPosLabel = qt.QLabel(qt.Qt.Horizontal,None) self.cameraYPosLabel.setText("Down/Up (mm): ") self.cameraYPosSlider = slicer.qMRMLSliderWidget() self.cameraYPosSlider.minimum = self.sliderTranslationMinMm self.cameraYPosSlider.maximum = self.sliderTranslationMaxMm self.cameraYPosSlider.value = self.sliderTranslationDefaultMm self.cameraYPosSlider.singleStep = self.sliderSingleStepValue self.cameraYPosSlider.pageStep = self.sliderPageStepValue self.translationFormLayout.addRow(self.cameraYPosLabel,self.cameraYPosSlider) self.cameraZPosLabel = qt.QLabel(qt.Qt.Horizontal,None) self.cameraZPosLabel.setText("Front/Back (mm): ") self.cameraZPosSlider = slicer.qMRMLSliderWidget() self.cameraZPosSlider.minimum = self.sliderTranslationMinMm self.cameraZPosSlider.maximum = self.sliderTranslationMaxMm self.cameraZPosSlider.value = self.sliderTranslationDefaultMm self.cameraZPosSlider.singleStep = self.sliderSingleStepValue self.cameraZPosSlider.pageStep = self.sliderPageStepValue self.translationFormLayout.addRow(self.cameraZPosLabel,self.cameraZPosSlider) # "Model Visibility" Collapsible self.modelVisibilityCollapsibleButton = ctk.ctkCollapsibleGroupBox() self.modelVisibilityCollapsibleButton.title = "Model Visibility" self.cameraControlFormLayout.addRow(self.modelVisibilityCollapsibleButton) # Layout within the collapsible button self.modelVisibilityFormLayout = qt.QFormLayout(self.modelVisibilityCollapsibleButton) self.modelOnlyViewpointOnLabel = qt.QLabel(qt.Qt.Horizontal,None) self.modelOnlyViewpointOnLabel.text = "Model visible only for Viewpoint on: " self.modelOnlyViewpointOnSelector = slicer.qMRMLNodeComboBox() self.modelOnlyViewpointOnSelector.nodeTypes = ( ("vtkMRMLModelNode"), "" ) self.modelOnlyViewpointOnSelector.noneEnabled = True self.modelOnlyViewpointOnSelector.addEnabled = False self.modelOnlyViewpointOnSelector.removeEnabled = False self.modelOnlyViewpointOnSelector.setMRMLScene( slicer.mrmlScene ) self.modelOnlyViewpointOnSelector.setToolTip("This model be visible if Viewpoint mode is enabled, and invisible otherwise") self.modelVisibilityFormLayout.addRow(self.modelOnlyViewpointOnLabel,self.modelOnlyViewpointOnSelector) self.modelOnlyViewpointOffLabel = qt.QLabel(qt.Qt.Horizontal,None) self.modelOnlyViewpointOffLabel.text = "Model visible only for Viewpoint off: " self.modelOnlyViewpointOffSelector = slicer.qMRMLNodeComboBox() self.modelOnlyViewpointOffSelector.nodeTypes = ( ("vtkMRMLModelNode"), "" ) self.modelOnlyViewpointOffSelector.noneEnabled = True self.modelOnlyViewpointOffSelector.addEnabled = False self.modelOnlyViewpointOffSelector.removeEnabled = False self.modelOnlyViewpointOffSelector.setMRMLScene( slicer.mrmlScene ) self.modelOnlyViewpointOffSelector.setToolTip("This model be visible if Viewpoint Mode is disabled, and invisible otherwise") self.modelVisibilityFormLayout.addRow(self.modelOnlyViewpointOffLabel,self.modelOnlyViewpointOffSelector) # Camera parallel projection checkbox self.cameraParallelProjectionLabel = qt.QLabel() self.cameraParallelProjectionLabel.setText("Parallel Projection") self.cameraParallelProjectionCheckbox = qt.QCheckBox() self.cameraParallelProjectionCheckbox.setCheckState(0) self.cameraParallelProjectionCheckbox.setToolTip("If checked, render with parallel projection (box-shaped view). Otherwise render with perspective projection (cone-shaped view).") self.cameraControlFormLayout.addRow(self.cameraParallelProjectionLabel,self.cameraParallelProjectionCheckbox) # "Toggle Tool Point of View" button self.enableViewpointButton = qt.QPushButton() self.enableViewpointButton.setToolTip("The camera will continuously update its position so that it follows the tool.") self.enableViewpointButton.setText(self.enableViewpointButtonTextState0) self.cameraControlFormLayout.addRow(self.enableViewpointButton) #Connections self.enableViewpointButton.connect('clicked()', self.enableViewpointButtonPressed) self.cameraParallelProjectionCheckbox.connect('stateChanged(int)', self.toggleCameraParallelProjectionCheckboxPressed) self.cameraViewAngleSlider.connect('valueChanged(double)', self.logic.SetCameraViewAngleDeg) self.cameraParallelScaleSlider.connect('valueChanged(double)', self.logic.SetCameraParallelScale) self.cameraXPosSlider.connect('valueChanged(double)', self.logic.SetCameraXPosMm) self.cameraYPosSlider.connect('valueChanged(double)', self.logic.SetCameraYPosMm) self.cameraZPosSlider.connect('valueChanged(double)', self.logic.SetCameraZPosMm) self.upDirectionAnteriorRadioButton.connect('clicked()', self.changeUpToAnterior) self.upDirectionPosteriorRadioButton.connect('clicked()', self.changeUpToPosterior) self.upDirectionLeftRadioButton.connect('clicked()', self.changeUpToLeft) self.upDirectionRightRadioButton.connect('clicked()', self.changeUpToRight) self.upDirectionSuperiorRadioButton.connect('clicked()', self.changeUpToSuperior) self.upDirectionInferiorRadioButton.connect('clicked()', self.changeUpToInferior) self.degreesOfFreedom3RadioButton.connect('clicked()', self.changeInterfaceTo3DOFMode) self.degreesOfFreedom5RadioButton.connect('clicked()', self.changeInterfaceTo5DOFMode) self.degreesOfFreedom6RadioButton.connect('clicked()', self.changeInterfaceTo6DOFMode) # Add vertical spacer self.layout.addStretch(1)
def setup(self): self.PathRecorderModuleDirectoryPath = slicer.modules.pathrecorder.path.replace( "PathRecorder.py", "") # Instantiate and connect widgets ... # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # 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 = "PathRecorder Reload" reloadFormLayout.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." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Input fiducial node selector # self.inputFiducialsNodeSelector = slicer.qMRMLNodeComboBox() self.inputFiducialsNodeSelector.nodeTypes = [ 'vtkMRMLMarkupsFiducialNode' ] self.inputFiducialsNodeSelector.selectNodeUponCreation = True self.inputFiducialsNodeSelector.addEnabled = True self.inputFiducialsNodeSelector.removeEnabled = False self.inputFiducialsNodeSelector.noneEnabled = True self.inputFiducialsNodeSelector.showHidden = False self.inputFiducialsNodeSelector.showChildNodeTypes = False self.inputFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) self.inputFiducialsNodeSelector.objectName = 'inputFiducialsNodeSelector' self.inputFiducialsNodeSelector.toolTip = "Select storage node for the recorded points (Markup-Fiducial-Node)." #inputFiducialsNodeSelector.connect('currentNodeChanged(bool)', self.enableOrDisableCreateButton) parametersFormLayout.addRow("Storage Node:", self.inputFiducialsNodeSelector) #self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # Input Tracker node selector # self.inputTrackerNodeSelector = slicer.qMRMLNodeComboBox() self.inputTrackerNodeSelector.nodeTypes = [ 'vtkMRMLLinearTransformNode' ] self.inputTrackerNodeSelector.selectNodeUponCreation = True self.inputTrackerNodeSelector.addEnabled = False self.inputTrackerNodeSelector.removeEnabled = False self.inputTrackerNodeSelector.noneEnabled = True self.inputTrackerNodeSelector.showHidden = False self.inputTrackerNodeSelector.showChildNodeTypes = False self.inputTrackerNodeSelector.setMRMLScene(slicer.mrmlScene) self.inputTrackerNodeSelector.objectName = 'inputTrackerNodeSelector' self.inputTrackerNodeSelector.toolTip = "Select the tracker linear transform node." #inputTrackerNodeSelector.connect('currentNodeChanged(bool)', self.enableOrDisableCreateButton) parametersFormLayout.addRow("Tracker Transform:", self.inputTrackerNodeSelector) #self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputTrackerNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # # Status Area # statusCollapsibleButton = ctk.ctkCollapsibleButton() statusCollapsibleButton.text = "Tracker Status" self.layout.addWidget(statusCollapsibleButton) # Layout within the status collapsible button statusFormLayout = qt.QFormLayout(statusCollapsibleButton) # # Status Button # self.statusRedIcon = qt.QIcon(self.PathRecorderModuleDirectoryPath + '/Resources/Icons/icon_DotRed.png') self.statusGreenIcon = qt.QIcon(self.PathRecorderModuleDirectoryPath + '/Resources/Icons/icon_DotGreen.png') self.statusButton = qt.QPushButton("") #self.statusButton.toolTip = "Tracker Status" self.statusButton.enabled = False self.statusButton.setIcon(self.statusRedIcon) self.statusButton.setMaximumWidth(25) # Bold and large font for needle label largeFont = qt.QFont() largeFont.setPixelSize(14) # # Label for showing the tracker position # self.currentCoordinatesLabel = qt.QLabel('[ NaN , NaN , NaN ]') self.currentCoordinatesLabel.setToolTip("Tracker Position") statusFormLayout.addRow(self.statusButton, self.currentCoordinatesLabel) # # Collect Area # collectCollapsibleButton = ctk.ctkCollapsibleButton() collectCollapsibleButton.text = "Acquire Points" self.layout.addWidget(collectCollapsibleButton) # Layout within the collect collapsible button collectFormLayout = qt.QFormLayout(collectCollapsibleButton) # # Name base line-edit # self.nameBaseLineEdit = qt.QLineEdit() self.nameBaseLineEdit.setToolTip("Fiducials Name Base") collectFormLayout.addRow("Fiducials Name Base:", self.nameBaseLineEdit) # # Single Acquire Button # self.singleAcquireButton = qt.QPushButton("Single Point") self.singleAcquireButton.toolTip = "Acquire a single point at the current position." self.singleAcquireButton.enabled = True collectFormLayout.addRow(self.singleAcquireButton) # # Continuous Acquire Button # self.recordButtonIcon = qt.QIcon(self.PathRecorderModuleDirectoryPath + '/Resources/Icons/icon_Record.png') self.stopButtonIcon = qt.QIcon(self.PathRecorderModuleDirectoryPath + '/Resources/Icons/icon_Stop.png') self.acquireButton = qt.QPushButton("Continuous") self.acquireButton.toolTip = "Start acquiring points continiously." self.acquireButton.enabled = True self.acquireButton.checkable = True self.acquireButton.setIcon(self.recordButtonIcon) #self.acquireButton.setMinimumWidth(80) #self.acquireButton.setMaximumWidth(80) collectFormLayout.addRow(self.acquireButton) # # Distance-based Radio Button # self.distanceBasedButton = qt.QRadioButton("Minimum Distance:") self.distanceBasedButton.setChecked(1) #collectFormLayout.addRow() # Distance slider distanceSlider = ctk.ctkSliderWidget() #distanceSlider.decimals = 0 distanceSlider.minimum = 0.1 distanceSlider.maximum = 100 distanceSlider.suffix = " mm" distanceSlider.value = 1 distanceSlider.toolTip = "Set minimum distance between recorded points" self.distanceSlider = distanceSlider collectFormLayout.addRow("Minimum Distance:", distanceSlider) # # Delete Button # self.deleteButton = qt.QPushButton("Delete") self.deleteButton.toolTip = "Delete all the points." self.deleteButton.enabled = True collectFormLayout.addRow(self.deleteButton) # # Export Area # exportCollapsibleButton = ctk.ctkCollapsibleButton() exportCollapsibleButton.text = "Export Points" self.layout.addWidget(exportCollapsibleButton) # Layout within the dummy collapsible button exportFormLayout = qt.QFormLayout(exportCollapsibleButton) # # Load Button # self.exportDirectoryButton = ctk.ctkDirectoryButton() exportFormLayout.addRow(self.exportDirectoryButton) # # Name base line-edit # self.fileNameBaseLineEdit = qt.QLineEdit() self.fileNameBaseLineEdit.setToolTip("File name base") self.fileNameBaseLineEdit.text = 'PathRecorder' exportFormLayout.addRow("File Name Base:", self.fileNameBaseLineEdit) # # Save Button # saveButtonIcon = qt.QIcon(self.PathRecorderModuleDirectoryPath + '/Resources/Icons/icon_Save.png') self.exportButton = qt.QPushButton() self.exportButton.setIcon(saveButtonIcon) self.exportButton.toolTip = "Save points." self.exportButton.enabled = True exportFormLayout.addRow(self.exportButton) # connections self.inputFiducialsNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.setAnnotationHierarchyNode) self.inputTrackerNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.setTransformNode) self.distanceBasedButton.connect('toggled(bool)', self.distanceBasedSelected) self.acquireButton.connect('toggled(bool)', self.onAcquireButtonToggled) self.singleAcquireButton.connect('clicked()', self.onSingleAcButtonClicked) self.deleteButton.connect('clicked()', self.onDeleteButtonClicked) self.exportButton.connect('clicked()', self.onExportButtonClicked) #self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) #self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1)
def setup(self): # Instantiate and connect widgets ... if self.developerMode: # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # 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 = "CompareVolumes Reload" reloadFormLayout.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 All") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # reload and run specific tests scenarios = ( "Three Volume", "View Watcher", "LayerReveal", ) for scenario in scenarios: button = qt.QPushButton("Reload and Test %s" % scenario) self.reloadAndTestButton.toolTip = "Reload this module and then run the %s self test." % scenario reloadFormLayout.addWidget(button) button.connect( 'clicked()', lambda s=scenario: self.onReloadAndTest(scenario=s)) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # orientation # self.orientationBox = qt.QGroupBox("Orientation") self.orientationBox.setLayout(qt.QFormLayout()) self.orientationButtons = {} self.orientations = ("Axial", "Sagittal", "Coronal") for orientation in self.orientations: self.orientationButtons[orientation] = qt.QRadioButton() self.orientationButtons[orientation].text = orientation self.orientationButtons[orientation].connect( "clicked()", lambda o=orientation: self.setOrientation(o)) self.orientationBox.layout().addWidget( self.orientationButtons[orientation]) parametersFormLayout.addWidget(self.orientationBox) self.setOrientation(self.orientations[0]) # # target volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = (("vtkMRMLVolumeNode"), "") self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = True self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Target Volume: ", self.inputSelector) # # lightbox # self.lightboxVolumeButton = qt.QPushButton("Lightbox Target Volume") self.lightboxVolumeButton.setToolTip( "Make a set of slice views that span the extent of this study at equally spaced locations in the selected orientation." ) parametersFormLayout.addRow(self.lightboxVolumeButton) self.lightboxVolumeButton.connect("clicked()", self.onLightboxVolume) # # background volume selector # self.backgroundSelector = slicer.qMRMLNodeComboBox() self.backgroundSelector.nodeTypes = (("vtkMRMLVolumeNode"), "") self.backgroundSelector.selectNodeUponCreation = True self.backgroundSelector.addEnabled = False self.backgroundSelector.removeEnabled = False self.backgroundSelector.noneEnabled = True self.backgroundSelector.showHidden = False self.backgroundSelector.showChildNodeTypes = True self.backgroundSelector.setMRMLScene(slicer.mrmlScene) self.backgroundSelector.setToolTip( "Common background - all lightbox panes will have this background and a different volume in each foreground." ) parametersFormLayout.addRow("Common Background Volume: ", self.backgroundSelector) # # label volume selector # self.labelSelector = slicer.qMRMLNodeComboBox() self.labelSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.labelSelector.selectNodeUponCreation = True self.labelSelector.addEnabled = False self.labelSelector.removeEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = True self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip( "Common label - all lightbox panes will have this label on top.") parametersFormLayout.addRow("Common Label Volume: ", self.labelSelector) self.lightboxVolumesButton = qt.QPushButton("Lightbox All Volumes") self.lightboxVolumesButton.setToolTip( "Make a set of slice views that show each of the currently loaded volumes, with optional companion volumes, in the selected orientation." ) parametersFormLayout.addRow(self.lightboxVolumesButton) self.lightboxVolumesButton.connect("clicked()", self.onLightboxVolumes) # # Add layer reveal area # layerRevealCollapsibleButton = ctk.ctkCollapsibleButton() layerRevealCollapsibleButton.text = "Layer Reveal Cursor" self.layout.addWidget(layerRevealCollapsibleButton) layerRevealFormLayout = qt.QFormLayout(layerRevealCollapsibleButton) self.layerRevealCheck = qt.QCheckBox() layerRevealFormLayout.addRow("Layer Reveal Cursor", self.layerRevealCheck) self.layerRevealCheck.connect("toggled(bool)", self.onLayerRevealToggled) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # TODO: The following lines are strictly for debug purposes, should be removed when this module is done self.developerMode = True slicer.igwidget = self self.logic = InsertionGridPlannerLogic() # Collapsible buttons self.parametersCollapsibleButton = ctk.ctkCollapsibleButton() self.parametersCollapsibleButton.text = "InsertionGridPlanner" self.layout.addWidget(self.parametersCollapsibleButton) # Layout within the collapsible button self.parametersFormLayout = qt.QFormLayout( self.parametersCollapsibleButton) # Transform Tool Tip To Reference combobox self.transformNodeGridToTargetLabel = qt.QLabel() self.transformNodeGridToTargetLabel.setText( "Grid to Target Transform: ") self.transformNodeGridToTargetSelector = slicer.qMRMLNodeComboBox() self.transformNodeGridToTargetSelector.nodeTypes = (( "vtkMRMLLinearTransformNode"), "") self.transformNodeGridToTargetSelector.noneEnabled = False self.transformNodeGridToTargetSelector.addEnabled = False self.transformNodeGridToTargetSelector.removeEnabled = False self.transformNodeGridToTargetSelector.setMRMLScene(slicer.mrmlScene) self.transformNodeGridToTargetSelector.setToolTip( "Pick the transform for going from the grid's coordinate system to the target (reference) coordinate system" ) self.parametersFormLayout.addRow( self.transformNodeGridToTargetLabel, self.transformNodeGridToTargetSelector) # Grid type self.gridPatternRectangularLabel = qt.QLabel(qt.Qt.Horizontal, None) self.gridPatternRectangularLabel.setText("Rectangular Grid") self.gridPatternRectangularRadioButton = qt.QRadioButton() self.gridPatternRectangularRadioButton.setToolTip( "Make the grid rectangular") self.gridPatternRectangularRadioButton.setChecked(True) self.parametersFormLayout.addRow( self.gridPatternRectangularLabel, self.gridPatternRectangularRadioButton) self.gridPatternTriangularLabel = qt.QLabel(qt.Qt.Horizontal, None) self.gridPatternTriangularLabel.setText("Triangular Grid") self.gridPatternTriangularRadioButton = qt.QRadioButton() self.gridPatternTriangularRadioButton.setToolTip( "Make the grid triangular") self.parametersFormLayout.addRow(self.gridPatternTriangularLabel, self.gridPatternTriangularRadioButton) # Grid size self.gridSizeLeftLabel = qt.QLabel() self.gridSizeLeftLabel.setText("Extent left (mm): ") self.gridSizeLeftSlider = slicer.qMRMLSliderWidget() self.gridSizeLeftSlider.minimum = 0 # mm self.gridSizeLeftSlider.maximum = 150 # mm self.gridSizeLeftSlider.value = 0 # mm self.gridSizeLeftSlider.setToolTip("Adjust the size of the grid") self.parametersFormLayout.addRow(self.gridSizeLeftLabel, self.gridSizeLeftSlider) self.gridSizeRightLabel = qt.QLabel() self.gridSizeRightLabel.setText("Extent right (mm): ") self.gridSizeRightSlider = slicer.qMRMLSliderWidget() self.gridSizeRightSlider.minimum = 0 # mm self.gridSizeRightSlider.maximum = 150 # mm self.gridSizeRightSlider.value = 0 # mm self.gridSizeRightSlider.setToolTip("Adjust the size of the grid") self.parametersFormLayout.addRow(self.gridSizeRightLabel, self.gridSizeRightSlider) self.gridSizeUpLabel = qt.QLabel() self.gridSizeUpLabel.setText("Extent up (mm): ") self.gridSizeUpSlider = slicer.qMRMLSliderWidget() self.gridSizeUpSlider.minimum = 0 # mm self.gridSizeUpSlider.maximum = 150 # mm self.gridSizeUpSlider.value = 0 # mm self.gridSizeUpSlider.setToolTip("Adjust the size of the grid") self.parametersFormLayout.addRow(self.gridSizeUpLabel, self.gridSizeUpSlider) self.gridSizeDownLabel = qt.QLabel() self.gridSizeDownLabel.setText("Extent down (mm): ") self.gridSizeDownSlider = slicer.qMRMLSliderWidget() self.gridSizeDownSlider.minimum = 0 # mm self.gridSizeDownSlider.maximum = 150 # mm self.gridSizeDownSlider.value = 0 # mm self.gridSizeDownSlider.setToolTip("Adjust the size of the grid") self.parametersFormLayout.addRow(self.gridSizeDownLabel, self.gridSizeDownSlider) # Grid spacing self.gridSpacingHorizontalLabel = qt.QLabel(qt.Qt.Horizontal, None) self.gridSpacingHorizontalLabel.text = "Horizontal Spacing (mm): " self.gridSpacingHorizontalSlider = slicer.qMRMLSliderWidget() self.gridSpacingHorizontalSlider.minimum = 1 # mm self.gridSpacingHorizontalSlider.maximum = 50 # mm self.gridSpacingHorizontalSlider.value = 10 # mm self.parametersFormLayout.addRow(self.gridSpacingHorizontalLabel, self.gridSpacingHorizontalSlider) self.gridSpacingVerticalLabel = qt.QLabel(qt.Qt.Horizontal, None) self.gridSpacingVerticalLabel.text = "Vertical Spacing (mm): " self.gridSpacingVerticalSlider = slicer.qMRMLSliderWidget() self.gridSpacingVerticalSlider.minimum = 1 # mm self.gridSpacingVerticalSlider.maximum = 50 # mm self.gridSpacingVerticalSlider.value = 10 # mm self.parametersFormLayout.addRow(self.gridSpacingVerticalLabel, self.gridSpacingVerticalSlider) # Grid creation self.createGridButton = qt.QPushButton() self.createGridButton.text = "Create Grid" self.createGridButton.setToolTip("Create the virtual grid guide.") self.parametersFormLayout.addRow(self.createGridButton) self.deleteGridButton = qt.QPushButton() self.deleteGridButton.text = "Delete Grid" self.deleteGridButton.setToolTip("Delete the virtual grid guide.") self.parametersFormLayout.addRow(self.deleteGridButton) # Add vertical spacer self.layout.addStretch(1) #Connections self.createGridButton.connect('clicked()', self.createGridButtonPressed) self.deleteGridButton.connect('clicked()', self.logic.deleteGrid)
def createUserInterface(self): """ This method uses qt to create a user interface of radio buttons to select a registration method. Note that BSpline registration is so slow and memory-consuming as to at one point break Slicer. There is an option to run it with limited memory, but this may take prohibitively long. <- NOTE this last comment was based on expert automated registration - not sure about other modules. """ self.__layout = self.__parent.createUserInterface() step_label = qt.QLabel( """Select your preferred method of registration. If you have already registered your images, or no registration is required, check the option "No Registration." The moving image will be registered to the fixed image, and then resampled at the dimensions of the fixed image. Be aware that many other modules in Slicer have more complex and/or customizable registration methods, should you require more thorough registration. """) step_label.setWordWrap(True) self.__primaryGroupBox = qt.QGroupBox() self.__primaryGroupBox.setTitle('Information') self.__primaryGroupBoxLayout = qt.QFormLayout(self.__primaryGroupBox) self.__primaryGroupBoxLayout.addRow(step_label) self.__layout.addRow(self.__primaryGroupBox) # Moving/Fixed Image Registration Order Options OrderGroupBox = qt.QGroupBox() OrderGroupBox.setTitle('Registration Order') self.__layout.addRow(OrderGroupBox) OrderGroupBoxLayout = qt.QFormLayout(OrderGroupBox) self.__OrderRadio1 = qt.QRadioButton( "Register pre-contrast to post-contrast.") self.__OrderRadio1.toolTip = "Your pre-contrast image will be transformed." OrderGroupBoxLayout.addRow(self.__OrderRadio1) self.__OrderRadio1.setChecked(True) self.__OrderRadio2 = qt.QRadioButton( "Register post-contrast to pre-contrast.") self.__OrderRadio2.toolTip = "Your post-contrast image will be transformed." OrderGroupBoxLayout.addRow(self.__OrderRadio2) # Registration Method Options RegistrationGroupBox = qt.QGroupBox() RegistrationGroupBox.setTitle('Registration Method') self.__layout.addRow(RegistrationGroupBox) RegistrationGroupBoxLayout = qt.QFormLayout(RegistrationGroupBox) self.__RegistrationRadio1 = qt.QRadioButton("No Registration") self.__RegistrationRadio1.toolTip = "Performs no registration." RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio1) self.__RegistrationRadio2 = qt.QRadioButton("Rigid Registration") self.__RegistrationRadio2.toolTip = """Computes a rigid registration on the pre-contrast image with respect to the post-contrast image. This will likely be the fastest registration method""" RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio2) self.__RegistrationRadio3 = qt.QRadioButton("Affine Registration") self.__RegistrationRadio3.toolTip = "Computes a rigid and affine registration on the pre-contrast image with respect to the post-contrast image. This method may take longer than rigid registration, but has the ability to stretch or compress images in addition to rotation and translation." RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio3) self.__RegistrationRadio3.setChecked(True) self.__RegistrationRadio4 = qt.QRadioButton("Deformable Registration") self.__RegistrationRadio4.toolTip = """Computes a BSpline Registration on the pre-contrast image with respect to the post-contrast image. This method is slowest and may be necessary for only severly distorted images.""" RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio4) # Output Volume Preference OutputGroupBox = qt.QGroupBox() OutputGroupBox.setTitle('Registration Output') self.__layout.addRow(OutputGroupBox) OutputGroupBoxLayout = qt.QFormLayout(OutputGroupBox) self.__OutputRadio1 = qt.QRadioButton("Create new volume.") self.__OutputRadio1.toolTip = "A new volume will be created with the naming convention \"[pre]_reg_[post]\"." OutputGroupBoxLayout.addRow(self.__OutputRadio1) self.__OutputRadio1.setChecked(True) self.__OutputRadio2 = qt.QRadioButton("Replace existing volume.") self.__OutputRadio2.toolTip = "Your registered volume will be overwritten at the end of this step." OutputGroupBoxLayout.addRow(self.__OutputRadio2) # Registration Button and Progress Indicator RunGroupBox = qt.QGroupBox() RunGroupBox.setTitle('Run Registration') self.__layout.addRow(RunGroupBox) RunGroupBoxLayout = qt.QFormLayout(RunGroupBox) self.__registrationButton = qt.QPushButton('Run registration') self.__registrationStatus = qt.QLabel('Register scans') self.__registrationStatus.alignment = 4 # This codes for centered alignment, although I'm not sure why. RunGroupBoxLayout.addRow(self.__registrationStatus) RunGroupBoxLayout.addRow(self.__registrationButton) self.__registrationButton.connect('clicked()', self.onRegistrationRequest)
def setup(self): self.FilteringFrame = qt.QFrame() self.FilteringFrame.setLayout(qt.QVBoxLayout()) self.FilteringFrame.enabled = False self.FilteringFrame.setObjectName('FilteringFrame') self.FilteringFrame.setStyleSheet( '#FilteringFrame {border: 1px solid lightGray; color: black; }') self.layout.addWidget(self.FilteringFrame) filterLabel = qt.QLabel() filterLabel.setText('Filtering') self.FilteringFrame.layout().addWidget(filterLabel) radioButtonsGroup = qt.QGroupBox() radioButtonsGroup.setLayout(qt.QHBoxLayout()) radioButtonsGroup.setFixedWidth(120) radioButtonsGroup.setObjectName('radioButtonsGroup') radioButtonsGroup.setStyleSheet( '#radioButtonsGroup {border: 1px solid white; color: black; }') self.filterOnRadioButton = qt.QRadioButton() self.filterOnRadioButton.setText('On') self.filterOnRadioButton.setChecked(0) radioButtonsGroup.layout().addWidget(self.filterOnRadioButton) self.filterOffRadioButton = qt.QRadioButton() self.filterOffRadioButton.setText('Off') self.filterOffRadioButton.setChecked(1) radioButtonsGroup.layout().addWidget(self.filterOffRadioButton) self.FilteringFrame.layout().addWidget(radioButtonsGroup) self.filterOptionsFrame = qt.QFrame() self.filterOptionsFrame.setLayout(qt.QVBoxLayout()) self.filterOptionsFrame.setObjectName('filterOptionsFrame') self.filterOptionsFrame.setStyleSheet( '#filterOptionsFrame {border: 0.5px solid lightGray; color: black; }' ) self.filterOptionsFrame.hide() self.FilteringFrame.layout().addWidget(self.filterOptionsFrame) self.filterApplication = qt.QCheckBox() self.filterApplication.setText('Filter for Phenotype Analysis') self.filterApplication.setChecked(0) self.filterOptionsFrame.layout().addWidget(self.filterApplication) filterOptionsGroup = qt.QGroupBox() filterOptionsGroup.setLayout(qt.QHBoxLayout()) filterOptionsGroup.setFixedWidth(220) filterOptionsGroup.setObjectName('filterOptionsGroup') filterOptionsGroup.setStyleSheet( '#filterOptionsGroup {border: 1px solid white; color: black; }') self.NLMFilterRadioButton = qt.QRadioButton() self.NLMFilterRadioButton.setText('NLM') self.NLMFilterRadioButton.setChecked(1) filterOptionsGroup.layout().addWidget(self.NLMFilterRadioButton) self.MedianFilterRadioButton = qt.QRadioButton() self.MedianFilterRadioButton.setText('Median') self.MedianFilterRadioButton.setChecked(0) filterOptionsGroup.layout().addWidget(self.MedianFilterRadioButton) self.GaussianFilterRadioButton = qt.QRadioButton() self.GaussianFilterRadioButton.setText('Gaussian') self.GaussianFilterRadioButton.setChecked(0) filterOptionsGroup.layout().addWidget(self.GaussianFilterRadioButton) self.filterOptionsFrame.layout().addWidget(filterOptionsGroup) # Filter Params FilterParams = qt.QFrame() FilterParams.setLayout(qt.QVBoxLayout()) self.filterOptionsFrame.layout().addWidget(FilterParams) DimGroupBox = qt.QGroupBox() DimGroupBox.setLayout(qt.QHBoxLayout()) DimGroupBox.setFixedWidth(180) DimGroupBox.setObjectName('DimGroupBox') DimGroupBox.setStyleSheet( '#DimGroupBox {border: 1px solid white; color: black; }') FilterParams.layout().addWidget(DimGroupBox) FilterDimensionLabel = qt.QLabel() FilterDimensionLabel.setText('Dimensions: ') FilterDimensionLabel.setToolTip( 'Choose if the filter has to operate in 2D or 3D.') DimGroupBox.layout().addWidget(FilterDimensionLabel) self.Filt2DOption = qt.QPushButton() self.Filt2DOption.setText('2D') self.Filt2DOption.setCheckable(1) self.Filt2DOption.setChecked(1) self.Filt2DOption.setAutoExclusive(1) self.Filt2DOption.setFixedWidth(45) DimGroupBox.layout().addWidget(self.Filt2DOption) self.Filt3DOption = qt.QPushButton() self.Filt3DOption.setText('3D') self.Filt3DOption.setCheckable(1) self.Filt3DOption.setChecked(0) self.Filt3DOption.setFixedWidth(45) self.Filt3DOption.setAutoExclusive(1) DimGroupBox.layout().addWidget(self.Filt3DOption) StrengthGroupBox = qt.QGroupBox() StrengthGroupBox.setLayout(qt.QHBoxLayout()) StrengthGroupBox.setFixedWidth(270) StrengthGroupBox.setObjectName('StrengthGroupBox') StrengthGroupBox.setStyleSheet( '#StrengthGroupBox {border: 1px solid white; color: black; }') FilterParams.layout().addWidget(StrengthGroupBox) FilterStrengthLabel = qt.QLabel() FilterStrengthLabel.setText('Strength: ') FilterStrengthLabel.setToolTip( 'Choose strength of the filtering process.') StrengthGroupBox.layout().addWidget(FilterStrengthLabel) self.SmoothOption = qt.QPushButton() self.SmoothOption.setText('Smooth') self.SmoothOption.setCheckable(1) self.SmoothOption.setChecked(1) self.SmoothOption.setAutoExclusive(1) self.SmoothOption.setFixedWidth(60) StrengthGroupBox.layout().addWidget(self.SmoothOption) self.MediumOption = qt.QPushButton() self.MediumOption.setText('Medium') self.MediumOption.setCheckable(1) self.MediumOption.setChecked(0) self.MediumOption.setFixedWidth(60) self.MediumOption.setAutoExclusive(1) StrengthGroupBox.layout().addWidget(self.MediumOption) self.HeavyOption = qt.QPushButton() self.HeavyOption.setText('Heavy') self.HeavyOption.setCheckable(1) self.HeavyOption.setChecked(0) self.HeavyOption.setFixedWidth(60) self.HeavyOption.setAutoExclusive(1) StrengthGroupBox.layout().addWidget(self.HeavyOption) # Downsampling option for label map creation self.LMCreationFrame = qt.QFrame() self.LMCreationFrame.setLayout(qt.QVBoxLayout()) self.LMCreationFrame.enabled = False self.LMCreationFrame.setObjectName('LMCreationFrame') self.LMCreationFrame.setStyleSheet( '#LMCreationFrame {border: 1px solid lightGray; color: black; }') self.parent.layout().addWidget(self.LMCreationFrame) LMCreationLabel = qt.QLabel() LMCreationLabel.setText('Label Map Creation:') self.LMCreationFrame.layout().addWidget(LMCreationLabel) self.DownSamplingGroupBox = qt.QGroupBox() self.DownSamplingGroupBox.setLayout(qt.QHBoxLayout()) self.DownSamplingGroupBox.setFixedWidth(130) self.DownSamplingGroupBox.setObjectName('DownSamplingGroupBox') self.DownSamplingGroupBox.setStyleSheet( '#DownSamplingGroupBox {border: 1px solid white; color: black; }') self.DownSamplingGroupBox.setToolTip( 'Choose between fast and slow label map creation.') self.LMCreationFrame.layout().addWidget(self.DownSamplingGroupBox) self.FastOption = qt.QRadioButton() self.FastOption.setText('Fast') self.FastOption.setCheckable(1) self.FastOption.setChecked(0) self.DownSamplingGroupBox.layout().addWidget(self.FastOption) self.SlowOption = qt.QRadioButton() self.SlowOption.setText('Slow') self.SlowOption.setCheckable(1) self.SlowOption.setChecked(1) self.DownSamplingGroupBox.layout().addWidget(self.SlowOption) self.filterOnRadioButton.connect('toggled(bool)', self.showFilterParams) self.filterOffRadioButton.connect('toggled(bool)', self.hideFilterParams)
def initMainPanel(self): # Create main collapsible Button self.mainCollapsibleBtn = ctk.ctkCollapsibleButton() self.mainCollapsibleBtn.setStyleSheet( "ctkCollapsibleButton { background-color: DarkSeaGreen }") self.mainCollapsibleBtn.text = "Remeshing Tools Selection" #self.mainCollapsibleBtn.collapsible = True self.layout.addWidget(self.mainCollapsibleBtn) self.mainFormLayout = qt.QFormLayout(self.mainCollapsibleBtn) # Create input Segmentation Selector self.inputSelectorCoBx = slicer.qMRMLNodeComboBox() self.inputSelectorCoBx.nodeTypes = ["vtkMRMLModelNode"] self.inputSelectorCoBx.setFixedWidth(200) self.inputSelectorCoBx.selectNodeUponCreation = True self.inputSelectorCoBx.addEnabled = False self.inputSelectorCoBx.removeEnabled = False self.inputSelectorCoBx.noneEnabled = False self.inputSelectorCoBx.showHidden = False self.inputSelectorCoBx.showChildNodeTypes = False self.inputSelectorCoBx.setMRMLScene(slicer.mrmlScene) self.inputSelectorCoBx.setToolTip( "select an .stl file as the input segmentation") self.mainFormLayout.addRow("Input segmentation: ", self.inputSelectorCoBx) # Create button to show mesh of InputNode self.showMeshBtn = qt.QPushButton("Show Mesh") self.showMeshBtn.setFixedHeight(20) self.showMeshBtn.setFixedWidth(100) self.showMeshBtn.setStyleSheet( "QPushButton{ background-color: DarkSeaGreen }") self.showMeshBtn.toolTip = ( 'How to use:' ' Click the Show Mesh Button to show mesh of Input Segmentation ') self.showMeshBtn.connect('clicked(bool)', self.onShowBtnClick) self.mainFormLayout.addRow("Input Segmentation: ", self.showMeshBtn) # Create button to set visibility to 1 of inputNode self.showBtn = qt.QPushButton("Show Input") self.showBtn.setFixedHeight(20) self.showBtn.setFixedWidth(100) self.showBtn.setStyleSheet( "QPushButton{ background-color: DarkSeaGreen }") self.showBtn.toolTip = ( 'How to use:' ' Click the Show Mesh Button to show Input Segmentation ') self.showBtn.connect('clicked(bool)', self.onInputBtnClick) self.mainFormLayout.addRow("Input Segmentation: ", self.showBtn) # ---------------------------------------INSTANT MESHING-------------------------------------------- # Create collapsible Button for Instant-Meshing options self.instantCollapsibleBtn = ctk.ctkCollapsibleButton() self.instantCollapsibleBtn.text = "Instant-Meshing" self.layout.addWidget(self.instantCollapsibleBtn) self.instantFormLayout = qt.QFormLayout(self.instantCollapsibleBtn) self.instantCollapsibleBtn.connect('clicked(bool)', self.onInstantClick) # Create button to run the Instant-Meshing tool self.imBtn = qt.QPushButton("Run") self.imBtn.setFixedHeight(40) self.imBtn.setFixedWidth(100) self.imBtn.setStyleSheet( "QPushButton{ background-color: DarkSeaGreen }") self.imBtn.toolTip = ( 'How to use:' ' Click the Run Button to start instant-meshing ') self.imBtn.connect('clicked(bool)', self.onImBtnClick) self.instantFormLayout.addRow(self.imBtn, self.imtimeLbl) # Create check box to display normals self.checkshowNormals = qt.QCheckBox() self.checkshowNormals.checked = False self.checkshowNormals.toolTip = ('If activated:' ' shows normals ') self.checkshowNormals.stateChanged.connect( self.onCheckShowNormalsChkBx) self.instantFormLayout.addRow( " Show normals: ", self.checkshowNormals) # ---------------------------------------ADVANCED USER OPTIONS-------------------------------------------- # Create group box for advanced user options self.instantCollapsiblegroupBtn = ctk.ctkCollapsibleGroupBox() self.instantCollapsiblegroupBtn.title = "Advanced Options" self.layout.addWidget(self.instantCollapsiblegroupBtn) self.instantCollapsiblegroupBtn.collapsed = True self.instantFormLayout.addRow(self.instantCollapsiblegroupBtn) self.instantCGBFormLayout = qt.QFormLayout( self.instantCollapsiblegroupBtn) # Create radio buttons for triangle or quad meshing self.checkTR = qt.QRadioButton() self.checkTR.text = "Triangles (6/6)" self.checkTR.checked = True # use triangle meshing by default self.instantCGBFormLayout.addRow( "Orientation and Position Symmetry Type: ", self.checkTR) self.checkQD1 = qt.QRadioButton() self.checkQD1.text = "Quads (2/4)" self.instantCGBFormLayout.addRow( " ", self.checkQD1) self.checkQD2 = qt.QRadioButton() self.checkQD2.text = "Quads (4/4)" self.instantCGBFormLayout.addRow( " ", self.checkQD2) # Create check boxes for boolean values self.checkintrinsic = qt.QCheckBox() self.checkintrinsic.checked = False # use extrinsic by default self.checkintrinsic.toolTip = ( 'If activated:' ' Measures smoothness directly on the surface instead of natural alignment to surface features ' ) self.checkintrinsic.stateChanged.connect(self.oncheckint) self.instantCGBFormLayout.addRow("Intrinsic: ", self.checkintrinsic) self.checkdominant = qt.QCheckBox() self.checkdominant.checked = False self.checkdominant.toolTip = ( 'If activated:' ' Generates a tri/quad dominant mesh instead of a pure tri/quad mesh ' ) self.checkdominant.stateChanged.connect(self.oncheckdom) self.instantCGBFormLayout.addRow("Dominant: ", self.checkdominant) self.checkdetermin = qt.QCheckBox() self.checkdetermin.checked = False self.checkdetermin.toolTip = ( 'If activated:' ' Prefers (slower) deterministic algorithms ') self.checkdetermin.stateChanged.connect(self.oncheckdet) self.instantCGBFormLayout.addRow("Deterministic: ", self.checkdetermin) # Create slider widget to adjust face count (triangle), prior vertex count (to change back, change -f in cmd to -v) self.vertSlider = ctk.ctkSliderWidget() self.vertSlider.minimum = 1000 self.vertSlider.maximum = 10000 self.vertSlider.setFixedWidth(400) self.vertSlider.value = 2800 self.vertSlider.toolTip = ('What it changes:' ' Desired face count of the output mesh ') self.instantCGBFormLayout.addRow("Triangle count: ", self.vertSlider) # Create slider widget to adjust smoothing & ray tracing reprojection steps self.smoothraySlider = ctk.ctkSliderWidget() self.smoothraySlider.minimum = 0 self.smoothraySlider.maximum = 10 self.smoothraySlider.setFixedWidth(400) self.smoothraySlider.value = 2 self.smoothraySlider.toolTip = ( 'What it changes:' ' Number of smoothing & ray tracing reprojection steps (default: 2) ' ) self.instantCGBFormLayout.addRow("Smoothing Steps: ", self.smoothraySlider) # Create slider widget to adjust Point cloud mode self.knnSlider = ctk.ctkSliderWidget() self.knnSlider.minimum = 5 self.knnSlider.maximum = 20 self.knnSlider.setFixedWidth(400) self.knnSlider.value = 10 self.knnSlider.toolTip = ( 'Point cloud mode:' ' Number of adjacent points to consider (default: 10) ') self.instantCGBFormLayout.addRow("Adjacent Points: ", self.knnSlider) # Create slider widget to adjust Dihedral angle threshold self.angleSlider = ctk.ctkSliderWidget() self.angleSlider.minimum = -1 self.angleSlider.maximum = 90 self.angleSlider.setFixedWidth(400) self.angleSlider.value = -1 self.angleSlider.toolTip = ( 'What it changes:' ' Dihedral angle threshold for creases, -1 means sharp creases ') self.instantCGBFormLayout.addRow("Crease Angle: ", self.angleSlider) # ---------------------------------------ROBUST QUAD/HEX-DOMINANT MESHING-------------------------------------------- # Create collapsible Button for robust quad/hex-dominant meshing options self.quadhexCollapsibleBtn = ctk.ctkCollapsibleButton() self.quadhexCollapsibleBtn.text = "Robust Quad/Hex-dominant Meshing" self.layout.addWidget(self.quadhexCollapsibleBtn) self.quadhexCollapsibleBtn.collapsed = True self.quadhexFormLayout = qt.QFormLayout(self.quadhexCollapsibleBtn) self.quadhexCollapsibleBtn.connect('clicked(bool)', self.onQuadHexClick) # Create button to run the tool self.rmBtn = qt.QPushButton("Run") self.rmBtn.setFixedHeight(40) self.rmBtn.setFixedWidth(100) self.rmBtn.setStyleSheet( "QPushButton{ background-color: DarkSeaGreen }") self.rmBtn.toolTip = ( 'How to use:' ' Click the Run Button to start robust quad/hex-dominant meshing ') self.rmBtn.connect('clicked(bool)', self.onRmBtnClick) self.quadhexFormLayout.addRow(self.rmBtn, self.qhtimeLbl) # ---------------------------------------ADVANCED USER OPTIONS-------------------------------------------- # Create group box for advanced user options self.robustCollapsiblegroupBtn = ctk.ctkCollapsibleGroupBox() self.robustCollapsiblegroupBtn.title = "Advanced Options" self.layout.addWidget(self.robustCollapsiblegroupBtn) self.robustCollapsiblegroupBtn.collapsed = True self.quadhexFormLayout.addRow(self.robustCollapsiblegroupBtn) self.robustCGBFormLayout = qt.QFormLayout( self.robustCollapsiblegroupBtn) # Create radio buttons to adjust dimension self.checkdim2 = qt.QRadioButton() self.checkdim2.checked = True # use dimension 2 by default self.checkdim2.text = "2" self.robustCGBFormLayout.addRow("Dimension: ", self.checkdim2) # Create slider widget to adjust scale self.scaleSlider = ctk.ctkSliderWidget() self.scaleSlider.minimum = 2 self.scaleSlider.maximum = 10 self.scaleSlider.setFixedWidth(400) self.scaleSlider.value = 3 self.robustCGBFormLayout.addRow("Scale: ", self.scaleSlider) # Create slider widget to adjust smooth iterator self.smoothSlider = ctk.ctkSliderWidget() self.smoothSlider.minimum = 5 self.smoothSlider.maximum = 20 self.smoothSlider.setFixedWidth(400) self.smoothSlider.value = 10 self.robustCGBFormLayout.addRow("Smoothing iteration count: ", self.smoothSlider)
def open(self): # main dialog self.dialog = qt.QDialog(slicer.util.mainWindow()) self.dialog.setWindowTitle('Export to DICOM Study') self.dialog.setWindowModality(1) layout = qt.QVBoxLayout() self.dialog.setLayout(layout) self.studyLabel = qt.QLabel('Attach Data to Study: %s' % self.studyUID) layout.addWidget(self.studyLabel) # scene or volume option self.selectFrame = qt.QFrame(self.dialog) layout.addWidget(self.selectFrame) self.selectLayout = qt.QGridLayout() self.selectFrame.setLayout(self.selectLayout) self.exportScene = qt.QRadioButton("Export Entire Scene", self.selectFrame) self.exportScene.setToolTip( "Create a Slicer Data Bundle in a DICOM Private Creator\n(Only compatible with Slicer)" ) self.exportVolume = qt.QRadioButton("Export Selected Volume", self.selectFrame) self.exportVolume.setToolTip( "Create a compatible DICOM series of slice images") self.exportVolume.checked = True self.selectLayout.addWidget(self.exportScene, 0, 0) self.selectLayout.addWidget(self.exportVolume, 1, 0) self.exportScene.connect('toggled(bool)', self.onExportRadio) self.exportVolume.connect('toggled(bool)', self.onExportRadio) # select volume self.volumeSelector = slicer.qMRMLNodeComboBox(self.dialog) self.volumeSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "") self.volumeSelector.selectNodeUponCreation = False self.volumeSelector.addEnabled = False self.volumeSelector.noneEnabled = False self.volumeSelector.removeEnabled = False self.volumeSelector.showHidden = False self.volumeSelector.showChildNodeTypes = False self.volumeSelector.setMRMLScene(slicer.mrmlScene) self.volumeSelector.setToolTip("Pick the label map to edit") self.selectLayout.addWidget(self.volumeSelector, 1, 1) # DICOM Parameters self.dicomFrame = qt.QFrame(self.dialog) self.dicomFormLayout = qt.QFormLayout() self.dicomFrame.setLayout(self.dicomFormLayout) self.dicomEntries = {} exporter = DICOMLib.DICOMExporter(self.studyUID) self.dicomParameters = exporter.parametersFromStudy() self.dicomParameters['Series Description'] = '3D Slicer Export' for label in self.dicomParameters.keys(): self.dicomEntries[label] = qt.QLineEdit() self.dicomEntries[label].text = self.dicomParameters[label] self.dicomFormLayout.addRow(label + ": ", self.dicomEntries[label]) layout.addWidget(self.dicomFrame) # button box bbox = qt.QDialogButtonBox(self.dialog) bbox.addButton(bbox.Ok) bbox.addButton(bbox.Cancel) bbox.connect('accepted()', self.onOk) bbox.connect('rejected()', self.onCancel) layout.addWidget(bbox) self.dialog.open()
def setup(self): self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged) w = qt.QWidget() layout = qt.QGridLayout() w.setLayout(layout) self.layout.addWidget(w) w.show() self.layout = layout # create frames self.inputFrame = ctk.ctkCollapsibleButton() self.inputFrame.text = "Input" self.inputFrame.collapsed = 0 inputFrameLayout = qt.QFormLayout(self.inputFrame) self.layout.addWidget(self.inputFrame) self.ctrlFrame = ctk.ctkCollapsibleButton() self.ctrlFrame.text = "Frame control" self.ctrlFrame.collapsed = 0 ctrlFrameLayout = qt.QGridLayout(self.ctrlFrame) self.layout.addWidget(self.ctrlFrame) self.plotFrame = ctk.ctkCollapsibleButton() self.plotFrame.text = "Plotting" self.plotFrame.collapsed = 0 plotFrameLayout = qt.QGridLayout(self.plotFrame) self.layout.addWidget(self.plotFrame) self.plotSettingsFrame = ctk.ctkCollapsibleButton() self.plotSettingsFrame.text = "Settings" self.plotSettingsFrame.collapsed = 1 plotSettingsFrameLayout = qt.QGridLayout(self.plotSettingsFrame) plotFrameLayout.addWidget(self.plotSettingsFrame, 0, 1) label = qt.QLabel('Input multivolume') self.__mvSelector = slicer.qMRMLNodeComboBox() self.__mvSelector.nodeTypes = ['vtkMRMLMultiVolumeNode'] self.__mvSelector.setMRMLScene(slicer.mrmlScene) self.__mvSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged) self.__mvSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onInputChanged) self.__mvSelector.addEnabled = 0 inputFrameLayout.addRow(label, self.__mvSelector) label = qt.QLabel('Input secondary multivolume') self.fgSelector = slicer.qMRMLNodeComboBox() self.fgSelector.nodeTypes = ['vtkMRMLMultiVolumeNode'] self.fgSelector.setMRMLScene(slicer.mrmlScene) self.fgSelector.addEnabled = 0 self.fgSelector.noneEnabled = 1 self.fgSelector.toolTip = "Secondary multivolume will be used for the secondary \ plot in interactive charting. As an example, this can be used to overlay the \ curve obtained by fitting a model to the data" inputFrameLayout.addRow(label, self.fgSelector) # TODO: initialize the slider based on the contents of the labels array # slider to scroll over metadata stored in the vector container being explored self.__mdSlider = ctk.ctkSliderWidget() label = qt.QLabel('Current frame number') # "play" control self.playButton = qt.QPushButton('Play') self.playButton.toolTip = 'Iterate over multivolume frames' self.playButton.checkable = True ctrlFrameLayout.addWidget(label, 0, 0) ctrlFrameLayout.addWidget(self.__mdSlider, 0, 1) ctrlFrameLayout.addWidget(self.playButton, 0, 2) self.playButton.connect('toggled(bool)', self.onPlayButtonToggled) self.__mdSlider.connect('valueChanged(double)', self.onSliderChanged) label = qt.QLabel('Current frame copy') self.__vfSelector = slicer.qMRMLNodeComboBox() self.__vfSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__vfSelector.setMRMLScene(slicer.mrmlScene) self.__vfSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVFMRMLSceneChanged) self.__vfSelector.addEnabled = 1 self.__vfSelector.enabled = 0 # do not show "children" of vtkMRMLScalarVolumeNode self.__vfSelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode", \ "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"] self.extractFrame = False self.extractButton = qt.QPushButton('Enable current frame copying') self.extractButton.checkable = True self.extractButton.connect('toggled(bool)', self.onExtractFrameToggled) ctrlFrameLayout.addWidget(label, 1, 0) ctrlFrameLayout.addWidget(self.__vfSelector, 1, 1, 1, 2) ctrlFrameLayout.addWidget(self.extractButton, 2, 0, 1, 3) # initialize slice observers (from DataProbe.py) # keep list of pairs: [observee,tag] so they can be removed easily self.styleObserverTags = [] # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic self.sliceWidgetsPerStyle = {} self.refreshObservers() # label map for probing label = qt.QLabel('Probed label volume') self.__fSelector = slicer.qMRMLNodeComboBox() self.__fSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__fSelector.addAttribute('vtkMRMLScalarVolumeNode', 'LabelMap', '1') self.__fSelector.toolTip = 'Label map to be probed' self.__fSelector.setMRMLScene(slicer.mrmlScene) self.__fSelector.addEnabled = 0 self.chartButton = qt.QPushButton('Chart') self.chartButton.checkable = False self.chartButton.connect('clicked()', self.onChartRequested) plotSettingsFrameLayout.addWidget(label, 0, 0) plotSettingsFrameLayout.addWidget(self.__fSelector, 0, 1) plotSettingsFrameLayout.addWidget(self.chartButton, 0, 2) self.iCharting = qt.QPushButton() self.iCharting.text = 'Enable interactive charting' self.iCharting.checkable = True plotSettingsFrameLayout.addWidget(self.iCharting, 1, 0, 1, 3) self.iCharting.setChecked(True) self.iCharting.connect('toggled(bool)', self.onInteractiveChartingChanged) groupLabel = qt.QLabel('Interactive plotting mode:') self.iChartingMode = qt.QButtonGroup() self.iChartingIntensity = qt.QRadioButton('Signal intensity') #self.iChartingIntensity.tooltip = 'Plot range adjusted dynamically to the range over the time course for the selected pixel' self.iChartingIntensityFixedAxes = qt.QRadioButton( 'Fixed range intensity') #self.iChartingIntensityFixedAxes.tooltip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume" self.iChartingPercent = qt.QRadioButton('Percent change') #self.iChartingPercent.tooltip = 'Percent change relative to the average of the first N frames (parameter set below)' self.iChartingIntensity.setChecked(1) self.groupWidget = qt.QWidget() self.groupLayout = qt.QFormLayout(self.groupWidget) self.groupLayout.addRow(groupLabel) self.groupLayout.addRow(self.iChartingIntensity) self.groupLayout.addRow(self.iChartingIntensityFixedAxes) self.groupLayout.addRow(self.iChartingPercent) self.baselineFrames = qt.QSpinBox() self.baselineFrames.minimum = 1 label = qt.QLabel('Number of frames for baseline calculation') self.groupLayout.addRow(label, self.baselineFrames) self.xLogScaleCheckBox = qt.QCheckBox() self.xLogScaleCheckBox.setChecked(0) label = qt.QLabel('Use log scale for X axis') self.groupLayout.addRow(self.xLogScaleCheckBox, label) self.xLogScaleCheckBox.connect('stateChanged(int)', self.onXLogScaleRequested) self.yLogScaleCheckBox = qt.QCheckBox() self.yLogScaleCheckBox.setChecked(0) label = qt.QLabel('Use log scale for Y axis') self.groupLayout.addRow(self.yLogScaleCheckBox, label) self.yLogScaleCheckBox.connect('stateChanged(int)', self.onYLogScaleRequested) plotSettingsFrameLayout.addWidget(self.groupWidget, 2, 0) # add chart container widget self.__chartView = ctk.ctkVTKChartView(w) plotFrameLayout.addWidget(self.__chartView, 3, 0, 1, 3) self.__chart = self.__chartView.chart() self.__chartTable = vtk.vtkTable() self.__xArray = vtk.vtkFloatArray() self.__yArray = vtk.vtkFloatArray() # will crash if there is no name self.__xArray.SetName('') self.__yArray.SetName('signal intensity') self.__chartTable.AddColumn(self.__xArray) self.__chartTable.AddColumn(self.__yArray)
def setup(self): """This is called one time when the module GUI is initialized """ ScriptedLoadableModuleWidget.setup(self) # Create objects that can be used anywhere in the module. Example: in most cases there should be just one # object of the logic class self.logic = CIP_PAARatioLogic() # # Create all the widgets. Example Area mainAreaCollapsibleButton = ctk.ctkCollapsibleButton() mainAreaCollapsibleButton.text = "Main parameters" self.layout.addWidget(mainAreaCollapsibleButton) self.mainAreaLayout = qt.QGridLayout(mainAreaCollapsibleButton) self.label = qt.QLabel("Select the volume") self.label.setStyleSheet("margin:10px 0 20px 7px") self.mainAreaLayout.addWidget(self.label, 0, 0) self.volumeSelector = slicer.qMRMLNodeComboBox() self.volumeSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "") # DEPRECATED. Now there is a new vtkMRMLLabelMapNode #self.volumeSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", "0" ) # No labelmaps self.volumeSelector.selectNodeUponCreation = True self.volumeSelector.autoFillBackground = True self.volumeSelector.addEnabled = True self.volumeSelector.noneEnabled = False self.volumeSelector.removeEnabled = False self.volumeSelector.showHidden = False self.volumeSelector.showChildNodeTypes = False self.volumeSelector.setMRMLScene(slicer.mrmlScene) self.volumeSelector.setStyleSheet( "margin:0px 0 0px 0; padding:2px 0 2px 5px") self.mainAreaLayout.addWidget(self.volumeSelector, 0, 1) # self.label2 = qt.QLabel("Select the slice") # self.label2.setStyleSheet("margin:0px 0 20px 7px; padding-top:20px") # self.mainAreaLayout.addWidget(self.label2, 1, 0) self.placeDefaultRulersButton = ctk.ctkPushButton() self.placeDefaultRulersButton.text = "Place default rulers" # self.placeDefaultRulersSliceButton.toolTip = "Navigate to the best estimated slice to place the rulers" self.placeDefaultRulersButton.setIcon( qt.QIcon("{0}/next.png".format(SlicerUtil.CIP_ICON_DIR))) self.placeDefaultRulersButton.setIconSize(qt.QSize(20, 20)) self.placeDefaultRulersButton.setStyleSheet("font-weight: bold;") # self.placeDefaultRulersButton.setFixedWidth(140) self.mainAreaLayout.addWidget(self.placeDefaultRulersButton, 1, 1) ### Structure Selector self.structuresGroupbox = qt.QGroupBox("Select the structure") self.groupboxLayout = qt.QVBoxLayout() self.structuresGroupbox.setLayout(self.groupboxLayout) self.mainAreaLayout.addWidget(self.structuresGroupbox, 2, 0) self.structuresButtonGroup = qt.QButtonGroup() # btn = qt.QRadioButton("None") # btn.visible = False # self.structuresButtonGroup.addButton(btn) # self.groupboxLayout.addWidget(btn) btn = qt.QRadioButton("Both") btn.checked = True self.structuresButtonGroup.addButton(btn, 0) self.groupboxLayout.addWidget(btn) btn = qt.QRadioButton("Pulmonary Arterial") self.structuresButtonGroup.addButton(btn, 1) self.groupboxLayout.addWidget(btn) btn = qt.QRadioButton("Aorta") self.structuresButtonGroup.addButton(btn, 2) self.groupboxLayout.addWidget(btn) ### Buttons toolbox self.buttonsToolboxFrame = qt.QFrame() self.buttonsToolboxLayout = qt.QGridLayout() self.buttonsToolboxFrame.setLayout(self.buttonsToolboxLayout) self.mainAreaLayout.addWidget(self.buttonsToolboxFrame, 2, 1) self.placeRulersButton = ctk.ctkPushButton() self.placeRulersButton.text = "Place ruler/s" self.placeRulersButton.toolTip = "Place the ruler/s for the selected structure/s in the current slice" self.placeRulersButton.setIcon( qt.QIcon("{0}/ruler.png".format(SlicerUtil.CIP_ICON_DIR))) self.placeRulersButton.setIconSize(qt.QSize(20, 20)) self.placeRulersButton.setFixedWidth(105) self.placeRulersButton.setStyleSheet("font-weight:bold") self.buttonsToolboxLayout.addWidget(self.placeRulersButton, 0, 0) self.moveUpButton = ctk.ctkPushButton() self.moveUpButton.text = "Move up" self.moveUpButton.toolTip = "Move the selected ruler/s one slice up" self.moveUpButton.setIcon( qt.QIcon("{0}/move_up.png".format(SlicerUtil.CIP_ICON_DIR))) self.moveUpButton.setIconSize(qt.QSize(20, 20)) self.moveUpButton.setFixedWidth(95) self.buttonsToolboxLayout.addWidget(self.moveUpButton, 0, 1) self.moveDownButton = ctk.ctkPushButton() self.moveDownButton.text = "Move down" self.moveDownButton.toolTip = "Move the selected ruler/s one slice down" self.moveDownButton.setIcon( qt.QIcon("{0}/move_down.png".format(SlicerUtil.CIP_ICON_DIR))) self.moveDownButton.setIconSize(qt.QSize(20, 20)) self.moveDownButton.setFixedWidth(95) self.buttonsToolboxLayout.addWidget(self.moveDownButton, 0, 2) self.removeButton = ctk.ctkPushButton() self.removeButton.text = "Remove ALL rulers" self.removeButton.toolTip = "Remove all the rulers for this volume" self.removeButton.setIcon( qt.QIcon("{0}/delete.png".format(SlicerUtil.CIP_ICON_DIR))) self.removeButton.setIconSize(qt.QSize(20, 20)) self.buttonsToolboxLayout.addWidget(self.removeButton, 1, 1, 1, 2, 2) ### Textboxes self.textboxesFrame = qt.QFrame() self.textboxesLayout = qt.QFormLayout() self.textboxesFrame.setLayout(self.textboxesLayout) self.textboxesFrame.setFixedWidth(190) self.mainAreaLayout.addWidget(self.textboxesFrame, 3, 0) self.paTextBox = qt.QLineEdit() self.paTextBox.setReadOnly(True) self.textboxesLayout.addRow("PA (mm): ", self.paTextBox) self.aortaTextBox = qt.QLineEdit() self.aortaTextBox.setReadOnly(True) self.textboxesLayout.addRow("Aorta (mm): ", self.aortaTextBox) self.ratioTextBox = qt.QLineEdit() self.ratioTextBox.setReadOnly(True) self.textboxesLayout.addRow("Ratio PA/A: ", self.ratioTextBox) # Save case data self.reportsCollapsibleButton = ctk.ctkCollapsibleButton() self.reportsCollapsibleButton.text = "Reporting" self.layout.addWidget(self.reportsCollapsibleButton) self.reportsLayout = qt.QHBoxLayout(self.reportsCollapsibleButton) self.storedColumnNames = [ "caseId", "paDiameter_mm", "aortaDiameter_mm", "pa1r", "pa1a", "pa1s", "pa2r", "pa2a", "pa2s", "a1r", "a1a", "a1s", "a2r", "a2a", "a2s" ] self.reportsWidget = CaseReportsWidget( "CIP_PAARatio", columnNames=self.storedColumnNames, parentWidget=self.reportsCollapsibleButton) self.reportsWidget.setup() self.switchToRedView() ##### # Case navigator if SlicerUtil.isSlicerACILLoaded(): caseNavigatorAreaCollapsibleButton = ctk.ctkCollapsibleButton() caseNavigatorAreaCollapsibleButton.text = "Case navigator" self.layout.addWidget(caseNavigatorAreaCollapsibleButton, 0x0020) # caseNavigatorLayout = qt.QVBoxLayout(caseNavigatorAreaCollapsibleButton) # Add a case list navigator from ACIL.ui import CaseNavigatorWidget self.caseNavigatorWidget = CaseNavigatorWidget( self.moduleName, caseNavigatorAreaCollapsibleButton) self.caseNavigatorWidget.setup() self.layout.addStretch() # Connections self.observers = [] self.__addSceneObservables__() self.volumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onVolumeSelectorChanged) self.placeDefaultRulersButton.connect('clicked()', self.oPlaceDefaultRulersClicked) self.placeRulersButton.connect('clicked()', self.onPlaceRulersClicked) self.moveUpButton.connect('clicked()', self.onMoveUpRulerClicked) self.moveDownButton.connect('clicked()', self.onMoveDownRulerClicked) self.removeButton.connect('clicked()', self.onRemoveRulerClicked) self.reportsWidget.addObservable( self.reportsWidget.EVENT_SAVE_BUTTON_CLICKED, self.onSaveReport)
def setup(self, wName, parent): if self.ctrlWidget: return self.LinkViewers() self.numFrames = len(self.nodeImgList[0][0]) if parent: self.ctrlWidget = parent else: # Create seperate window self.ctrlWidget = slicer.qMRMLWidget() self.ctrlWidget.setMRMLScene(slicer.mrmlScene) self.ctrlWidget.setLayout(qt.QFormLayout()) self.ctrlWidget.setWindowTitle(wName) ctrlLayout = self.ctrlWidget.layout() # Create Slider Panel self.sliderPanel = qt.QWidget() self.sliderPanel.setLayout(qt.QGridLayout()) ctrlLayout.addWidget(self.sliderPanel) sliderLayout = self.sliderPanel.layout() if self.numFrames > 1: self.ctrlFrameLabel = qt.QLabel('Frame') self.ctrlFrameSlider = ctk.ctkSliderWidget() self.ctrlFrameSlider.connect('valueChanged(double)', self.onSliderFrameChanged) sliderLayout.addWidget(self.ctrlFrameLabel, 0, 0) sliderLayout.addWidget(self.ctrlFrameSlider, 0, 1) self.ctrlLevelLabel = qt.QLabel('Level') self.ctrlLevelSlider = ctk.ctkSliderWidget() self.ctrlLevelSlider.connect('valueChanged(double)', self.onSliderLevelChanged) sliderLayout.addWidget(self.ctrlLevelLabel, 1, 0) sliderLayout.addWidget(self.ctrlLevelSlider, 1, 1) self.ctrlWindowLabel = qt.QLabel('Window') self.ctrlWindowSlider = ctk.ctkSliderWidget() self.ctrlWindowSlider.connect('valueChanged(double)', self.onSliderWindowChanged) sliderLayout.addWidget(self.ctrlWindowLabel, 2, 0) sliderLayout.addWidget(self.ctrlWindowSlider, 2, 1) self.setSliderRangesAndValues() if self.sliceNodeList: self.orientPanel = qt.QWidget() self.orientPanel.setLayout(qt.QGridLayout()) ctrlLayout.addWidget(self.orientPanel) self.orientationButtons = {} index = 0 for orientation in self.orientations: self.orientationButtons[orientation] = qt.QRadioButton() self.orientationButtons[orientation].text = orientation # self.orientationBox.layout().addWidget(self.orientationButtons[orientation]) self.orientPanel.layout().addWidget( self.orientationButtons[orientation], 0, index) self.orientationButtons[orientation].connect( "clicked()", lambda o=orientation: self.setOrientation(o)) index += 1 self.setOrientation(self.selectedOrientation) if False: #self.plotFrame = ctk.ctkCollapsibleButton() #self.plotFrame.text = "Plotting" #self.plotFrame.collapsed = 0 self.plotFrame = qt.QWidget() plotFrameLayout = qt.QGridLayout(self.plotFrame) ctrlLayout.addWidget(self.plotFrame) self.plotSettingsFrame = ctk.ctkCollapsibleButton() self.plotSettingsFrame.text = "Settings" self.plotSettingsFrame.collapsed = 1 plotSettingsFrameLayout = qt.QGridLayout(self.plotSettingsFrame) #plotFrameLayout.addWidget(self.plotSettingsFrame,0,1) self.xLogScaleCheckBox = qt.QCheckBox() self.xLogScaleCheckBox.setChecked(0) self.yLogScaleCheckBox = qt.QCheckBox() self.yLogScaleCheckBox.setChecked(0) # taken from https://github.com/fedorov/MultiVolumeExplorer self.__chartView = ctk.ctkVTKChartView(self.ctrlWidget) # self.plotFrame) # self.ctrlWidget plotFrameLayout.addWidget(self.__chartView, 0, 0) self.__chart = self.__chartView.chart() self.__chartTable = vtk.vtkTable() self.__xArray = vtk.vtkFloatArray() self.__yArray = vtk.vtkFloatArray() # will crash if there is no name self.__xArray.SetName('') self.__yArray.SetName('signal intensity') self.__chartTable.AddColumn(self.__xArray) self.__chartTable.AddColumn(self.__yArray) self.onInputChanged() self.refreshObservers() self.buttonPanel = qt.QWidget() self.buttonPanel.setLayout(qt.QGridLayout()) ctrlLayout.addWidget(self.buttonPanel) self.exitButton = qt.QPushButton("Exit") self.exitButton.toolTip = "Close down slicer." self.exitButton.name = "sviewer exit" self.buttonPanel.layout().addWidget(self.exitButton, 0, 0) self.exitButton.connect('clicked()', exit) # do not do ctrlWin.show() here - for some reason window does not pop up then return self.ctrlWidget
def createUserInterface(self): """ As of now, this user interface is fairly simple. If there are other methods of normalization, they could be added here. """ self.__layout = self.__parent.createUserInterface() step_label = qt.QLabel( """Normalize intensities between your two images before subtracting them.""" ) step_label.setWordWrap(True) self.__primaryGroupBox = qt.QGroupBox() self.__primaryGroupBox.setTitle('Information') self.__primaryGroupBoxLayout = qt.QFormLayout(self.__primaryGroupBox) self.__primaryGroupBoxLayout.addRow(step_label) self.__layout.addRow(self.__primaryGroupBox) # Normalization methods - there aren't many now, but there may be in the future. NormGroupBox = qt.QGroupBox() NormGroupBox.setTitle('Normalization Methods') self.__layout.addRow(NormGroupBox) NormGroupBoxLayout = qt.QFormLayout(NormGroupBox) self.__normalizationButton = qt.QPushButton( 'Run Gaussian Normalization') NormGroupBoxLayout.addRow(self.__normalizationButton) self.__normalizationButton.connect('clicked()', self.onGaussianNormalizationRequest) self.__normalizationButton.setEnabled(1) # Create new volumes options. self.__OutputRadio1 = qt.QRadioButton("Create new volumes.") self.__OutputRadio1.toolTip = "New volumes will be created with the naming convention \"[vol]_normalized\"." NormGroupBoxLayout.addRow(self.__OutputRadio1) self.__OutputRadio1.setChecked(True) self.__OutputRadio2 = qt.QRadioButton("Replace existing volumes.") self.__OutputRadio2.toolTip = "Original volumes will be overwritten at the end of this step." NormGroupBoxLayout.addRow(self.__OutputRadio2) # Normalization order options. May not be relevant in every case. OrderGroupBox = qt.QGroupBox() OrderGroupBox.setTitle('Normalization Order') self.__layout.addRow(OrderGroupBox) OrderGroupBoxLayout = qt.QFormLayout(OrderGroupBox) self.__OrderRadio1 = qt.QRadioButton( "Normalize pre-contrast to post-contrast.") self.__OrderRadio1.toolTip = "Your pre-contrast image will be normalized." OrderGroupBoxLayout.addRow(self.__OrderRadio1) self.__OrderRadio1.setChecked(True) self.__OrderRadio2 = qt.QRadioButton( "Normalize post-contrast to pre-contrast.") self.__OrderRadio2.toolTip = "Your post-contrast image will be normalized." OrderGroupBoxLayout.addRow(self.__OrderRadio2) # Subtraction methods. Likely only one method, in practice. SubtractGroupBox = qt.QGroupBox() SubtractGroupBox.setTitle('Calculate Subtraction Map') self.__layout.addRow(SubtractGroupBox) SubtractGroupBoxLayout = qt.QFormLayout(SubtractGroupBox) self.__subtractionButton = qt.QPushButton('Run Subtraction Algorithm') SubtractGroupBoxLayout.addRow(self.__subtractionButton) self.__subtractionButton.connect('clicked()', self.onSubtractionRequest) self.__subtractionButton.setEnabled(1)
def setup(self): # intialize variables # Data of current loaded patient self.IDcurrPatient = {} self.imageNodes = {} # List of currently loaded image nodes self.labelNodes = {} # List of currently loaded label nodes self.ModelNodes = {} # Data of database self.mainPatientdir = self.outputDir = self.datafile = {} #--------------------------------------------------------- # 2D Slice Snapshots self.IMGSliceExtractCollapsibleButton = ctk.ctkCollapsibleButton() self.IMGSliceExtractCollapsibleButton.text = "2D Slice and Model Image Capture" self.layout.addWidget(self.IMGSliceExtractCollapsibleButton) self.IMGSliceExtractCollapsibleButton.collapsed = False self.IMGSliceExtractFormLayout = qt.QFormLayout( self.IMGSliceExtractCollapsibleButton) # Input 1: Input Directory selector self.input6Frame = qt.QFrame(self.IMGSliceExtractCollapsibleButton) self.input6Frame.setLayout(qt.QHBoxLayout()) self.IMGSliceExtractFormLayout.addWidget(self.input6Frame) self.input6Selector = qt.QLabel("Input Directory (DICOM): ", self.input6Frame) self.input6Frame.layout().addWidget(self.input6Selector) self.input6Button = qt.QPushButton("Select main directory DICOM files") self.input6Button.toolTip = "Select main directory with DICOM files (folder names are patient names)" self.input6Button.enabled = True self.input6Frame.layout().addWidget(self.input6Button) # Input 2: Output Directory selector self.input7Frame = qt.QFrame(self.IMGSliceExtractCollapsibleButton) self.input7Frame.setLayout(qt.QHBoxLayout()) self.IMGSliceExtractFormLayout.addWidget(self.input7Frame) self.input7Selector = qt.QLabel("Output Directory: ", self.input7Frame) self.input7Frame.layout().addWidget(self.input7Selector) self.input7Button = qt.QPushButton( "Select main directory output NRRD or NFITI files") self.input7Button.toolTip = "Select main directory for output NRRD or NIFTI files (folder names are patient names)" self.input7Button.enabled = True self.input7Frame.layout().addWidget(self.input7Button) # Keywords Collapsible Button self.KeywordsCollapsibleButton = ctk.ctkCollapsibleButton( self.IMGSliceExtractCollapsibleButton) self.KeywordsCollapsibleButton.text = "Keyword Matching" self.KeywordsCollapsibleButtonLayout = qt.QHBoxLayout() self.KeywordsCollapsibleButton.setLayout( self.KeywordsCollapsibleButtonLayout) self.IMGSliceExtractFormLayout.addWidget( self.KeywordsCollapsibleButton) self.KeywordsCollapsibleButton.collapsed = False self.keywordsFrame = qt.QFrame(self.KeywordsCollapsibleButton) self.keywordsFrame.setLayout(qt.QFormLayout()) self.KeywordsCollapsibleButtonLayout.addWidget(self.keywordsFrame) # Radio Buttons Frame self.radioButtonFrame = qt.QFrame(self.keywordsFrame) self.radioButtonFrame.setLayout(qt.QFormLayout()) self.fileFormatGroup = qt.QButtonGroup(self.radioButtonFrame) self.nrrdButton = qt.QRadioButton("NRRD") self.nrrdButton.checked = True self.niftiButton = qt.QRadioButton("NIFTI") self.fileFormatGroup.addButton(self.nrrdButton) self.fileFormatGroup.addButton(self.niftiButton) self.radioButtonFrame.layout().addRow(self.nrrdButton, self.niftiButton) self.keywordsHeader = qt.QLabel("Keyword Matching:", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.keywordsHeader) # Keywords Frame self.inputMaskHeader = qt.QLabel("Input Image File Type:", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputMaskHeader, self.radioButtonFrame) self.inputImageKeywords = qt.QLabel("Input Image Keywords:", self.keywordsFrame) self.inputImageKeywordsField = qt.QLineEdit("", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputImageKeywords, self.inputImageKeywordsField) self.inputImageExclusionKeywords = qt.QLabel( "Input Image Exclusion Keywords:", self.keywordsFrame) self.inputImageExclusionKeywordsField = qt.QLineEdit( "", self.keywordsFrame) self.keywordsFrame.layout().addRow( self.inputImageExclusionKeywords, self.inputImageExclusionKeywordsField) self.inputLabelKeywords = qt.QLabel("Input Label Keywords:", self.keywordsFrame) self.inputLabelKeywordsField = qt.QLineEdit("", self.keywordsFrame) self.keywordsFrame.layout().addRow(self.inputLabelKeywords, self.inputLabelKeywordsField) self.inputLabelExclusionKeywords = qt.QLabel( "Input Label Exclusion Keywords:", self.keywordsFrame) self.inputLabelExclusionKeywordsField = qt.QLineEdit( "", self.keywordsFrame) self.keywordsFrame.layout().addRow( self.inputLabelExclusionKeywords, self.inputLabelExclusionKeywordsField) # IMG Slice Extract Button self.IMGSliceExtractButton = qt.QPushButton("Extract Images") self.IMGSliceExtractFormLayout.addWidget(self.IMGSliceExtractButton) #--------------------------------------------------------- # Connections self.input6Button.connect('clicked(bool)', self.onInput6Button) self.input7Button.connect('clicked(bool)', self.onInput7Button) self.IMGSliceExtractButton.connect('clicked(bool)', self.onIMGSliceExtract)
def create(self): super(PETTumorSegmentationEffectOptions, self).create() #Save space in the GUI self.frame.layout().setSpacing(0) self.frame.layout().setMargin(0) # refinementBoxesFrame contains the options for how clicks are handled self.refinementBoxesFrame = qt.QFrame(self.frame) self.refinementBoxesFrame.setLayout(qt.QHBoxLayout()) self.refinementBoxesFrame.layout().setSpacing(0) self.refinementBoxesFrame.layout().setMargin(0) self.frame.layout().addWidget(self.refinementBoxesFrame) #default is global refinement (threshold refinement) self.noRefinementRadioButton = qt.QRadioButton( "Create new", self.refinementBoxesFrame) self.noRefinementRadioButton.setToolTip( "On click, always segment a new object.") self.globalRefinementRadioButton = qt.QRadioButton( "Global refinement", self.refinementBoxesFrame) self.globalRefinementRadioButton.setToolTip( "On click, refine globally (adjusting then entire boundary) if no center point for the label, otherwise segment a new object." ) self.localRefinementRadioButton = qt.QRadioButton( "Local refinement", self.refinementBoxesFrame) self.localRefinementRadioButton.setToolTip( "On click, refine locally (adjusting part of the boundary) if no center point for the label, otherwise segment a new object." ) self.globalRefinementRadioButton.setChecked(True) #radio button so only one can be applied self.refinementBoxesFrame.layout().addWidget( qt.QLabel("Interaction style: ", self.refinementBoxesFrame)) self.refinementBoxesFrame.layout().addWidget( self.noRefinementRadioButton) self.refinementBoxesFrame.layout().addWidget( self.globalRefinementRadioButton) self.refinementBoxesFrame.layout().addWidget( self.localRefinementRadioButton) self.refinementBoxesFrame.layout().addStretch(1) self.widgets.append(self.noRefinementRadioButton) self.widgets.append(self.globalRefinementRadioButton) self.widgets.append(self.localRefinementRadioButton) self.noRefinementRadioButton.connect('clicked()', self.onRefinementTypeChanged) self.localRefinementRadioButton.connect('clicked()', self.onRefinementTypeChanged) self.globalRefinementRadioButton.connect('clicked()', self.onRefinementTypeChanged) #options are hidden (collapsed) until requested self.optFrame = ctk.ctkCollapsibleButton(self.frame) self.optFrame.setText("Options") self.optFrame.setLayout(qt.QVBoxLayout()) self.optFrame.layout().setSpacing(0) self.optFrame.layout().setMargin(0) self.optFrame.visible = True self.optFrame.collapsed = True self.optFrame.collapsedHeight = 0 self.optFrame.setToolTip("Displays algorithm options.") #most useful options are kept on top: Splitting, Sealing, Assist Centering, Allow # Overwriting #to save vertical space, put 2 ina row, so subframes here with horizontal layout are used #first row self.commonCheckBoxesFrame1 = qt.QFrame(self.optFrame) self.commonCheckBoxesFrame1.setLayout(qt.QHBoxLayout()) self.commonCheckBoxesFrame1.layout().setSpacing(0) self.commonCheckBoxesFrame1.layout().setMargin(0) self.optFrame.layout().addWidget(self.commonCheckBoxesFrame1) #top left self.splittingCheckBox = qt.QCheckBox("Splitting", self.commonCheckBoxesFrame1) self.splittingCheckBox.setToolTip( "Cut off adjacent objects to the target via watershed or local minimum. Useful for lymph node chains." ) self.splittingCheckBox.checked = False self.commonCheckBoxesFrame1.layout().addWidget(self.splittingCheckBox) self.widgets.append(self.splittingCheckBox) #top right self.sealingCheckBox = qt.QCheckBox("Sealing", self.commonCheckBoxesFrame1) self.sealingCheckBox.setToolTip( "Close single-voxel gaps in the object or between the object and other objects, if above the threshold. Useful for lymph node chains." ) self.sealingCheckBox.checked = False self.commonCheckBoxesFrame1.layout().addWidget(self.sealingCheckBox) self.widgets.append(self.sealingCheckBox) #second row self.commonCheckBoxesFrame2 = qt.QFrame(self.optFrame) self.commonCheckBoxesFrame2.setLayout(qt.QHBoxLayout()) self.commonCheckBoxesFrame2.layout().setSpacing(0) self.commonCheckBoxesFrame2.layout().setMargin(0) self.optFrame.layout().addWidget(self.commonCheckBoxesFrame2) #bottom left self.assistCenteringCheckBox = qt.QCheckBox( "Assist Centering", self.commonCheckBoxesFrame2) self.assistCenteringCheckBox.setToolTip( "Move the center to the highest voxel within 7 physical units, without being on or next to other object labels. Improves consistency." ) self.assistCenteringCheckBox.checked = True self.commonCheckBoxesFrame2.layout().addWidget( self.assistCenteringCheckBox) self.widgets.append(self.assistCenteringCheckBox) #bottom right self.allowOverwritingCheckBox = qt.QCheckBox( "Allow Overwriting", self.commonCheckBoxesFrame2) self.allowOverwritingCheckBox.setToolTip("Ignore other object labels.") self.allowOverwritingCheckBox.checked = False self.commonCheckBoxesFrame2.layout().addWidget( self.allowOverwritingCheckBox) self.widgets.append(self.allowOverwritingCheckBox) #advanced options, for abnormal cases such as massive necrotic objects or #low-transition scans like phantoms #infrequently used, just keep vertical self.advFrame = ctk.ctkCollapsibleButton(self.optFrame) self.advFrame.setText("Advanced") self.advFrame.setLayout(qt.QVBoxLayout()) self.advFrame.layout().setSpacing(0) self.advFrame.layout().setMargin(0) self.advFrame.visible = True self.advFrame.collapsed = True self.advFrame.collapsedHeight = 0 self.advFrame.setToolTip( "Displays more advanced algorithm options. Do not use if you don't know what they mean." ) #top self.necroticRegionCheckBox = qt.QCheckBox("Necrotic Region", self.advFrame) self.necroticRegionCheckBox.setToolTip( "Prevents cutoff from low uptake. Use if placing a center inside a necrotic region." ) self.necroticRegionCheckBox.checked = False self.advFrame.layout().addWidget(self.necroticRegionCheckBox) self.widgets.append(self.necroticRegionCheckBox) #middle self.denoiseThresholdCheckBox = qt.QCheckBox("Denoise Threshold", self.advFrame) self.denoiseThresholdCheckBox.setToolTip( "Calculates threshold based on median-filtered image. Use only if scan is very noisey." ) self.denoiseThresholdCheckBox.checked = False self.advFrame.layout().addWidget(self.denoiseThresholdCheckBox) self.widgets.append(self.denoiseThresholdCheckBox) #bottom self.linearCostCheckBox = qt.QCheckBox("Linear Cost", self.advFrame) self.linearCostCheckBox.setToolTip( "Cost function below threshold is linear rather than based on region. Use only if little/no transition region in uptake." ) self.linearCostCheckBox.checked = False self.advFrame.layout().addWidget(self.linearCostCheckBox) self.widgets.append(self.linearCostCheckBox) self.optFrame.layout().addWidget(self.advFrame) #apply button kept at bottom of all options self.applyButton = qt.QPushButton("Apply", self.optFrame) self.optFrame.layout().addWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApply) self.widgets.append(self.applyButton) self.applyButton.setToolTip( "Redo last segmentation with the same center and refinement points with any changes in options." ) #When changing settings, update the MRML with it self.assistCenteringCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.allowOverwritingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.splittingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.sealingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.necroticRegionCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.denoiseThresholdCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.linearCostCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.frame.layout().addWidget(self.optFrame) EditorLib.HelpButton( self.frame, "Click on a lesion in a PET scan to segment it. Depending on refinement settings, click again to refine globally and/or locally. Options may help deal with cases such as segmenting individual lesions in a chain. For more information: http://www.slicer.org/slicerWiki/index.php/Documentation/4.4/Modules/PETTumorSegmentationEffect" ) # Add vertical spacer self.frame.layout().addStretch(1) # Clear any existing data and undo/redo queue; working directly with other tools is # beyond the scope of this self.logic.reset() self.updateGUIFromMRML(self, 0)
def setup(self): """Init the widget """ self.modulePath = SlicerUtil.getModuleFolder("CIP_GetImage") self.resourcesPath = os.path.join(self.modulePath, "CIP_GetImage_Resources") self.StudyId = "" self.logic = CIP_GetImageLogic(self.modulePath) # Widget to load cases faster self.loadSaveDatabuttonsWidget = CIPUI.LoadSaveDataWidget( parentWidget=self.parent) self.loadSaveDatabuttonsWidget.setup(moduleName="CIP_GetImage") # # Obligatory parameters area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Image data" self.layout.addWidget(parametersCollapsibleButton) parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # Study radio buttons label = qt.QLabel() label.text = "Select the study:" parametersFormLayout.addRow(label) self.rbgStudy = qt.QButtonGroup() for key in self.studyIds: rbStudyid = qt.QRadioButton(key) self.rbgStudy.addButton(rbStudyid) parametersFormLayout.addWidget(rbStudyid) self.txtOtherStudy = qt.QLineEdit() self.txtOtherStudy.hide() parametersFormLayout.addWidget(self.txtOtherStudy) # Case id self.txtCaseId = qt.QLineEdit() parametersFormLayout.addRow("Case ID ", self.txtCaseId) # Image types label = qt.QLabel() label.text = "Select the images that you want to load:" parametersFormLayout.addRow(label) self.cbsImageTypes = [] for key in self.imageTypes: check = qt.QCheckBox() check.checked = True check.setText(key) parametersFormLayout.addWidget(check) self.cbsImageTypes.append(check) # Label maps label = qt.QLabel() label.text = "Select the label maps that you want to load:" parametersFormLayout.addRow(label) # Labelmap types checkboxes self.cbsLabelMapTypes = [] for key in self.labelMapTypes: check = qt.QCheckBox() check.setText(key) check.checked = self.labelMapTypes[key][0] parametersFormLayout.addWidget(check) self.cbsLabelMapTypes.append(check) # Load image Button self.downloadButton = qt.QPushButton("Download") self.downloadButton.toolTip = "Load the image" #self.downloadButton.enabled = False self.downloadButton.setStyleSheet( "background-color: green; font-weight:bold; color:white") parametersFormLayout.addRow(self.downloadButton) self.downloadButton.connect('clicked (bool)', self.onDownloadButton) # Information message self.lblDownloading = qt.QLabel() self.lblDownloading.text = "Downloading images. Please wait..." self.lblDownloading.hide() parametersFormLayout.addRow(self.lblDownloading) # # Optional Parameters # optionalParametersCollapsibleButton = ctk.ctkCollapsibleButton() optionalParametersCollapsibleButton.text = "Optional parameters" self.layout.addWidget(optionalParametersCollapsibleButton) optionalParametersFormLayout = qt.QFormLayout( optionalParametersCollapsibleButton) # Local storage (Slicer temporary path) self.localStoragePath = "{0}/CIP".format(slicer.app.temporaryPath) if not os.path.exists(self.localStoragePath): os.makedirs(self.localStoragePath) # Make sure that everybody has write permissions (sometimes there are problems because of umask) os.chmod(self.localStoragePath, 0o777) self.storagePathButton = ctk.ctkDirectoryButton() self.storagePathButton.directory = self.localStoragePath optionalParametersFormLayout.addRow("Local directory: ", self.storagePathButton) # Connection type (SSH, "normal") label = qt.QLabel() label.text = "Connection type:" optionalParametersFormLayout.addRow(label) self.rbgConnectionType = qt.QButtonGroup() self.rbSSH = qt.QRadioButton("SSH (secure connection)") self.rbSSH.setChecked(True) self.rbgConnectionType.addButton(self.rbSSH) optionalParametersFormLayout.addWidget(self.rbSSH) self.rbCP = qt.QRadioButton("Common") self.rbgConnectionType.addButton(self.rbCP) optionalParametersFormLayout.addWidget(self.rbCP) # SSH Server login self.txtServer = qt.QLineEdit() s = SlicerUtil.settingGetOrSetDefault( "CIP_GetImage", "server", "This is your ssh user and server. Example: [email protected]") self.txtServer.text = s # This is your ssh user and server. Example: [email protected]" optionalParametersFormLayout.addRow("Server:", self.txtServer) # Server root path self.txtServerpath = qt.QLineEdit() s = SlicerUtil.settingGetOrSetDefault( "CIP_GetImage", "serverRootPath", "This is your root path to search for files. Ex: /Cases/Processed") self.txtServerpath.text = s # This is your root path to search for files. Ex: /Cases/Processed optionalParametersFormLayout.addRow("Server root path:", self.txtServerpath) # SSH Private key self.txtPrivateKeySSH = qt.QLineEdit() s = SlicerUtil.settingGetOrSetDefault("CIP_GetImage", "sshKey", "") self.txtPrivateKeySSH.text = s # this is the full path to your ssh key if you need it. Be aware of Unix/Windows comaptibility (hint: use os.path.join) # Please notice that you won't need a SSH key if your computer already has one locally installed" optionalParametersFormLayout.addRow( "SSH private key (leave blank for computer's default): ", self.txtPrivateKeySSH) # Cache mode self.cbCacheMode = qt.QCheckBox("Cache mode activated") self.cbCacheMode.setChecked(True) # Cache mode is activated by default optionalParametersFormLayout.addRow("", self.cbCacheMode) # Clean cache Button self.cleanCacheButton = qt.QPushButton("Clean cache") self.cleanCacheButton.toolTip = "Remove all the local cached files" optionalParametersFormLayout.addRow(self.cleanCacheButton) optionalParametersCollapsibleButton.collapsed = True if SlicerUtil.IsDevelopment: # reload button self.reloadButton = qt.QPushButton("Reload (just development)") self.reloadButton.toolTip = "Reload this module (for development purposes)." self.reloadButton.name = "Reload" self.layout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # Add vertical spacer self.layout.addStretch(1) # Connections self.rbgStudy.connect("buttonClicked (QAbstractButton*)", self.onRbStudyClicked) self.txtOtherStudy.connect("textEdited (QString)", self.onTxtOtherStudyEdited) self.rbgConnectionType.connect("buttonClicked (QAbstractButton*)", self.onRbgConnectionType) self.storagePathButton.connect("directorySelected(QString)", self.onTmpDirChanged) self.cleanCacheButton.connect('clicked (bool)', self.onCleanCacheButtonClicked)
def setup(self): """Instantiate and connect widgets ...""" self.scene = slicer.mrmlScene self.icp = vtk.vtkIterativeClosestPointTransform() # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # 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 = "SurfaceICPRegistration Reload" reloadFormLayout.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." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # # Input Surface Volume Collapsible Button # inputSurfaceCollapsibleButton = ctk.ctkCollapsibleButton() inputSurfaceCollapsibleButton.text = "Input Surface Volumes" self.layout.addWidget(inputSurfaceCollapsibleButton) inputSurfaceFormLayout = qt.QFormLayout(inputSurfaceCollapsibleButton) # # Input Surface Volume Options # self.modelSelectors = {} self.viewNames = ("Fixed Surface Volume", "Moving Surface Volume") for viewName in self.viewNames: self.modelSelectors[viewName] = slicer.qMRMLNodeComboBox() self.modelSelectors[viewName].nodeTypes = (("vtkMRMLModelNode"), "") self.modelSelectors[viewName].selectNodeUponCreation = False self.modelSelectors[viewName].addEnabled = False self.modelSelectors[viewName].removeEnabled = True self.modelSelectors[viewName].noneEnabled = True self.modelSelectors[viewName].showHidden = False self.modelSelectors[viewName].showChildNodeTypes = True self.modelSelectors[viewName].setMRMLScene(slicer.mrmlScene) self.modelSelectors[viewName].setToolTip( "Pick the %s surface volume." % viewName.lower()) inputSurfaceFormLayout.addRow("%s" % viewName, self.modelSelectors[viewName]) # # Input Inicial Transform Options # self.volumeInitialTransformSelectors = {} self.volumeInitialTransformSelectors[ "Initial Transform"] = slicer.qMRMLNodeComboBox() self.volumeInitialTransformSelectors["Initial Transform"].nodeTypes = ( ("vtkMRMLLinearTransformNode"), "") self.volumeInitialTransformSelectors[ "Initial Transform"].selectNodeUponCreation = False self.volumeInitialTransformSelectors[ "Initial Transform"].addEnabled = False self.volumeInitialTransformSelectors[ "Initial Transform"].removeEnabled = True self.volumeInitialTransformSelectors[ "Initial Transform"].noneEnabled = True self.volumeInitialTransformSelectors[ "Initial Transform"].showHidden = False self.volumeInitialTransformSelectors[ "Initial Transform"].showChildNodeTypes = True self.volumeInitialTransformSelectors["Initial Transform"].setMRMLScene( slicer.mrmlScene) self.volumeInitialTransformSelectors["Initial Transform"].setToolTip( "Pick the initial Transform file") inputSurfaceFormLayout.addRow( "(Optional) Initial Transform", self.volumeInitialTransformSelectors["Initial Transform"]) # # Input Registration Parameters Collapsible Button # inputRegistrationParametersCollapsibleButton = ctk.ctkCollapsibleButton( ) inputRegistrationParametersCollapsibleButton.text = "Input Registration Parameters" self.layout.addWidget(inputRegistrationParametersCollapsibleButton) inputRegistrationParametersFormLayout = qt.QFormLayout( inputRegistrationParametersCollapsibleButton) # # Landmark Transform Mode TYPE SELECTION # - allows selection of the active registration type to display # self.landmarkTransformTypeBox = qt.QGroupBox("Landmark Transform Mode") self.landmarkTransformTypeBox.setLayout(qt.QFormLayout()) self.landmarkTransformTypeButtons = {} self.landmarkTransformTypes = ("RigidBody", "Similarity", "Affine") for landmarkTransformType in self.landmarkTransformTypes: self.landmarkTransformTypeButtons[ landmarkTransformType] = qt.QRadioButton() self.landmarkTransformTypeButtons[ landmarkTransformType].text = landmarkTransformType self.landmarkTransformTypeButtons[ landmarkTransformType].setToolTip( "Pick the type of registration") self.landmarkTransformTypeButtons[landmarkTransformType].connect( "clicked()", lambda t=landmarkTransformType: self.onLandmarkTrandformType(t )) self.landmarkTransformTypeBox.layout().addWidget( self.landmarkTransformTypeButtons[landmarkTransformType]) inputRegistrationParametersFormLayout.addWidget( self.landmarkTransformTypeBox) # # Mean Distance Mode TYPE SELECTION # self.meanDistanceTypeBox = qt.QGroupBox("Mean Distance Mode") self.meanDistanceTypeBox.setLayout(qt.QFormLayout()) self.meanDistanceTypeButtons = {} self.meanDistanceTypes = ("RMS", "Absolute Value") inputRegistrationParametersFormLayout.addWidget( self.landmarkTransformTypeBox) for meanDistanceType in self.meanDistanceTypes: self.meanDistanceTypeButtons[meanDistanceType] = qt.QRadioButton() self.meanDistanceTypeButtons[ meanDistanceType].text = meanDistanceType self.meanDistanceTypeButtons[meanDistanceType].setToolTip( "Pick the type of registration") self.meanDistanceTypeButtons[meanDistanceType].connect( "clicked()", lambda t=meanDistanceType: self.onMeanDistanceType(t)) self.meanDistanceTypeBox.layout().addWidget( self.meanDistanceTypeButtons[meanDistanceType]) inputRegistrationParametersFormLayout.addWidget( self.meanDistanceTypeBox) # # Start by Matching Centroids Options # self.startMatchingCentroids = qt.QCheckBox() self.startMatchingCentroids.checked = True self.startMatchingCentroids.connect("toggled(bool)", self.onMatchCentroidsLinearActive) inputRegistrationParametersFormLayout.addRow( "Start by matching centroids ", self.startMatchingCentroids) # # Check Mean Distance Options # self.checkMeanDistance = qt.QCheckBox() self.checkMeanDistance.checked = True self.checkMeanDistance.connect("toggled(bool)", self.onCheckMeanDistanceActive) inputRegistrationParametersFormLayout.addRow("Check Mean Distance ", self.checkMeanDistance) # Number of Iterations numberOfIterations = ctk.ctkSliderWidget() numberOfIterations.connect('valueChanged(double)', self.numberOfIterationsValueChanged) numberOfIterations.decimals = 0 numberOfIterations.minimum = 50 numberOfIterations.maximum = 80000 numberOfIterations.value = 50 inputRegistrationParametersFormLayout.addRow("Number of Iterations:", numberOfIterations) # Number of Landmarks numberOfLandmarks = ctk.ctkSliderWidget() numberOfLandmarks.connect('valueChanged(double)', self.numberOfLandmarksValueChanged) numberOfLandmarks.decimals = 0 numberOfLandmarks.minimum = 0 numberOfLandmarks.maximum = 10000 numberOfLandmarks.value = 200 inputRegistrationParametersFormLayout.addRow("Number of Landmarks:", numberOfLandmarks) # Maximum Distance maxDistance = ctk.ctkSliderWidget() maxDistance.connect('valueChanged(double)', self.maxDistanceValueChanged) maxDistance.decimals = 4 maxDistance.minimum = 0.0001 maxDistance.maximum = 10 maxDistance.value = 0.01 inputRegistrationParametersFormLayout.addRow("Maximum Distance:", maxDistance) # # Output Surface Collapsible Button # outputSurfaceCollapsibleButton = ctk.ctkCollapsibleButton() outputSurfaceCollapsibleButton.text = "Output Files" self.layout.addWidget(outputSurfaceCollapsibleButton) outputSurfaceFormLayout = qt.QFormLayout( outputSurfaceCollapsibleButton) # # Output Surface Volume Options # self.modelOutputSurfaceSelectors = {} self.modelOutputSurfaceSelectors[ "Output Surface Volume"] = slicer.qMRMLNodeComboBox() self.modelOutputSurfaceSelectors["Output Surface Volume"].nodeTypes = ( ("vtkMRMLModelNode"), "") self.modelOutputSurfaceSelectors[ "Output Surface Volume"].addEnabled = True self.modelOutputSurfaceSelectors[ "Output Surface Volume"].selectNodeUponCreation = True self.modelOutputSurfaceSelectors[ "Output Surface Volume"].removeEnabled = True self.modelOutputSurfaceSelectors[ "Output Surface Volume"].noneEnabled = True self.modelOutputSurfaceSelectors[ "Output Surface Volume"].showHidden = False self.modelOutputSurfaceSelectors[ "Output Surface Volume"].showChildNodeTypes = True self.modelOutputSurfaceSelectors["Output Surface Volume"].setMRMLScene( slicer.mrmlScene) self.modelOutputSurfaceSelectors["Output Surface Volume"].setToolTip( "Pick the Output Surface Volume") outputSurfaceFormLayout.addRow( "Output Surface Volume", self.modelOutputSurfaceSelectors["Output Surface Volume"]) # # Output Transform Options # self.volumeOutputTransformSelectors = {} self.volumeOutputTransformSelectors[ "Output Transform"] = slicer.qMRMLNodeComboBox() self.volumeOutputTransformSelectors["Output Transform"].nodeTypes = (( "vtkMRMLLinearTransformNode"), "") self.volumeOutputTransformSelectors[ "Output Transform"].selectNodeUponCreation = True self.volumeOutputTransformSelectors[ "Output Transform"].addEnabled = True self.volumeOutputTransformSelectors[ "Output Transform"].removeEnabled = True self.volumeOutputTransformSelectors[ "Output Transform"].noneEnabled = True self.volumeOutputTransformSelectors[ "Output Transform"].showHidden = False self.volumeOutputTransformSelectors[ "Output Transform"].showChildNodeTypes = True self.volumeOutputTransformSelectors["Output Transform"].setMRMLScene( slicer.mrmlScene) self.volumeOutputTransformSelectors["Output Transform"].setToolTip( "Pick the Output Transform file") outputSurfaceFormLayout.addRow( "Output Transform", self.volumeOutputTransformSelectors["Output Transform"]) # # Apply Button # self.applyButton = qt.QPushButton("Run Registration") self.applyButton.toolTip = "Run the registration algorithm." self.applyButton.enabled = True outputSurfaceFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) #for selector in self.volumeSelectors.values(): # selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onApplyButton) #self.volumeInitialTransformSelectors.values().connect('currentNodeChanged(vtkMRMLNode*)', self.onVolumeInitialTransformSelect) # listen to the scene #self.addObservers() # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... self.logic = NeedleTrackingLogic(None) self.logic.setWidget(self) #-------------------------------------------------- # For debugging # # Reload and Test area reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) reloadCollapsibleButton.collapsed = True # 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 = "Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # #-------------------------------------------------- self.nCath = 1 # Number of catheters #-------------------------------------------------- # GUI components # # Connection Area # connectionCollapsibleButton = ctk.ctkCollapsibleButton() connectionCollapsibleButton.text = "Connection (OpenIGTLink)" self.layout.addWidget(connectionCollapsibleButton) # Layout within the dummy collapsible button connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton) #-------------------------------------------------- # Connector Selector #-------------------------------------------------- self.igtlConnector1 = NeedleTrackingIGTLConnector("Connector 1") self.igtlConnector1.port = 18944 self.igtlConnector1.buildGUI(connectionFormLayout) #-------------------------------------------------- # Catheter #-------------------------------------------------- catheterCollapsibleButton = ctk.ctkCollapsibleButton() catheterCollapsibleButton.text = "Tracking Node" self.layout.addWidget(catheterCollapsibleButton) catheterFormLayout = qt.QFormLayout(catheterCollapsibleButton) #-------------------------------------------------- # Tracking node selector trackingNodeGroupBox = ctk.ctkCollapsibleGroupBox() trackingNodeGroupBox.title = "Tracking Node" catheterFormLayout.addWidget(trackingNodeGroupBox) trackingNodeFormLayout = qt.QFormLayout(trackingNodeGroupBox) self.trackingDataSelector = slicer.qMRMLNodeComboBox() self.trackingDataSelector.nodeTypes = (( "vtkMRMLIGTLTrackingDataBundleNode"), "") self.trackingDataSelector.selectNodeUponCreation = True self.trackingDataSelector.addEnabled = True self.trackingDataSelector.removeEnabled = False self.trackingDataSelector.noneEnabled = False self.trackingDataSelector.showHidden = True self.trackingDataSelector.showChildNodeTypes = False self.trackingDataSelector.setMRMLScene(slicer.mrmlScene) self.trackingDataSelector.setToolTip("Incoming tracking data") trackingNodeFormLayout.addRow("TrackingData: ", self.trackingDataSelector) # # check box to trigger transform conversion # self.activeTrackingCheckBox = qt.QCheckBox() self.activeTrackingCheckBox.checked = 0 self.activeTrackingCheckBox.enabled = 1 self.activeTrackingCheckBox.setToolTip("Activate Tracking") trackingNodeFormLayout.addRow("Active: ", self.activeTrackingCheckBox) #-------------------------------------------------- # Catheter Configuration configGroupBox = ctk.ctkCollapsibleGroupBox() configGroupBox.title = "Catheter Configuration" configGroupBox.collapsed = True catheterFormLayout.addWidget(configGroupBox) configFormLayout = qt.QFormLayout(configGroupBox) self.tipLengthSliderWidget = [None] * self.nCath self.catheterDiameterSliderWidget = [None] * self.nCath self.catheterOpacitySliderWidget = [None] * self.nCath for cath in range(self.nCath): # # Tip Length (legnth between the catheter tip and the first coil) # self.tipLengthSliderWidget[cath] = ctk.ctkSliderWidget() self.tipLengthSliderWidget[cath].singleStep = 0.5 self.tipLengthSliderWidget[cath].minimum = 0.0 self.tipLengthSliderWidget[cath].maximum = 100.0 self.tipLengthSliderWidget[cath].value = 10.0 self.tipLengthSliderWidget[cath].setToolTip( "Set the length of the catheter tip.") configFormLayout.addRow("Cath %d Tip Length (mm): " % cath, self.tipLengthSliderWidget[cath]) # # Catheter #1 Catheter diameter # self.catheterDiameterSliderWidget[cath] = ctk.ctkSliderWidget() self.catheterDiameterSliderWidget[cath].singleStep = 0.1 self.catheterDiameterSliderWidget[cath].minimum = 0.1 self.catheterDiameterSliderWidget[cath].maximum = 10.0 self.catheterDiameterSliderWidget[cath].value = 1.0 self.catheterDiameterSliderWidget[cath].setToolTip( "Set the diameter of the catheter") configFormLayout.addRow("Cath %d Diameter (mm): " % cath, self.catheterDiameterSliderWidget[cath]) # # Catheter #1 Catheter opacity # self.catheterOpacitySliderWidget[cath] = ctk.ctkSliderWidget() self.catheterOpacitySliderWidget[cath].singleStep = 0.1 self.catheterOpacitySliderWidget[cath].minimum = 0.0 self.catheterOpacitySliderWidget[cath].maximum = 1.0 self.catheterOpacitySliderWidget[cath].value = 1.0 self.catheterOpacitySliderWidget[cath].setToolTip( "Set the opacity of the catheter") configFormLayout.addRow("Cath %d Opacity: " % cath, self.catheterOpacitySliderWidget[cath]) # # Check box to show/hide coil labels # self.showCoilLabelCheckBox = qt.QCheckBox() self.showCoilLabelCheckBox.checked = 0 self.showCoilLabelCheckBox.setToolTip("Show/hide coil labels") configFormLayout.addRow("Show Coil Labels: ", self.showCoilLabelCheckBox) #-------------------------------------------------- # Coordinate System # coordinateGroupBox = ctk.ctkCollapsibleGroupBox() coordinateGroupBox.title = "Coordinate System" coordinateGroupBox.collapsed = True catheterFormLayout.addWidget(coordinateGroupBox) coordinateLayout = qt.QFormLayout(coordinateGroupBox) self.coordinateRPlusRadioButton = qt.QRadioButton("+X") self.coordinateRMinusRadioButton = qt.QRadioButton("-X") self.coordinateRPlusRadioButton.checked = 1 self.coordinateRBoxLayout = qt.QHBoxLayout() self.coordinateRBoxLayout.addWidget(self.coordinateRPlusRadioButton) self.coordinateRBoxLayout.addWidget(self.coordinateRMinusRadioButton) self.coordinateRGroup = qt.QButtonGroup() self.coordinateRGroup.addButton(self.coordinateRPlusRadioButton) self.coordinateRGroup.addButton(self.coordinateRMinusRadioButton) coordinateLayout.addRow("Right:", self.coordinateRBoxLayout) self.coordinateAPlusRadioButton = qt.QRadioButton("+Y") self.coordinateAMinusRadioButton = qt.QRadioButton("-Y") self.coordinateAPlusRadioButton.checked = 1 self.coordinateABoxLayout = qt.QHBoxLayout() self.coordinateABoxLayout.addWidget(self.coordinateAPlusRadioButton) self.coordinateABoxLayout.addWidget(self.coordinateAMinusRadioButton) self.coordinateAGroup = qt.QButtonGroup() self.coordinateAGroup.addButton(self.coordinateAPlusRadioButton) self.coordinateAGroup.addButton(self.coordinateAMinusRadioButton) coordinateLayout.addRow("Anterior:", self.coordinateABoxLayout) self.coordinateSPlusRadioButton = qt.QRadioButton("+Z") self.coordinateSMinusRadioButton = qt.QRadioButton("-Z") self.coordinateSPlusRadioButton.checked = 1 self.coordinateSBoxLayout = qt.QHBoxLayout() self.coordinateSBoxLayout.addWidget(self.coordinateSPlusRadioButton) self.coordinateSBoxLayout.addWidget(self.coordinateSMinusRadioButton) self.coordinateSGroup = qt.QButtonGroup() self.coordinateSGroup.addButton(self.coordinateSPlusRadioButton) self.coordinateSGroup.addButton(self.coordinateSMinusRadioButton) coordinateLayout.addRow("Superior:", self.coordinateSBoxLayout) #-------------------------------------------------- # Reslice # resliceCollapsibleButton = ctk.ctkCollapsibleButton() resliceCollapsibleButton.text = "Image Reslice" self.layout.addWidget(resliceCollapsibleButton) #resliceLayout = qt.QFormLayout(resliceCollapsibleButton) self.reslice = NeedleTrackingReslice("Image Reslice") self.reslice.nCath = self.nCath self.reslice.buildGUI(resliceCollapsibleButton) #-------------------------------------------------- # Connections #-------------------------------------------------- self.trackingDataSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onTrackingDataSelected) self.activeTrackingCheckBox.connect('toggled(bool)', self.onActiveTracking) for cath in range(self.nCath): self.tipLengthSliderWidget[cath].connect( "valueChanged(double)", functools.partial(self.onTipLengthChanged, cath)) self.catheterDiameterSliderWidget[cath].connect( "valueChanged(double)", functools.partial(self.onCatheterDiameterChanged, cath)) self.catheterOpacitySliderWidget[cath].connect( "valueChanged(double)", functools.partial(self.onCatheterOpacityChanged, cath)) self.showCoilLabelCheckBox.connect('toggled(bool)', self.onCoilLabelChecked) self.coordinateRPlusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateRMinusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateAPlusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateAMinusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateSPlusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) self.coordinateSMinusRadioButton.connect('clicked(bool)', self.onSelectCoordinate) # Add vertical spacer self.layout.addStretch(1)
def setup(self): # Instantiate and connect widgets ... # # Reload and Test area # if True: """Developer interface""" reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Advanced - Reload && Test" reloadCollapsibleButton.collapsed = False self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # 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 = "CardiacAgatstonMeasures Reload" reloadFormLayout.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." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # Collapsible button for Input Parameters self.measuresCollapsibleButton = ctk.ctkCollapsibleButton() self.measuresCollapsibleButton.text = "Input Parameters" self.layout.addWidget(self.measuresCollapsibleButton) # Collapsible button for Label Parameters self.labelsCollapsibleButton = ctk.ctkCollapsibleButton() self.labelsCollapsibleButton.text = "Label Parameters" #self.layout.addWidget(self.labelsCollapsibleButton) # Layout within the sample collapsible button self.measuresFormLayout = qt.QFormLayout( self.measuresCollapsibleButton) self.labelsFormLayout = qt.QFormLayout(self.labelsCollapsibleButton) # The Input Volume Selector self.inputFrame = qt.QFrame(self.measuresCollapsibleButton) self.inputFrame.setLayout(qt.QHBoxLayout()) self.measuresFormLayout.addRow(self.inputFrame) self.inputSelector = qt.QLabel("Input Volume: ", self.inputFrame) self.inputFrame.layout().addWidget(self.inputSelector) self.inputSelector = slicer.qMRMLNodeComboBox(self.inputFrame) self.inputSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputFrame.layout().addWidget(self.inputSelector) # Radio Buttons for Selecting 80 KEV or 120 KEV self.RadioButtonsFrame = qt.QFrame(self.measuresCollapsibleButton) self.RadioButtonsFrame.setLayout(qt.QHBoxLayout()) self.measuresFormLayout.addRow(self.RadioButtonsFrame) self.KEV80 = qt.QRadioButton("80 KEV", self.RadioButtonsFrame) self.KEV80.setToolTip("Select 80 KEV.") self.KEV80.checked = False self.RadioButtonsFrame.layout().addWidget(self.KEV80) self.KEV120 = qt.QRadioButton("120 KEV", self.RadioButtonsFrame) self.KEV120.setToolTip("Select 120 KEV.") self.KEV120.checked = False self.RadioButtonsFrame.layout().addWidget(self.KEV120) # Threshold button thresholdButton = qt.QPushButton("Threshold Volume") thresholdButton.toolTip = "Threshold the selected Input Volume" thresholdButton.setStyleSheet("background-color: rgb(230,241,255)") self.measuresFormLayout.addRow(thresholdButton) thresholdButton.connect('clicked(bool)', self.onThresholdButtonClicked) # Add vertical spacer self.layout.addStretch(1) # Set local var as instance attribute self.thresholdButton = thresholdButton # sets the layout to Red Slice Only layoutManager = slicer.app.layoutManager() layoutManager.setLayout( slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)
def setup(self): # make an instance of the logic self.logic = TwoTensorModelVizLogic() # # Model Selection Area # modelCollapsibleButton = ctk.ctkCollapsibleButton() modelCollapsibleButton.text = "Basic" self.layout.addWidget(modelCollapsibleButton) modelFormLayout = qt.QFormLayout(modelCollapsibleButton) # ============Fiber model selector=================== self.modelSelector = slicer.qMRMLNodeComboBox() self.modelSelector.nodeTypes = ( ("vtkMRMLFiberBundleNode"), "" ) self.modelSelector.selectNodeUponCreation = True self.modelSelector.addEnabled = False self.modelSelector.removeEnabled = False self.modelSelector.noneEnabled = False self.modelSelector.showHidden = False self.modelSelector.showChildNodeTypes = False self.modelSelector.setMRMLScene( slicer.mrmlScene ) self.modelSelector.setToolTip( "Pick a bundle of fibers." ) modelFormLayout.addRow("Fiber bundles: ", self.modelSelector) self.modelSelector.connect('currentNodeChanged(vtkMRMLNode*)', \ self.onModelSelect) # ============Glyph Space scroller================= self.sliderGlyphSpace = ctk.ctkSliderWidget() self.sliderGlyphSpace.decimals = 0 self.sliderGlyphSpace.minimum=1 self.sliderGlyphSpace.maximum=100 self.sliderGlyphSpace.value=10 self.sliderGlyphSpace.enabled = False modelFormLayout.addRow("Glyph Space:", self.sliderGlyphSpace) self.sliderGlyphSpace.connect('valueChanged(double)', \ self.onGlyphSpaceChanged) # ============Glyph Scale scroller================= self.sliderGlyphScale = ctk.ctkSliderWidget() self.sliderGlyphScale.decimals = 0 self.sliderGlyphScale.minimum=1 self.sliderGlyphScale.maximum=10000 self.sliderGlyphScale.value=2000 self.sliderGlyphScale.enabled = False modelFormLayout.addRow("Glyph Scale:", self.sliderGlyphScale) self.sliderGlyphScale.connect('valueChanged(double)', \ self.onGlyphScaleChanged) modelGridLayout=qt.QGridLayout() modelFormLayout.addRow("View Items:",modelGridLayout) # ============Check Box for showing lines============== self.checkboxLines=qt.QCheckBox("Lines") self.checkboxLines.toolTip="When checked, fiber lines are shown." self.checkboxLines.checked=True self.checkboxLines.enabled=False #modelFormLayout.addRow(self.checkboxLines) modelGridLayout.addWidget(self.checkboxLines,0,0) # ============Check Box for showing tensor 1============== self.checkboxTensor1=qt.QCheckBox("Tensor 1") self.checkboxTensor1.toolTip="When checked, cylinder glyphs are shown for tensor 1." self.checkboxTensor1.checked=True self.checkboxTensor1.enabled=False modelGridLayout.addWidget(self.checkboxTensor1,0,1) # ============Check Box for showing tensor 2============== self.checkboxTensor2=qt.QCheckBox("Tensor 2") self.checkboxTensor2.toolTip="When checked, cylinder glyphs are shown for tensor 2." self.checkboxTensor2.checked=True self.checkboxTensor2.enabled=False modelGridLayout.addWidget(self.checkboxTensor2,0,2) # ============Check Box for showing tube============== self.checkboxTubes=qt.QCheckBox("Tubes") self.checkboxTubes.toolTip="When checked, tubes will be shown." self.checkboxTubes.checked=True self.checkboxTubes.enabled=False modelGridLayout.addWidget(self.checkboxTubes,0,3) # # Fiber Filter Area # filterCollapsibleButton = ctk.ctkCollapsibleButton() filterCollapsibleButton.text = "Fiber Filter" self.layout.addWidget(filterCollapsibleButton) filterFormLayout = qt.QFormLayout(filterCollapsibleButton) # ============Line Space scroller================= self.sliderLineSpace = ctk.ctkSliderWidget() self.sliderLineSpace.decimals = 0 self.sliderLineSpace.minimum=1 self.sliderLineSpace.maximum=100 self.sliderLineSpace.value=10 self.sliderLineSpace.enabled = False filterFormLayout.addRow("One of n Fibers:", self.sliderLineSpace) self.sliderLineSpace.connect('valueChanged(double)', \ self.onLineSpaceChanged) # ============Line Num scroller================= self.sliderLineNum = ctk.ctkSliderWidget() self.sliderLineNum.decimals = 0 self.sliderLineNum.minimum=1 self.sliderLineNum.maximum=100 self.sliderLineNum.value=1 self.sliderLineNum.enabled = False filterFormLayout.addRow("Specific Fiber No:", self.sliderLineNum) self.sliderLineNum.connect('valueChanged(double)', \ self.onLineNumChanged) # ============Check Box for showing one fiber============== self.checkboxOnlyOneLine=qt.QCheckBox("Only show the specific fiber") self.checkboxOnlyOneLine.toolTip="When checked, only the specified fiber is shown." self.checkboxOnlyOneLine.checked=False self.checkboxOnlyOneLine.enabled=False filterFormLayout.addWidget(self.checkboxOnlyOneLine) # # Cylinder Color Mapping Area # cylinderColorCollapsibleButton = ctk.ctkCollapsibleButton() cylinderColorCollapsibleButton.text = "Cylinder Boby Color" self.layout.addWidget(cylinderColorCollapsibleButton) cylinderVBoxLayOut = qt.QVBoxLayout(cylinderColorCollapsibleButton) # Add a TabWidget cylinderTabWidget=qt.QTabWidget() cylinderVBoxLayOut.addWidget(cylinderTabWidget) # Create four pages and the GridLayOut redPage=qt.QWidget() redGrid=qt.QGridLayout(redPage) cylinderTabWidget.addTab(redPage,'Red') greenPage=qt.QWidget() greenGrid=qt.QGridLayout(greenPage) cylinderTabWidget.addTab(greenPage,'Green') bluePage=qt.QWidget() blueGrid=qt.QGridLayout(bluePage) cylinderTabWidget.addTab(bluePage,'Blue') alphaPage=qt.QWidget() alphaGrid=qt.QGridLayout(alphaPage) cylinderTabWidget.addTab(alphaPage,'Alpha') #========= Set the Red page ============== groupBox=qt.QGroupBox() grid = qt.QGridLayout(groupBox) redGrid.addWidget(groupBox,0,1) self.bodRadioR1=qt.QRadioButton("Fixed to:") self.bodRadioR2=qt.QRadioButton("Mapped to:") self.bodRadioR1.checked=True self.bodSliderR = ctk.ctkSliderWidget() self.bodSliderR.decimals = 0 self.bodSliderR.minimum=0 self.bodSliderR.maximum=255 self.bodSliderR.value=1 self.bodSliderR.enabled = True self.bodComboR = qt.QComboBox() self.bodComboR.duplicatesEnabled= False grid.addWidget(self.bodRadioR1,0,0) grid.addWidget(self.bodRadioR2,1,0) grid.addWidget(self.bodSliderR,0,1) grid.addWidget(self.bodComboR,1,1) #========= Set the Green page ============== groupBox=qt.QGroupBox() grid = qt.QGridLayout(groupBox) greenGrid.addWidget(groupBox,0,1) self.bodRadioG1=qt.QRadioButton("Fixed to:") self.bodRadioG2=qt.QRadioButton("Mapped to:") self.bodRadioG1.checked=True self.bodSliderG = ctk.ctkSliderWidget() self.bodSliderG.decimals = 0 self.bodSliderG.minimum=0 self.bodSliderG.maximum=255 self.bodSliderG.value=1 self.bodSliderG.enabled = True self.bodComboG = qt.QComboBox() self.bodComboG.duplicatesEnabled= False grid.addWidget(self.bodRadioG1,0,0) grid.addWidget(self.bodRadioG2,1,0) grid.addWidget(self.bodSliderG,0,1) grid.addWidget(self.bodComboG,1,1) #========= Set the Blue page ============== groupBox=qt.QGroupBox() grid = qt.QGridLayout(groupBox) blueGrid.addWidget(groupBox,0,1) self.bodRadioB1=qt.QRadioButton("Fixed to:") self.bodRadioB2=qt.QRadioButton("Mapped to:") self.bodRadioB1.checked=True self.bodSliderB = ctk.ctkSliderWidget() self.bodSliderB.decimals = 0 self.bodSliderB.minimum=0 self.bodSliderB.maximum=255 self.bodSliderB.value=1 self.bodSliderB.enabled = True self.bodComboB = qt.QComboBox() self.bodComboB.duplicatesEnabled= False grid.addWidget(self.bodRadioB1,0,0) grid.addWidget(self.bodRadioB2,1,0) grid.addWidget(self.bodSliderB,0,1) grid.addWidget(self.bodComboB,1,1) #========= Set the Alpha page ============== groupBox=qt.QGroupBox() grid = qt.QGridLayout(groupBox) alphaGrid.addWidget(groupBox,0,1) self.bodRadioA1=qt.QRadioButton("Fixed to:") self.bodRadioA2=qt.QRadioButton("Mapped to:") self.bodRadioA1.checked=True self.bodSliderA = ctk.ctkSliderWidget() self.bodSliderA.decimals = 0 self.bodSliderA.minimum=0 self.bodSliderA.maximum=255 self.bodSliderA.value=1 self.bodSliderA.enabled = True self.bodComboA = qt.QComboBox() self.bodComboA.duplicatesEnabled= False grid.addWidget(self.bodRadioA1,0,0) grid.addWidget(self.bodRadioA2,1,0) grid.addWidget(self.bodSliderA,0,1) grid.addWidget(self.bodComboA,1,1) # # Tube Mapping Area # tubeColorCollapsibleButton = ctk.ctkCollapsibleButton() tubeColorCollapsibleButton.text = "Tube Mapping" self.layout.addWidget(tubeColorCollapsibleButton) tubeVboxLayOut = qt.QVBoxLayout(tubeColorCollapsibleButton) # Add a TabWidget tubeTabWidget=qt.QTabWidget() tubeVboxLayOut.addWidget(tubeTabWidget) # Create three pages and the GridLayOut tubeColorPage=qt.QWidget() tubeColorGrid=qt.QGridLayout(tubeColorPage) tubeTabWidget.addTab(tubeColorPage,'Color') tubeSizePage=qt.QWidget() tubeSizeGrid=qt.QGridLayout(tubeSizePage) tubeTabWidget.addTab(tubeSizePage,'Size') #========= Set the color page ============== groupBox=qt.QGroupBox() grid = qt.QGridLayout(groupBox) tubeColorGrid.addWidget(groupBox,0,0) self.tubeRadioFixedTo=qt.QRadioButton("Fixed to") self.tubeRadioByOrientation=qt.QRadioButton("Color by orientation") self.tubeRadioSameAsCylinderBody=qt.QRadioButton("Same as Cylinder Body") self.tubeRadioByOrientation.checked=True grid.addWidget(self.tubeRadioFixedTo,0,0) grid.addWidget(self.tubeRadioByOrientation,1,0) grid.addWidget(self.tubeRadioSameAsCylinderBody,2,0) self.tubeColorButton=qt.QPushButton('Specifying Color') self.tubeColorButton.setAutoFillBackground(True) grid.addWidget(self.tubeColorButton,0,1) self.tubeColorButton.connect('clicked()', \ self.onTubeFixedColor) #========= Set the size page ============== self.tubeSizeRadio1=qt.QRadioButton("Fixed to:") self.tubeSizeRadio2=qt.QRadioButton("Mapped to:") self.tubeSizeRadio1.checked=True self.tubeSizeSlider = ctk.ctkSliderWidget() self.tubeSizeSlider.decimals = 2 self.tubeSizeSlider.minimum=0.0 self.tubeSizeSlider.maximum=5.0 self.tubeSizeSlider.value=0.1 self.tubeSizeSlider.enabled = True self.tubeComboBox = qt.QComboBox() self.tubeComboBox.duplicatesEnabled= False tubeSizeGrid.addWidget(self.tubeSizeRadio1,0,0) tubeSizeGrid.addWidget(self.tubeSizeRadio2,1,0) tubeSizeGrid.addWidget(self.tubeSizeSlider,0,1) tubeSizeGrid.addWidget(self.tubeComboBox,1,1) # ============Scale scroller================= label=qt.QLabel('Tube Scale:') self.sliderTubeScale = ctk.ctkSliderWidget() self.sliderTubeScale.decimals = 0 self.sliderTubeScale.minimum=1 self.sliderTubeScale.maximum=100 self.sliderTubeScale.value=5 self.sliderTubeScale.enabled = False tubeSizeGrid.addWidget(label,2,0) tubeSizeGrid.addWidget(self.sliderTubeScale,2,1) self.sliderTubeScale.connect('valueChanged(double)', \ self.onTubeScaleChanged) # # ============Apply button================= # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Apply the visualization." self.applyButton.enabled = False self.applyButton.setPalette(qt.QPalette(qt.QColor(128,255,128))) self.parent.layout().addWidget(self.applyButton) self.applyButton.connect('clicked()', \ self.onApply) # # ============Clear button================= # self.clearButton = qt.QPushButton("Clear") self.clearButton.toolTip = "Clear objects rendered in 3D view windows." self.clearButton.enabled = False self.clearButton.setPalette(qt.QPalette(qt.QColor(255,128,128))) self.parent.layout().addWidget(self.clearButton) self.clearButton.connect('clicked()', \ self.onClear) # ===========Finally, Add vertical spacer================ self.layout.addStretch(2)
def createUserInterface(self): """ This method uses qt to create a user interface of radio buttons to select a registration method. Note that BSpline registration is so slow and memory-consuming as to at one point break Slicer. There is an option to run it with limited memory, but this may take prohibitively long. <- NOTE this last comment was based on expert automated registration - not sure about other modules. """ self.__layout = self.__parent.createUserInterface() step_label = qt.QLabel( """This step allows you to pre-process your data as necessary for deep learning segmentation. Your data may already be preprocessed, in which case you can skip this step. Note that for proper deep learning segmentation, your data will need to be A) registered, and B) resampled into isotropic space. """) step_label.setWordWrap(True) self.__informationGroupBox = qt.QGroupBox() self.__informationGroupBox.setTitle('Information') self.__informationGroupBoxLayout = qt.QFormLayout( self.__informationGroupBox) self.__informationGroupBoxLayout.addRow(step_label) self.__layout.addRow(self.__informationGroupBox) self.__registrationCollapsibleButton = ctk.ctkCollapsibleButton() self.__registrationCollapsibleButton.text = "Registration" self.__layout.addWidget(self.__registrationCollapsibleButton) self.__registrationLayout = qt.QFormLayout( self.__registrationCollapsibleButton) # Moving/Fixed Image Registration Order Options OrderGroupBox = qt.QGroupBox() OrderGroupBox.setTitle('Registration Base Volume') self.__registrationLayout.addRow(OrderGroupBox) OrderGroupBoxLayout = qt.QFormLayout(OrderGroupBox) self.__OrderRadio1 = qt.QRadioButton("Register to T2.") self.__OrderRadio1.toolTip = "Your images will be registered to T2 space." OrderGroupBoxLayout.addRow(self.__OrderRadio1) self.__OrderRadio1.setChecked(True) self.__OrderRadio2 = qt.QRadioButton("Register to FLAIR") self.__OrderRadio2.toolTip = "Your images will be registered to FLAIR space." OrderGroupBoxLayout.addRow(self.__OrderRadio2) self.__OrderRadio3 = qt.QRadioButton("Register to post-contrast T1") self.__OrderRadio3.toolTip = "Your images will be registered to post-contrast T1 space." OrderGroupBoxLayout.addRow(self.__OrderRadio3) self.__OrderRadio4 = qt.QRadioButton("Register to pre-contrast T1") self.__OrderRadio4.toolTip = "Your images will be registered to pre-contrast T1 space." OrderGroupBoxLayout.addRow(self.__OrderRadio4) self.__orderMapping = dict( zip(self.volumeLabels, [ self.__OrderRadio1, self.__OrderRadio2, self.__OrderRadio3, self.__OrderRadio4 ])) # Registration Method Options RegistrationGroupBox = qt.QGroupBox() RegistrationGroupBox.setTitle('Registration Method') self.__registrationLayout.addRow(RegistrationGroupBox) RegistrationGroupBoxLayout = qt.QFormLayout(RegistrationGroupBox) self.__RegistrationRadio1 = qt.QRadioButton("Rigid Registration") self.__RegistrationRadio1.toolTip = """Computes a rigid registration on the pre-contrast image with respect to the post-contrast image. This will likely be the fastest registration method""" RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio1) self.__RegistrationRadio2 = qt.QRadioButton("Affine Registration") self.__RegistrationRadio2.toolTip = "Computes a rigid and affine registration on the pre-contrast image with respect to the post-contrast image. This method may take longer than rigid registration, but has the ability to stretch or compress images in addition to rotation and translation." RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio2) self.__RegistrationRadio2.setChecked(True) self.__RegistrationRadio3 = qt.QRadioButton("Deformable Registration") self.__RegistrationRadio3.toolTip = """Computes a BSpline Registration on the pre-contrast image with respect to the post-contrast image. This method is slowest and may be necessary for only severly distorted images.""" RegistrationGroupBoxLayout.addRow(self.__RegistrationRadio3) # Output Volume Preference OutputGroupBox = qt.QGroupBox() OutputGroupBox.setTitle('Registration Output') self.__registrationLayout.addRow(OutputGroupBox) OutputGroupBoxLayout = qt.QFormLayout(OutputGroupBox) self.__OutputRadio1 = qt.QRadioButton("Create new volume.") self.__OutputRadio1.toolTip = "A new volume will be created with the naming convention \"[pre]_reg_[post]\"." OutputGroupBoxLayout.addRow(self.__OutputRadio1) self.__OutputRadio1.setChecked(True) self.__OutputRadio2 = qt.QRadioButton("Replace existing volume.") self.__OutputRadio2.toolTip = "Your registered volume will be overwritten at the end of this step." OutputGroupBoxLayout.addRow(self.__OutputRadio2) # Registration Button and Progress Indicator RunGroupBox = qt.QGroupBox() RunGroupBox.setTitle('Run Registration') self.__registrationLayout.addRow(RunGroupBox) RunGroupBoxLayout = qt.QFormLayout(RunGroupBox) self.__registrationButton = qt.QPushButton('Run registration') self.__registrationStatus = qt.QLabel('Register scans') self.__registrationStatus.alignment = 4 # This codes for centered alignment, although I'm not sure why. RunGroupBoxLayout.addRow(self.__registrationStatus) RunGroupBoxLayout.addRow(self.__registrationButton) self.__registrationButton.connect('clicked()', self.onRegistrationRequest)
def setup(self): # Instantiate and connect widgets ... w = qt.QWidget() layout = qt.QGridLayout() w.setLayout(layout) self.layout.addWidget(w) w.show() #self.layout = layout # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # 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 = "SequenceRegistration Reload" reloadFormLayout.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." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # # Input Area # parametersCollapsibleButton1 = ctk.ctkCollapsibleButton() parametersCollapsibleButton1.text = "Inputs" self.layout.addWidget(parametersCollapsibleButton1) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton1) # # Input fixed image # self.fixedImageSelector = slicer.qMRMLNodeComboBox() self.fixedImageSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) self.fixedImageSelector.selectNodeUponCreation = True self.fixedImageSelector.addEnabled = False self.fixedImageSelector.removeEnabled = False self.fixedImageSelector.noneEnabled = False self.fixedImageSelector.showHidden = False self.fixedImageSelector.showChildNodeTypes = False self.fixedImageSelector.setMRMLScene( slicer.mrmlScene ) self.fixedImageSelector.setToolTip( "Please select the fixed image node for tracking." ) parametersFormLayout.addRow("Reference sequence/image node: ", self.fixedImageSelector) # # Input moving sequence image # self.movingImageSequenceSelector = slicer.qMRMLNodeComboBox() self.movingImageSequenceSelector.nodeTypes = ( ("vtkMRMLSequenceNode"), "" ) self.movingImageSequenceSelector.selectNodeUponCreation = True self.movingImageSequenceSelector.addEnabled = False self.movingImageSequenceSelector.removeEnabled = False self.movingImageSequenceSelector.noneEnabled = False self.movingImageSequenceSelector.showHidden = False self.movingImageSequenceSelector.showChildNodeTypes = False self.movingImageSequenceSelector.setMRMLScene( slicer.mrmlScene ) self.movingImageSequenceSelector.setToolTip( "Please select the moving sequence image node for tracking." ) parametersFormLayout.addRow("Moving sequence/image node: ", self.movingImageSequenceSelector) # # Input rigid transform # self.linearTransformSelector = slicer.qMRMLNodeComboBox() self.linearTransformSelector.nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" ) self.linearTransformSelector.selectNodeUponCreation = True self.linearTransformSelector.addEnabled = True self.linearTransformSelector.removeEnabled = True self.linearTransformSelector.noneEnabled = True self.linearTransformSelector.showHidden = False self.linearTransformSelector.showChildNodeTypes = False self.linearTransformSelector.setMRMLScene( slicer.mrmlScene ) self.linearTransformSelector.setToolTip( "Please select a transform." ) parametersFormLayout.addRow("Initial transform node: ", self.linearTransformSelector) # # ROI # self.InputROISelector = slicer.qMRMLNodeComboBox() self.InputROISelector.nodeTypes = ( ("vtkMRMLAnnotationROINode"), "" ) self.InputROISelector.selectNodeUponCreation = True self.InputROISelector.addEnabled = True self.InputROISelector.removeEnabled = True self.InputROISelector.noneEnabled = True self.InputROISelector.showHidden = False self.InputROISelector.showChildNodeTypes = False self.InputROISelector.setMRMLScene( slicer.mrmlScene ) parametersFormLayout.addRow("ROI: ", self.InputROISelector) self.ROIVisibilityButton = qt.QPushButton("Off") self.ROIVisibilityButton.checkable = True self.ROIVisibilityButton.checked = False self.ROIVisibilityButton.enabled = False parametersFormLayout.addRow("ROI Visibility: ", self.ROIVisibilityButton) self.InitializeTransformModeOptions = ("Off","useGeometryAlign","useMomentsAlign") # #Initialization # self.groupBox = qt.QGroupBox("Initialize Transform Mode") self.groupBoxLayout = qt.QHBoxLayout(self.groupBox) parametersFormLayout.addRow(self.groupBox) # # layout selection # for initializeTransformModeOption in self.InitializeTransformModeOptions: initializeTransformModeButton = qt.QRadioButton(initializeTransformModeOption) initializeTransformModeButton.connect('clicked()', lambda itmo=initializeTransformModeOption: self.selectInitializeTransformMode(itmo)) self.groupBoxLayout.addWidget(initializeTransformModeButton) #self.groupBoxLayout.addRow("Layout", layoutHolder) # # Register Button # self.registerButton = qt.QPushButton("Register") self.registerButton.toolTip = "Run the algorithm." self.registerButton.enabled = False parametersFormLayout.addRow(self.registerButton) # Connections self.fixedImageSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputSelect) self.movingImageSequenceSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputSelect) self.InputROISelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputSelect) self.ROIVisibilityButton.connect('clicked(bool)', self.onROIVisible) self.registerButton.connect('clicked(bool)', self.onApply) # # Output Area # outputsCollapsibleButton1 = ctk.ctkCollapsibleButton() outputsCollapsibleButton1.text = "Outputs (at least one output must be specified)" self.layout.addWidget(outputsCollapsibleButton1) # Layout within the dummy collapsible button outputsFormLayout = qt.QFormLayout(outputsCollapsibleButton1) # # Output rigid transform # self.outputTransformSequenceSelector = slicer.qMRMLNodeComboBox() self.outputTransformSequenceSelector.nodeTypes = ( ("vtkMRMLSequenceNode"), "" ) self.outputTransformSequenceSelector.selectNodeUponCreation = True self.outputTransformSequenceSelector.addEnabled = True self.outputTransformSequenceSelector.removeEnabled = True self.outputTransformSequenceSelector.noneEnabled = True self.outputTransformSequenceSelector.showHidden = False self.outputTransformSequenceSelector.showChildNodeTypes = False self.outputTransformSequenceSelector.setMRMLScene( slicer.mrmlScene ) self.outputTransformSequenceSelector.setToolTip( "Please select a sequence transform node." ) outputsFormLayout.addRow("Output sequence transform node: ", self.outputTransformSequenceSelector) # # Output images # self.outputImageSequenceSelector = slicer.qMRMLNodeComboBox() self.outputImageSequenceSelector.nodeTypes = ( ("vtkMRMLSequenceNode"), "" ) self.outputImageSequenceSelector.selectNodeUponCreation = True self.outputImageSequenceSelector.addEnabled = True self.outputImageSequenceSelector.removeEnabled = True self.outputImageSequenceSelector.noneEnabled = True self.outputImageSequenceSelector.showHidden = False self.outputImageSequenceSelector.showChildNodeTypes = False self.outputImageSequenceSelector.setMRMLScene( slicer.mrmlScene ) self.outputImageSequenceSelector.setToolTip( "Please select a sequence image node." ) outputsFormLayout.addRow("Output sequence image node: ", self.outputImageSequenceSelector) # Comment out the following code as this functionality is not moved to Sequence Browser module # plottingCollapsibleButton = ctk.ctkCollapsibleButton() # plottingCollapsibleButton.text = "Plotting" # plottingCollapsibleButton.collapsed = 0 # self.layout.addWidget(plottingCollapsibleButton) # plottingFrameLayout = qt.QGridLayout(plottingCollapsibleButton) # self.ChartingDisplayOptions = ("LR","AP","SI") # self.chartingDisplayOption = 'LR' # # # #Initialization # # # self.chartGroupBox = qt.QGroupBox("Display options:") # self.chartGroupBoxLayout = qt.QHBoxLayout(self.chartGroupBox) # plottingFrameLayout.addWidget(self.chartGroupBox,0,0,1,3) # # # # layout selection # # # for chartingDisplayOption in self.ChartingDisplayOptions: # chartingDisplayOptionButton = qt.QRadioButton(chartingDisplayOption) # chartingDisplayOptionButton.connect('clicked()', lambda cdo=chartingDisplayOption: self.selectChartingDisplayOption(cdo)) # self.chartGroupBoxLayout.addWidget(chartingDisplayOptionButton) # #self.groupBoxLayout.addRow("Layout", layoutHolder) # # add chart container widget # self.__chartView = ctk.ctkVTKChartView(w) # plottingFrameLayout.addWidget(self.__chartView,1,0,1,3) # self.__chart = self.__chartView.chart() # self.__chartTable = vtk.vtkTable() # self.__xArray = vtk.vtkFloatArray() # self.__yArray = vtk.vtkFloatArray() # self.__zArray = vtk.vtkFloatArray() # self.__mArray = vtk.vtkFloatArray() # # will crash if there is no name # self.__xArray.SetName('') # self.__yArray.SetName('signal intensity') # self.__zArray.SetName('') # self.__mArray.SetName('signal intensity') # self.__chartTable.AddColumn(self.__xArray) # self.__chartTable.AddColumn(self.__yArray) # self.__chartTable.AddColumn(self.__zArray) # self.__chartTable.AddColumn(self.__mArray) self.outputTransformSequenceSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onOutputSelect) self.outputImageSequenceSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onOutputSelect) # Add vertical spacer self.layout.addStretch(1)