def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) # Add generic settings genericGroupBox = ctk.ctkCollapsibleGroupBox() genericGroupBox.title = "Generic DICOM settings" genericGroupBoxFormLayout = qt.QFormLayout(genericGroupBox) loadReferencesComboBox = ctk.ctkComboBox() loadReferencesComboBox.toolTip = "Determines whether referenced DICOM series are " \ "offered when loading DICOM, or the automatic behavior if interaction is disabled. " \ "Interactive selection of referenced series is the default selection" loadReferencesComboBox.addItem("Ask user", qt.QMessageBox.InvalidRole) loadReferencesComboBox.addItem("Always", qt.QMessageBox.Yes) loadReferencesComboBox.addItem("Never", qt.QMessageBox.No) loadReferencesComboBox.currentIndex = 0 genericGroupBoxFormLayout.addRow("Load referenced series:", loadReferencesComboBox) parent.registerProperty("DICOM/automaticallyLoadReferences", loadReferencesComboBox, "currentUserDataAsString", str(qt.SIGNAL("currentIndexChanged(int)"))) vBoxLayout.addWidget(genericGroupBox) # Add settings panel for the plugins plugins = slicer.modules.dicomPlugins for pluginName in plugins.keys(): if hasattr(plugins[pluginName], 'settingsPanelEntry'): pluginGroupBox = ctk.ctkCollapsibleGroupBox() pluginGroupBox.title = pluginName vBoxLayout.addWidget(pluginGroupBox) plugins[pluginName].settingsPanelEntry(parent, pluginGroupBox) vBoxLayout.addStretch(1)
def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) # Add generic settings genericGroupBox = ctk.ctkCollapsibleGroupBox() genericGroupBox.title = "Generic DICOM settings" genericGroupBoxFormLayout = qt.QFormLayout(genericGroupBox) loadReferencesComboBox = ctk.ctkComboBox() loadReferencesComboBox.toolTip = "Determines whether referenced DICOM series are " \ "offered when loading DICOM, or the automatic behavior if interaction is disabled. " \ "Interactive selection of referenced series is the default selection" loadReferencesComboBox.addItem("Ask user", qt.QMessageBox.InvalidRole) loadReferencesComboBox.addItem("Always", qt.QMessageBox.Yes) loadReferencesComboBox.addItem("Never", qt.QMessageBox.No) loadReferencesComboBox.currentIndex = 0 genericGroupBoxFormLayout.addRow("Load referenced series:", loadReferencesComboBox) parent.registerProperty( "DICOM/automaticallyLoadReferences", loadReferencesComboBox, "currentUserDataAsString", str(qt.SIGNAL("currentIndexChanged(int)"))) vBoxLayout.addWidget(genericGroupBox) # Add settings panel for the plugins plugins = slicer.modules.dicomPlugins for pluginName in plugins.keys(): if hasattr(plugins[pluginName], 'settingsPanelEntry'): pluginGroupBox = ctk.ctkCollapsibleGroupBox() pluginGroupBox.title = pluginName vBoxLayout.addWidget(pluginGroupBox) plugins[pluginName].settingsPanelEntry(parent, pluginGroupBox) vBoxLayout.addStretch(1)
def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) # Add generic settings genericGroupBox = ctk.ctkCollapsibleGroupBox() genericGroupBox.title = "Generic DICOM settings" genericGroupBoxFormLayout = qt.QFormLayout(genericGroupBox) directoryButton = ctk.ctkDirectoryButton() genericGroupBoxFormLayout.addRow("Database location:", directoryButton) parent.registerProperty(slicer.dicomDatabaseDirectorySettingsKey, directoryButton, "directory", str(qt.SIGNAL("directoryChanged(QString)")), "DICOM general settings", ctk.ctkSettingsPanel.OptionRequireRestart) # Restart is forced because no mechanism is implemented that would reopen the DICOM database after # folder location is changed. It is easier to restart the application than implementing an update # mechanism. loadReferencesComboBox = ctk.ctkComboBox() loadReferencesComboBox.toolTip = "Determines whether referenced DICOM series are " \ "offered when loading DICOM, or the automatic behavior if interaction is disabled. " \ "Interactive selection of referenced series is the default selection" loadReferencesComboBox.addItem("Ask user", qt.QMessageBox.InvalidRole) loadReferencesComboBox.addItem("Always", qt.QMessageBox.Yes) loadReferencesComboBox.addItem("Never", qt.QMessageBox.No) loadReferencesComboBox.currentIndex = 0 genericGroupBoxFormLayout.addRow("Load referenced series:", loadReferencesComboBox) parent.registerProperty("DICOM/automaticallyLoadReferences", loadReferencesComboBox, "currentUserDataAsString", str(qt.SIGNAL("currentIndexChanged(int)"))) detailedLoggingCheckBox = qt.QCheckBox() detailedLoggingCheckBox.toolTip = ( "Log more details during DICOM operations." " Useful for investigating DICOM loading issues but may impact performance." ) genericGroupBoxFormLayout.addRow("Detailed logging:", detailedLoggingCheckBox) detailedLoggingMapper = ctk.ctkBooleanMapper( detailedLoggingCheckBox, "checked", str(qt.SIGNAL("toggled(bool)"))) parent.registerProperty("DICOM/detailedLogging", detailedLoggingMapper, "valueAsInt", str(qt.SIGNAL("valueAsIntChanged(int)"))) vBoxLayout.addWidget(genericGroupBox) # Add settings panel for the plugins plugins = slicer.modules.dicomPlugins for pluginName in plugins.keys(): if hasattr(plugins[pluginName], 'settingsPanelEntry'): pluginGroupBox = ctk.ctkCollapsibleGroupBox() pluginGroupBox.title = pluginName vBoxLayout.addWidget(pluginGroupBox) plugins[pluginName].settingsPanelEntry(parent, pluginGroupBox) vBoxLayout.addStretch(1)
def buildMainPanel(self, frame): layout = qt.QVBoxLayout(frame) #-------------------------------------------------- # File recording # fileGroupBox = ctk.ctkCollapsibleGroupBox() fileGroupBox.title = "File Recording" fileGroupBox.collapsed = False layout.addWidget(fileGroupBox) fileLayout = qt.QFormLayout(fileGroupBox) fileBoxLayout = qt.QHBoxLayout() self.fileLineEdit = qt.QLineEdit() self.fileDialogBoxButton = qt.QPushButton() self.fileDialogBoxButton.setCheckable(False) self.fileDialogBoxButton.text = '...' self.fileDialogBoxButton.setToolTip("Open file dialog box.") fileBoxLayout.addWidget(self.fileLineEdit) fileBoxLayout.addWidget(self.fileDialogBoxButton) fileLayout.addRow("File Path:", fileBoxLayout) self.activeCheckBox = qt.QCheckBox() self.activeCheckBox.checked = 0 self.activeCheckBox.enabled = 1 self.activeCheckBox.setToolTip("Activate recording") fileLayout.addRow("Recording:", self.activeCheckBox) self.fileDialogBoxButton.connect('clicked(bool)', self.openDialogBox) self.fileLineEdit.editingFinished.connect(self.onFilePathEntered) self.activeCheckBox.connect('clicked(bool)', self.onActive) #-------------------------------------------------- # Point recording # pointGroupBox = ctk.ctkCollapsibleGroupBox() pointGroupBox.title = "Point Recording" pointGroupBox.collapsed = False layout.addWidget(pointGroupBox) pointLayout = qt.QVBoxLayout(pointGroupBox) self.precording = QPointRecordingFrame(catheters=self.catheters) pointLayout.addWidget(self.precording) ## TODO: Should it be called from the module class, either Widget or Logic? self.addSceneObservers()
def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) # Add generic settings genericGroupBox = ctk.ctkCollapsibleGroupBox() genericGroupBox.title = "Generic DICOM settings" genericGroupBoxFormLayout = qt.QFormLayout(genericGroupBox) loadReferencesComboBox = ctk.ctkComboBox() loadReferencesComboBox.toolTip = "Determines whether referenced DICOM series are " \ "offered when loading DICOM, or the automatic behavior if interaction is disabled. " \ "Interactive selection of referenced series is the default selection" loadReferencesComboBox.addItem("Ask user", qt.QMessageBox.InvalidRole) loadReferencesComboBox.addItem("Always", qt.QMessageBox.Yes) loadReferencesComboBox.addItem("Never", qt.QMessageBox.No) loadReferencesComboBox.currentIndex = 0 genericGroupBoxFormLayout.addRow("Load referenced series:", loadReferencesComboBox) parent.registerProperty("DICOM/automaticallyLoadReferences", loadReferencesComboBox, "currentUserDataAsString", str(qt.SIGNAL("currentIndexChanged(int)"))) schemaUpdateComboBox = ctk.ctkComboBox() schemaUpdateComboBox.toolTip = "What do do when the supported schema version is " \ "different from that of the loaded database" schemaUpdateComboBox.addItem("Always update", "AlwaysUpdate") schemaUpdateComboBox.addItem("Never update", "NeverUpdate") schemaUpdateComboBox.addItem("Ask user", "AskUser") schemaUpdateComboBox.currentIndex = 2 # Make 'AskUser' the default as opposed to the CTK default 'AlwaysUpdate' if slicer.app.commandOptions().testingEnabled: schemaUpdateComboBox.currentIndex = 0 # Update database for automatic tests genericGroupBoxFormLayout.addRow("Schema update behavior:", schemaUpdateComboBox) parent.registerProperty("DICOM/SchemaUpdateOption", schemaUpdateComboBox, "currentUserDataAsString", str(qt.SIGNAL("currentIndexChanged(int)"))) vBoxLayout.addWidget(genericGroupBox) # Add settings panel for the plugins plugins = slicer.modules.dicomPlugins for pluginName in plugins.keys(): if hasattr(plugins[pluginName], 'settingsPanelEntry'): pluginGroupBox = ctk.ctkCollapsibleGroupBox() pluginGroupBox.title = pluginName vBoxLayout.addWidget(pluginGroupBox) plugins[pluginName].settingsPanelEntry(parent, pluginGroupBox) vBoxLayout.addStretch(1)
def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) aiaaGroupBox = ctk.ctkCollapsibleGroupBox() aiaaGroupBox.title = 'AI-Assisted Annotation Server' aiaaGroupLayout = qt.QFormLayout(aiaaGroupBox) serverUrl = qt.QLineEdit() aiaaGroupLayout.addRow('Server address:', serverUrl) parent.registerProperty('NVIDIA-AIAA/serverUrl', serverUrl, 'text', str(qt.SIGNAL('textChanged(QString)'))) serverUrlHistory = qt.QLineEdit() aiaaGroupLayout.addRow('Server address history:', serverUrlHistory) parent.registerProperty('NVIDIA-AIAA/serverUrlHistory', serverUrlHistory, 'text', str(qt.SIGNAL('textChanged(QString)'))) compressDataCheckBox = qt.QCheckBox() compressDataCheckBox.checked = True compressDataCheckBox.toolTip = 'Enable this option on computer with slow network upload speed. Data compression reduces network transfer time but increases preprocessing time.' aiaaGroupLayout.addRow('Compress data:', compressDataCheckBox) compressDataMapper = ctk.ctkBooleanMapper( compressDataCheckBox, 'checked', str(qt.SIGNAL('toggled(bool)'))) parent.registerProperty('NVIDIA-AIAA/compressData', compressDataMapper, 'valueAsInt', str(qt.SIGNAL('valueAsIntChanged(int)'))) vBoxLayout.addWidget(aiaaGroupBox) vBoxLayout.addStretch(1)
def setup(self): categories = slicer.modules.sampleDataSources.keys() categories.sort() if 'BuiltIn' in categories: categories.remove('BuiltIn') categories.insert(0, 'BuiltIn') for category in categories: frame = ctk.ctkCollapsibleGroupBox(self.parent) self.layout.addWidget(frame) frame.title = category frame.name = '%sCollapsibleGroupBox' % category layout = qt.QVBoxLayout(frame) for source in slicer.modules.sampleDataSources[category]: name = source.sampleName if not name: name = source.nodeNames[0] b = qt.QPushButton('Download %s' % name) b.name = '%sPushButton' % name layout.addWidget(b) if source.customDownloader: b.connect('clicked()', source.customDownloader) else: b.connect( 'clicked()', lambda s=source: self.logic.downloadFromSource(s)) self.log = qt.QTextEdit() self.log.readOnly = True self.layout.addWidget(self.log) self.logMessage('<p>Status: <i>Idle</i>\n') # Add spacer to layout self.layout.addStretch(1)
def setup(self): categories = slicer.modules.sampleDataSources.keys() categories.sort() if 'BuiltIn' in categories: categories.remove('BuiltIn') categories.insert(0,'BuiltIn') for category in categories: frame = ctk.ctkCollapsibleGroupBox(self.parent) self.layout.addWidget(frame) frame.title = category frame.name = '%sCollapsibleGroupBox' % category layout = qt.QVBoxLayout(frame) for source in slicer.modules.sampleDataSources[category]: name = source.sampleName if not name: name = source.nodeNames[0] b = qt.QPushButton('Download %s' % name) b.name = '%sPushButton' % name layout.addWidget(b) if source.customDownloader: b.connect('clicked()', source.customDownloader) else: b.connect('clicked()', lambda s=source: self.logic.downloadFromSource(s)) self.log = qt.QTextEdit() self.log.readOnly = True self.layout.addWidget(self.log) self.logMessage('<p>Status: <i>Idle</i>\n') # Add spacer to layout self.layout.addStretch(1)
def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) plugins = slicer.modules.dicomPlugins for pluginName in plugins.keys(): if hasattr(plugins[pluginName], 'settingsPanelEntry'): pluginGroupBox = ctk.ctkCollapsibleGroupBox() pluginGroupBox.title = pluginName vBoxLayout.addWidget(pluginGroupBox) plugins[pluginName].settingsPanelEntry(parent, pluginGroupBox) vBoxLayout.addStretch(1)
def __init__(self, parent, rcPath): vBoxLayout = qt.QVBoxLayout(parent) # Add generic settings genericGroupBox = ctk.ctkCollapsibleGroupBox() genericGroupBox.title = "Generic SlicerMorph settings" genericGroupBoxFormLayout = qt.QFormLayout(genericGroupBox) self.loadMorphPreferencesCheckBox = qt.QCheckBox() self.loadMorphPreferencesCheckBox.toolTip = ( "Customize SlicerMorph features such as hotkeys at startup" " (file can be customized in python for advanced users).", " Restart the app for changes to take effect.") toBool = slicer.util.toBool key = "MorphPreferences/customize" customize = slicer.util.settingsValue(key, False, converter=toBool) self.loadMorphPreferencesCheckBox.checked = customize genericGroupBoxFormLayout.addRow("Use SlicerMorph customizations:", self.loadMorphPreferencesCheckBox) hbox = qt.QHBoxLayout() label = qt.QLineEdit(rcPath) label.readOnly = True genericGroupBoxFormLayout.addRow("Customization file:", label) loadNowButton = qt.QPushButton("Load now") loadNowButton.toolTip = "Load the customization file now" hbox.addWidget(label) hbox.addWidget(loadNowButton) genericGroupBoxFormLayout.addRow("Customization file:", hbox) loadNowButton.connect( "clicked()", lambda rcPath=rcPath: MorphPreferences.loadRCFile(rcPath)) self.loadMorphPreferencesCheckBox.connect( "toggled(bool)", self.onLoadMorphPreferencesCheckBoxToggled) hbox = qt.QHBoxLayout() self.downloadDirectory = qt.QLineEdit() self.downloadDirectory.readOnly = True key = "MorphPreferences/downloadDirectory" downloadDirectory = slicer.util.settingsValue(key, "", converter=str) if downloadDirectory == "": self.downloadDirectory.setText("Defaults") else: self.downloadDirectory.setText(downloadDirectory) self.setDownloadDirectories(downloadDirectory) self.setDownloadDirectoryButton = qt.QPushButton("Set") self.setDownloadDirectoryButton.connect("clicked()", self.onSetDownloadDirectory) hbox.addWidget(self.downloadDirectory) hbox.addWidget(self.setDownloadDirectoryButton) genericGroupBoxFormLayout.addRow("Download directory:", hbox) vBoxLayout.addWidget(genericGroupBox) vBoxLayout.addStretch(1)
def _addPluginOptionWidgets(self): description = "Edit segment statistics plugin parameters:" if self.pluginName: description = "Edit "+self.pluginName+" plugin parameters:" self.descriptionLabel.text = description if self.pluginName: for plugin in self.logic.plugins: if plugin.name==self.pluginName: self.parametersLayout.addRow(plugin.optionsWidget) else: for plugin in self.logic.plugins: pluginOptionsCollapsibleButton = ctk.ctkCollapsibleGroupBox(self.parametersWidget) pluginOptionsCollapsibleButton.setTitle( plugin.name ) pluginOptionsFormLayout = qt.QFormLayout(pluginOptionsCollapsibleButton) pluginOptionsFormLayout.addRow(plugin.optionsWidget) self.parametersLayout.addRow(pluginOptionsCollapsibleButton)
def __init__(self, parent): vBoxLayout = qt.QVBoxLayout(parent) # AIAA settings aiaaGroupBox = ctk.ctkCollapsibleGroupBox() aiaaGroupBox.title = "AI-Assisted Annotation Server" aiaaGroupLayout = qt.QFormLayout(aiaaGroupBox) serverUrl = qt.QLineEdit() aiaaGroupLayout.addRow("Server address:", serverUrl) parent.registerProperty("NVIDIA-AIAA/serverUrl", serverUrl, "text", str(qt.SIGNAL("textChanged(QString)"))) serverUrlHistory = qt.QLineEdit() aiaaGroupLayout.addRow("Server address history:", serverUrlHistory) parent.registerProperty("NVIDIA-AIAA/serverUrlHistory", serverUrlHistory, "text", str(qt.SIGNAL("textChanged(QString)"))) compressDataCheckBox = qt.QCheckBox() compressDataCheckBox.checked = True compressDataCheckBox.toolTip = ( "Enable this option on computer with slow network upload speed." " Data compression reduces network transfer time but increases preprocessing time." ) aiaaGroupLayout.addRow("Compress data:", compressDataCheckBox) compressDataMapper = ctk.ctkBooleanMapper( compressDataCheckBox, "checked", str(qt.SIGNAL("toggled(bool)"))) parent.registerProperty("NVIDIA-AIAA/compressData", compressDataMapper, "valueAsInt", str(qt.SIGNAL("valueAsIntChanged(int)"))) useSessionCheckBox = qt.QCheckBox() useSessionCheckBox.checked = False useSessionCheckBox.toolTip = ( "Enable this option to make use of AIAA sessions." " Volume is uploaded to AIAA as part of session once and it makes segmentation/dextr3d/deepgrow operations faster." ) aiaaGroupLayout.addRow("AIAA Session:", useSessionCheckBox) useSessionMapper = ctk.ctkBooleanMapper( useSessionCheckBox, "checked", str(qt.SIGNAL("toggled(bool)"))) parent.registerProperty("NVIDIA-AIAA/aiaaSession", useSessionMapper, "valueAsInt", str(qt.SIGNAL("valueAsIntChanged(int)"))) vBoxLayout.addWidget(aiaaGroupBox) vBoxLayout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # This module is often used in developer mode, therefore # collapse reload & test section by default. if hasattr(self, "reloadCollapsibleButton"): self.reloadCollapsibleButton.collapsed = True self.observerTags = [] self.logic = SampleDataLogic(self.logMessage) categories = slicer.modules.sampleDataSources.keys() categories.sort() if 'BuiltIn' in categories: categories.remove('BuiltIn') categories.insert(0, 'BuiltIn') for category in categories: frame = ctk.ctkCollapsibleGroupBox(self.parent) self.layout.addWidget(frame) frame.title = category frame.name = '%sCollapsibleGroupBox' % category layout = qt.QVBoxLayout(frame) for source in slicer.modules.sampleDataSources[category]: name = source.sampleName if not name: name = source.nodeNames[0] b = qt.QPushButton('Download %s' % name) b.name = '%sPushButton' % name layout.addWidget(b) if source.customDownloader: b.connect('clicked()', source.customDownloader) else: b.connect( 'clicked()', lambda s=source: self.logic.downloadFromSource(s)) self.log = qt.QTextEdit() self.log.readOnly = True self.layout.addWidget(self.log) self.logMessage('<p>Status: <i>Idle</i>\n') # Add spacer to layout self.layout.addStretch(1)
def buildGUI(self, parent): connectorGroupBox = ctk.ctkCollapsibleGroupBox() connectorGroupBox.title = self.cname parent.addWidget(connectorGroupBox) connectorFormLayout = qt.QFormLayout(connectorGroupBox) if self.connectorSelector == None: self.connectorSelector = slicer.qMRMLNodeComboBox() self.connectorSelector.nodeTypes = ( ("vtkMRMLIGTLConnectorNode"), "" ) self.connectorSelector.selectNodeUponCreation = True self.connectorSelector.addEnabled = True self.connectorSelector.removeEnabled = False self.connectorSelector.noneEnabled = False self.connectorSelector.showHidden = False self.connectorSelector.showChildNodeTypes = False self.connectorSelector.setMRMLScene( slicer.mrmlScene ) self.connectorSelector.setToolTip( "Establish a connection with the server" ) connectorFormLayout.addRow("Connector: ", self.connectorSelector) if self.portSpinBox == None: self.portSpinBox = qt.QSpinBox() self.portSpinBox.objectName = 'PortSpinBox' self.portSpinBox.setMaximum(64000) self.portSpinBox.setValue(self.port) self.portSpinBox.setToolTip("Port number of the server") connectorFormLayout.addRow("Port: ", self.portSpinBox) # check box to trigger transform conversion if self.activeConnectionCheckBox == None: self.activeConnectionCheckBox = qt.QCheckBox() self.activeConnectionCheckBox.checked = 0 self.activeConnectionCheckBox.enabled = 0 self.activeConnectionCheckBox.setToolTip("Activate OpenIGTLink connection") connectorFormLayout.addRow("Active: ", self.activeConnectionCheckBox) #-------------------------------------------------- # Connections #-------------------------------------------------- self.connectorSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onConnectorSelected) self.activeConnectionCheckBox.connect('toggled(bool)', self.onActiveConnection)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # This module is often used in developer mode, therefore # collapse reload & test section by default. if hasattr(self, "reloadCollapsibleButton"): self.reloadCollapsibleButton.collapsed = True self.observerTags = [] self.logic = SampleDataLogic(self.logMessage) categories = slicer.modules.sampleDataSources.keys() categories.sort() if 'BuiltIn' in categories: categories.remove('BuiltIn') categories.insert(0,'BuiltIn') for category in categories: frame = ctk.ctkCollapsibleGroupBox(self.parent) self.layout.addWidget(frame) frame.title = category frame.name = '%sCollapsibleGroupBox' % category layout = qt.QVBoxLayout(frame) for source in slicer.modules.sampleDataSources[category]: name = source.sampleName if not name: name = source.nodeNames[0] b = qt.QPushButton('Download %s' % name) b.name = '%sPushButton' % name layout.addWidget(b) if source.customDownloader: b.connect('clicked()', source.customDownloader) else: b.connect('clicked()', lambda s=source: self.logic.downloadFromSource(s)) self.log = qt.QTextEdit() self.log.readOnly = True self.layout.addWidget(self.log) self.logMessage('<p>Status: <i>Idle</i>\n') # Add spacer to layout self.layout.addStretch(1)
def __init__(self, columnNames, comboItems): layout = CustomTable.__init__(self, columnNames) self.settingsFormatText = ctk.ctkFittedTextBrowser() self.settingsFormatText.setFrameShape(qt.QFrame.NoFrame) self.settingsFormatText.setFrameShadow(qt.QFrame.Plain) self.settingsFormatText.setCollapsibleText('') gb = ctk.ctkCollapsibleGroupBox() gb.title = 'Settings Format' gb.collapsed = True gblayout = qt.QVBoxLayout(gb) gblayout.addWidget(self.settingsFormatText) layout.addWidget(gb) self.view.setItemDelegateForColumn( 0, ComboDelegate(self.model, comboItems, self.setSettingsFormatTextFromName)) self.view.setItemDelegateForColumn(self.model.columnCount() - 1, TextEditDelegate(self.model))
def setup( self ): ScriptedLoadableModuleWidget.setup(self) # # Logic # self.ptcLogic = PerkTutorCouchDBLogic() # # Save Area # saveCollapsibleButton = ctk.ctkCollapsibleButton() saveCollapsibleButton.text = "Save Session" self.layout.addWidget( saveCollapsibleButton ) # Layout within the collapsible button saveFormLayout = qt.QFormLayout( saveCollapsibleButton ) # User ID input self.saveUserIDLineEdit = qt.QLineEdit() saveFormLayout.addRow( "User ID", self.saveUserIDLineEdit ) # Study ID input self.saveStudyIDLineEdit = qt.QLineEdit() saveFormLayout.addRow("Study ID", self.saveStudyIDLineEdit ) # Trial ID input self.saveTrialIDLineEdit = qt.QLineEdit() saveFormLayout.addRow( "Trial ID", self.saveTrialIDLineEdit ) # skill level selector self.saveSkillSelector = qt.QComboBox() self.saveSkillSelector.addItems( SKILL_LEVEL_SELECTIONS ) saveFormLayout.addRow( "Skill level", self.saveSkillSelector ) # session completed selector self.saveSessionCompletionSelector = qt.QComboBox() self.saveSessionCompletionSelector.addItems( SESSION_COMPLETION_SELECTIONS ) saveFormLayout.addRow( "Status", self.saveSessionCompletionSelector ) # Node to save selector self.saveNodeSelector = slicer.qMRMLNodeComboBox() self.saveNodeSelector.noneEnabled = True self.saveNodeSelector.removeEnabled = False self.saveNodeSelector.addEnabled = False self.saveNodeSelector.renameEnabled = False self.saveNodeSelector.setMRMLScene( slicer.mrmlScene ) saveFormLayout.addRow( "Data", self.saveNodeSelector ) # Save Button self.saveButton = qt.QPushButton( "Save" ) self.saveButton.enabled = True saveFormLayout.addRow( self.saveButton ) # # Search Area # searchCollapsibleButton = ctk.ctkCollapsibleButton() searchCollapsibleButton.text = "Search For Session" self.layout.addWidget( searchCollapsibleButton ) # Layout within the collapsible button searchFormLayout = qt.QFormLayout( searchCollapsibleButton ) # Search user ID field self.searchUserIDLineEdit = qt.QLineEdit() searchFormLayout.addRow( "User ID", self.searchUserIDLineEdit ) # Search study ID field self.searchStudyIDLineEdit = qt.QLineEdit() searchFormLayout.addRow( "Study ID", self.searchStudyIDLineEdit ) # Search trial ID field self.searchTrialIDLineEdit = qt.QLineEdit() searchFormLayout.addRow( "Trial ID", self.searchTrialIDLineEdit ) # Search skill level field self.searchSkillSelector = qt.QComboBox() self.searchSkillSelector.addItems( ( "", ) + SKILL_LEVEL_SELECTIONS ) searchFormLayout.addRow( "Skill level", self.searchSkillSelector ) # Search Button self.searchButton = qt.QPushButton( "Search" ) self.searchButton.enabled = True searchFormLayout.addRow( self.searchButton ) # # Configuration # configurationCollapsibleButton = ctk.ctkCollapsibleButton() configurationCollapsibleButton.text = "Configuration" configurationCollapsibleButton.collapsed = True self.layout.addWidget( configurationCollapsibleButton ) # Layout within the collapsible button configurationVBoxLayout = qt.QVBoxLayout( configurationCollapsibleButton ) settings = slicer.app.userSettings() # # Database # databaseCollapsibleGroupBox = ctk.ctkCollapsibleGroupBox() databaseCollapsibleGroupBox.setTitle( "Remote Database" ) databaseCollapsibleGroupBox.collapsed = True configurationVBoxLayout.addWidget( databaseCollapsibleGroupBox ) # Layout within the group box databaseFormLayout = qt.QFormLayout( databaseCollapsibleGroupBox ) # Database username field self.databaseUsernameLineEdit = qt.QLineEdit() self.databaseUsernameLineEdit.setText( settings.value( self.moduleName + "/DatabaseUsername" ) ) databaseFormLayout.addRow( "Username", self.databaseUsernameLineEdit ) # Database password field self.databasePasswordLineEdit = qt.QLineEdit() self.databasePasswordLineEdit.setEchoMode( qt.QLineEdit.Password ) self.databasePasswordLineEdit.setText( settings.value( self.moduleName + "/DatabasePassword" ) ) databaseFormLayout.addRow( "Password", self.databasePasswordLineEdit ) # Remote database address self.databaseAddressLineEdit = qt.QLineEdit() self.databaseAddressLineEdit.setText( settings.value( self.moduleName + "/DatabaseAddress" ) ) databaseFormLayout.addRow( "Address", self.databaseAddressLineEdit ) # # File Server # fileServerCollapsibleGroupBox = ctk.ctkCollapsibleGroupBox() fileServerCollapsibleGroupBox.setTitle( "File Server" ) fileServerCollapsibleGroupBox.collapsed = True configurationVBoxLayout.addWidget( fileServerCollapsibleGroupBox ) # Layout within the group box fileServerFormLayout = qt.QFormLayout( fileServerCollapsibleGroupBox ) # File server session field self.fileServerSessionLineEdit = qt.QLineEdit() self.fileServerSessionLineEdit.setText( settings.value( self.moduleName + "/FileServerSession" ) ) fileServerFormLayout.addRow( "Session", self.fileServerSessionLineEdit ) # Local storage directory self.fileServerLocalDirectoryLineEdit = qt.QLineEdit() self.fileServerLocalDirectoryLineEdit.setText( settings.value( self.moduleName + "/FileServerLocalDirectory" ) ) fileServerFormLayout.addRow( "Local path", self.fileServerLocalDirectoryLineEdit ) # FTP client self.ftpClientDirectoryLineEdit = qt.QLineEdit() self.ftpClientDirectoryLineEdit.setText( settings.value( self.moduleName + "/FileServerClient" ) ) fileServerFormLayout.addRow( "FTP client", self.ftpClientDirectoryLineEdit ) # Update Button self.updateButton = qt.QPushButton( "Update" ) self.updateButton.enabled = True configurationVBoxLayout.addWidget( self.updateButton ) # # Stretcher # self.layout.addStretch( 1 ) # # Initialize the remote database from the settings at outset (if the settings are already specified) # try: self.ptcLogic.updateDatabase( PERK_TUTOR_DATABASE_NAME ) except Exception as e: logging.warning( e ) # # Connections # self.saveButton.connect( "clicked(bool)", self.onSaveButton ) self.searchButton.connect( "clicked(bool)", self.onSearchButton ) self.updateButton.connect( "clicked(bool)", self.onUpdateButton )
def __init__(self): toolTip = 'Click and drag to deform the image' WarpAbstractEffect.__init__(self, 'Smudge', toolTip) # radius self.radiusSlider = ctk.ctkSliderWidget() self.radiusSlider.singleStep = 0.1 self.radiusSlider.minimum = 5 self.radiusSlider.maximum = float( self.parameterNode.GetParameter("maxRadius")) self.radiusSlider.decimals = 1 self.radiusSlider.value = float( self.parameterNode.GetParameter("SmudgeRadius")) self.radiusSlider.setToolTip('Radius') self.parametersFrame.layout().addRow("Radius (mm):", self.radiusSlider) # hardness self.hardnessSlider = ctk.ctkSliderWidget() self.hardnessSlider.singleStep = 1 self.hardnessSlider.minimum = 0 self.hardnessSlider.maximum = 100 self.hardnessSlider.decimals = 0 self.hardnessSlider.value = float( self.parameterNode.GetParameter("SmudgeHardness")) self.hardnessSlider.setToolTip('Hardness') self.parametersFrame.layout().addRow("Hardness (%):", self.hardnessSlider) # force self.forceSlider = ctk.ctkSliderWidget() self.forceSlider.singleStep = 1 self.forceSlider.minimum = 0 self.forceSlider.maximum = 100 self.forceSlider.decimals = 0 self.forceSlider.value = float( self.parameterNode.GetParameter("SmudgeForce")) self.forceSlider.setToolTip('Force') self.parametersFrame.layout().addRow("Force (%):", self.forceSlider) # advanced advancedParametersGroupBox = ctk.ctkCollapsibleGroupBox() advancedParametersGroupBox.setTitle('Advanced') advancedParametersGroupBox.setLayout(qt.QFormLayout()) advancedParametersGroupBox.collapsed = True self.parametersFrame.layout().addRow(advancedParametersGroupBox) # post smoothing self.postSmoothingCheckBox = qt.QCheckBox('') self.postSmoothingCheckBox.setChecked( int(self.parameterNode.GetParameter("SmudgePostSmoothing"))) self.postSmoothingCheckBox.setToolTip( 'Enable to smooth the added warp once the operation finished.') advancedParametersGroupBox.layout().addRow("Post Smoothing:", self.postSmoothingCheckBox) # post smoothing value self.postSmoothingSlider = ctk.ctkSliderWidget() self.postSmoothingSlider.singleStep = 1 self.postSmoothingSlider.minimum = 0 self.postSmoothingSlider.maximum = 100 self.postSmoothingSlider.decimals = 0 self.postSmoothingSlider.value = float( self.parameterNode.GetParameter("SmudgeSigma")) self.postSmoothingSlider.setToolTip( 'Smoothing sigma as a percentage of the radius.') advancedParametersGroupBox.layout().addRow("Sigma (% Radius):", self.postSmoothingSlider) # expand edge self.expandGridSlider = ctk.ctkSliderWidget() self.expandGridSlider.singleStep = 1 self.expandGridSlider.minimum = 0 self.expandGridSlider.maximum = 100 self.expandGridSlider.decimals = 0 self.expandGridSlider.tracking = False self.expandGridSlider.value = float( self.parameterNode.GetParameter("expandGrid")) self.expandGridSlider.setToolTip( 'Expand the grid being modified. Useful when working with the edges of the image.' ) advancedParametersGroupBox.layout().addRow("Expand Grid (mm):", self.expandGridSlider) # grid boounds self.gridBoundsCheckBox = qt.QCheckBox('') self.gridBoundsCheckBox.setChecked(False) self.gridBoundsCheckBox.setToolTip('Display grid bounds.') advancedParametersGroupBox.layout().addRow("Show grid bounds:", self.gridBoundsCheckBox) self.radiusSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.hardnessSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.forceSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.postSmoothingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI) self.postSmoothingSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.expandGridSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.expandGridSlider.connect('valueChanged(double)', self.resetEffect) self.gridBoundsCheckBox.connect('toggled(bool)', self.onGridBoundsCheckBox)
def setup(self): """ Initialize all form elements """ ScriptedLoadableModuleWidget.setup(self) # Declare Cache path self.CacheDir = os.path.expanduser("~") + "/flywheelIO/" # #################Declare form elements####################### # Give a line_edit and label for the API key self.apiKeyCollapsibleGroupBox = ctk.ctkCollapsibleGroupBox() self.apiKeyCollapsibleGroupBox.setTitle("API Key Entry") self.layout.addWidget(self.apiKeyCollapsibleGroupBox) apiKeyFormLayout = qt.QFormLayout(self.apiKeyCollapsibleGroupBox) # # api Key Text Box # self.apiKeyTextLabel = qt.QLabel("API Key:") apiKeyFormLayout.addWidget(self.apiKeyTextLabel) self.apiKeyTextBox = qt.QLineEdit() self.apiKeyTextBox.setEchoMode(qt.QLineEdit.Password) apiKeyFormLayout.addWidget(self.apiKeyTextBox) self.connectAPIButton = qt.QPushButton("Connect Flywheel") self.connectAPIButton.enabled = True apiKeyFormLayout.addWidget(self.connectAPIButton) self.logAlertTextLabel = qt.QLabel("") apiKeyFormLayout.addWidget(self.logAlertTextLabel) # # CacheDir Text Box # self.cacheDirTextLabel = qt.QLabel("Disk Cache:") apiKeyFormLayout.addWidget(self.cacheDirTextLabel) self.cacheDirTextBox = qt.QLineEdit() self.cacheDirTextBox.setText(self.CacheDir) apiKeyFormLayout.addWidget(self.cacheDirTextBox) # # Use Cache CheckBox # self.useCacheCheckBox = qt.QCheckBox("Cache Images") self.useCacheCheckBox.toolTip = ( """Images cached to "Disk Cache".""" "Otherwise, deleted at every new retrieval." ) apiKeyFormLayout.addWidget(self.useCacheCheckBox) self.useCacheCheckBox.setCheckState(True) self.useCacheCheckBox.setTristate(False) # Data View Section self.dataCollapsibleGroupBox = ctk.ctkCollapsibleGroupBox() self.dataCollapsibleGroupBox.setTitle("Data") self.layout.addWidget(self.dataCollapsibleGroupBox) dataFormLayout = qt.QFormLayout(self.dataCollapsibleGroupBox) # # group Selector ComboBox # self.groupSelectorLabel = qt.QLabel("Current group:") dataFormLayout.addWidget(self.groupSelectorLabel) # Selector ComboBox self.groupSelector = qt.QComboBox() self.groupSelector.enabled = False self.groupSelector.setMinimumWidth(200) dataFormLayout.addWidget(self.groupSelector) # # project Selector ComboBox # self.projectSelectorLabel = qt.QLabel("Current project:") dataFormLayout.addWidget(self.projectSelectorLabel) # Selector ComboBox self.projectSelector = qt.QComboBox() self.projectSelector.enabled = False self.projectSelector.setMinimumWidth(200) dataFormLayout.addWidget(self.projectSelector) # TreeView for Single Projects containers: self.treeView = qt.QTreeView() self.treeView.enabled = False self.treeView.setMinimumWidth(200) self.treeView.setMinimumHeight(350) self.tree_management = TreeManagement(self) dataFormLayout.addWidget(self.treeView) # Load Files Button self.loadFilesButton = qt.QPushButton("Load Selected Files") self.loadFilesButton.enabled = False dataFormLayout.addWidget(self.loadFilesButton) # Upload to Flywheel Button self.uploadFilesButton = qt.QPushButton( "Upload to Flywheel\nas Container Files" ) self.uploadFilesButton.enabled = False dataFormLayout.addWidget(self.uploadFilesButton) # As Analysis Checkbox self.asAnalysisCheck = qt.QCheckBox("As Analysis") self.asAnalysisCheck.toolTip = ( "Upload Files to Flywheel as an Analysis Container." ) self.asAnalysisCheck.enabled = False dataFormLayout.addWidget(self.asAnalysisCheck) # ################# Connect form elements ####################### self.connectAPIButton.connect("clicked(bool)", self.onConnectAPIPushed) self.groupSelector.connect("currentIndexChanged(QString)", self.onGroupSelected) self.projectSelector.connect( "currentIndexChanged(QString)", self.onProjectSelected ) self.loadFilesButton.connect("clicked(bool)", self.onLoadFilesPushed) self.uploadFilesButton.connect("clicked(bool)", self.save_scene_to_flywheel) self.asAnalysisCheck.stateChanged.connect(self.onAnalysisCheckChanged) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = MyModuleLogic() # ------ 1. CREATE LAYOUT AND BUTTONS ------ # Layout setup: 3D Only self.layoutManager = slicer.app.layoutManager() self.layoutManager.setLayout( slicer.vtkMRMLLayoutNode.SlicerLayoutOneUp3DView) # # LOAD DATA # # Create layout collapsibleButtonLoad = ctk.ctkCollapsibleButton() collapsibleButtonLoad.text = "LOAD DATA" # title for layout self.layout.addWidget(collapsibleButtonLoad) formLayout_load = qt.QFormLayout(collapsibleButtonLoad) # Segment 1 Selector self.segment1_pathSelector = ctk.ctkPathLineEdit() self.segment1_pathSelector.enabled = True self.segment1_pathSelector.setMaximumWidth(400) self.segment1_pathSelector.currentPath = slicer.modules.mymodule.path.replace( "MyModule.py", "") + 'Data/Liver1.stl' formLayout_load.addRow("Segment 1: ", self.segment1_pathSelector) # Segment 1 Selector self.segment2_pathSelector = ctk.ctkPathLineEdit() self.segment2_pathSelector.enabled = True self.segment2_pathSelector.setMaximumWidth(400) self.segment2_pathSelector.currentPath = slicer.modules.mymodule.path.replace( "MyModule.py", "") + 'Data/Liver1beforeMM.stl' formLayout_load.addRow("Segment 2: ", self.segment2_pathSelector) # Button to load segments self.loadSegmentsButton = qt.QPushButton( "LOAD MODELS AS SEGMENTS") # text in button self.loadSegmentsButton.toolTip = "Load segments as segments" # hint text for button (appears when cursor is above the button for more than one second) self.loadSegmentsButton.enabled = True # if True it can be clicked formLayout_load.addRow( self.loadSegmentsButton) # include button in layout # # ALIGNMENT # # Create Layout collapsibleButtonAlignment = ctk.ctkCollapsibleButton() collapsibleButtonAlignment.text = "ALIGNMENT" self.layout.addWidget(collapsibleButtonAlignment) formLayout_alignment = qt.QFormLayout(collapsibleButtonAlignment) # Button for masks alignment self.alignSegmentsButton = qt.QPushButton( "ALIGN MODELS") # text in button self.alignSegmentsButton.toolTip = "Align segments" # hint text for button (appears when cursor is above the button for more than one second) self.alignSegmentsButton.enabled = True formLayout_alignment.addRow(self.alignSegmentsButton) # COMPARISON BETWEEN MASKS # # SORENSEN-DICE COEFFICIENT & HOUSDORFF DISTANCE BUTTONS # # Create layout collapsibleButtonComparison = ctk.ctkCollapsibleButton() collapsibleButtonComparison.text = "COMPARISON" # title for layout self.layout.addWidget(collapsibleButtonComparison) formLayout_comparison = qt.QFormLayout(collapsibleButtonComparison) # Button to obtain the Sorensen-Dice Coefficient self.diceCoeffButton = qt.QPushButton( "SORENSEN-DICE COEFFICIENT") # text in button self.diceCoeffButton.toolTip = "Sorensen-Dice Coefficient" # hint text for button (appears when the cursor is above the button for more than one second) self.diceCoeffButton.enabled = True # if true it can be clicked formLayout_comparison.addRow( self.diceCoeffButton) # include button in layout #Button to obtain the Hausdorff Distance self.hausDistButton = qt.QPushButton( "HAUSDORFF DISTANCE") # text in button self.hausDistButton.toolTip = qt.QPushButton( "Hausdorff Distance" ) # hint text for button (appears when the cursor is above the button for more than a second) self.hausDistButton.enabled = True # if true it can be clicked formLayout_comparison.addRow( self.hausDistButton) # include button in layout # # VISUALIZATION # # Create layout collapsibleButtonVisualization = ctk.ctkCollapsibleButton() collapsibleButtonVisualization.text = "VISUALIZATION" # title for layout self.layout.addWidget(collapsibleButtonVisualization) formLayout_visualization = qt.QFormLayout( collapsibleButtonVisualization) # # Segment visibility layout # # Create collapsible button inside layout segmentVisibility_GroupBox = ctk.ctkCollapsibleGroupBox() segmentVisibility_GroupBox.setTitle( "MODEL VISIBILITY") # title for collapsible button segmentVisibility_GroupBox.collapsed = False # if True it appears collapsed formLayout_visualization.addRow( segmentVisibility_GroupBox) # add collapsible button to layout # Create layout inside collapsible button segmentVisibility_GroupBox_Layout = qt.QFormLayout( segmentVisibility_GroupBox) # Create horizontal section segmentVisibilityLayout_1 = qt.QHBoxLayout() segmentVisibility_GroupBox_Layout.addRow( segmentVisibilityLayout_1) # insert section in current layout # Show or Hide Segment 1 in 3D scene self.segment1_checkBox = qt.QCheckBox('Segment 1') # text in checkbox self.segment1_checkBox.checked = True # if True it is initially checked self.segment1_checkBox.enabled = True # if True it can be checked segmentVisibilityLayout_1.addWidget( self.segment1_checkBox) # add checkbox to layout # Show or Hide Segment 2 in 3D scene self.segment2_checkBox = qt.QCheckBox('Segment 2') # text in checkbox self.segment2_checkBox.checked = True # if True it is initially checked self.segment2_checkBox.checked = True # if True it can be checked segmentVisibilityLayout_1.addWidget( self.segment2_checkBox) # add checkbox to layout # # Segment transparency layout # # Create collapsible button inside layout segmentOpacity_GroupBox = ctk.ctkCollapsibleGroupBox() segmentOpacity_GroupBox.setTitle( "MODEL OPACITY") # title for collapsible button segmentOpacity_GroupBox.collapsed = False # if True it appears collapsed formLayout_visualization.addRow( segmentOpacity_GroupBox) # add collapsible button to layout # Create layout inside collapsible button segmentOpacity_GroupBox_Layout = qt.QFormLayout( segmentOpacity_GroupBox) # Create an opacity Value Slider - Segment 1 self.opacityValueSliderWidget_1 = ctk.ctkSliderWidget() self.opacityValueSliderWidget_1.singleStep = 5 # step for range of values to be selected self.opacityValueSliderWidget_1.minimum = 0 # minimum value self.opacityValueSliderWidget_1.maximum = 100 # maximum value self.opacityValueSliderWidget_1.value = 100 # initial value segmentOpacity_GroupBox_Layout.addRow( "[%]: ", self.opacityValueSliderWidget_1) # add slider to layout # Create an opacity Value Slider - Segment 2 self.opacityValueSliderWidget_2 = ctk.ctkSliderWidget() self.opacityValueSliderWidget_2.singleStep = 5 # step for range of values to be selected self.opacityValueSliderWidget_2.minimum = 0 # minimum value self.opacityValueSliderWidget_2.maximum = 100 # maximum value self.opacityValueSliderWidget_2.value = 100 # initial value segmentOpacity_GroupBox_Layout.addRow( "[%]: ", self.opacityValueSliderWidget_2) # add slider to layout # # COLOR MAP # collapsibleButtonColorMap = ctk.ctkCollapsibleButton() collapsibleButtonColorMap.text = "COLOR MAP" self.layout.addWidget(collapsibleButtonColorMap) formLayout_colorMap = qt.QFormLayout(collapsibleButtonColorMap) self.showColorMapButton = qt.QPushButton( "SHOW COLOR MAP") # text in button self.showColorMapButton.toolTip = "Align segments" # hint text for button (appears when cursor is above the button for more than one second) self.showColorMapButton.enabled = True formLayout_colorMap.addRow(self.showColorMapButton) # Displayed Range group box self.displayedRange_GroupBox = ctk.ctkCollapsibleGroupBox() self.displayedRange_GroupBox.setTitle("Displayed Range") self.displayedRange_GroupBox.collapsed = False self.displayedRange_GroupBox.enabled = False formLayout_colorMap.addRow(self.displayedRange_GroupBox) displayedRange_GroupBox_Layout = qt.QFormLayout( self.displayedRange_GroupBox) displayedRange_H_Layout = qt.QHBoxLayout() displayedRange_GroupBox_Layout.addRow(displayedRange_H_Layout) ## Minimum value - displayed range self.minDisplayedRange_SpinBox = qt.QDoubleSpinBox() self.minDisplayedRange_SpinBox.setMaximum(40.0) self.minDisplayedRange_SpinBox.setMinimum(-40.0) self.minDisplayedRange_SpinBox.setSingleStep(0.1) self.minDisplayedRange_SpinBox.enabled = True self.minDisplayedRange_SpinBox.value = 0.0 displayedRange_H_Layout.addWidget(self.minDisplayedRange_SpinBox) ## Displayed range Slider self.displayedRange_SliderWidget = ctk.ctkDoubleRangeSlider() self.displayedRange_SliderWidget.setValues(0.0, 10.0) self.displayedRange_SliderWidget.orientation = 1 self.displayedRange_SliderWidget.singleStep = 0.1 self.displayedRange_SliderWidget.minimum = -40.0 self.displayedRange_SliderWidget.maximum = 40.0 displayedRange_H_Layout.addWidget(self.displayedRange_SliderWidget) ## Maximum value - displayed range self.maxDisplayedRange_SpinBox = qt.QDoubleSpinBox() self.maxDisplayedRange_SpinBox.setMaximum(40.0) self.maxDisplayedRange_SpinBox.setMinimum(-40.0) self.maxDisplayedRange_SpinBox.setSingleStep(0.1) self.maxDisplayedRange_SpinBox.enabled = True self.maxDisplayedRange_SpinBox.value = 10.0 displayedRange_H_Layout.addWidget(self.maxDisplayedRange_SpinBox) # Scalar Bar Visibility Checkbox self.ScalarBar_visibility_checkBox = qt.QCheckBox('Scalar Bar Visible') self.ScalarBar_visibility_checkBox.checked = True displayedRange_GroupBox_Layout.addRow( self.ScalarBar_visibility_checkBox) # Add vertical spacing self.layout.addStretch(1) # ------ 2. CONNECT BUTTONS WITH FUNCTIONS ------ # Connect each button with a function self.loadSegmentsButton.connect( 'clicked(bool)', self.onloadSegmentsButton ) # when the button is pressed we call the function onLoadSegment1Button self.segment1_checkBox.connect('stateChanged(int)', self.onupdateSegment1Visibility) self.segment2_checkBox.connect('stateChanged(int)', self.onupdateSegment2Visibility) self.opacityValueSliderWidget_1.connect("valueChanged(double)", self.onupdateSegment1Opacity) self.opacityValueSliderWidget_2.connect("valueChanged(double)", self.onupdateSegment2Opacity) self.alignSegmentsButton.connect('clicked(bool)', self.onAlignSegmentsButton) self.diceCoeffButton.connect('clicked(bool)', self.onDiceCoeffButton) self.hausDistButton.connect('clicked(bool)', self.onHausdorffDistButton) self.showColorMapButton.connect('clicked(bool)', self.onShowColorMapButton) self.displayedRange_SliderWidget.connect( "valuesChanged(double,double)", self.onDisplayedRangeSliderChanged) self.minDisplayedRange_SpinBox.connect( "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged) self.maxDisplayedRange_SpinBox.connect( "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged) self.ScalarBar_visibility_checkBox.connect( 'stateChanged(int)', self.onScalarBarVisibilityChecked)
def setupOptionsFrame(self): self.frame = qt.QFrame(self.scriptedEffect.optionsFrame()) qt.QFormLayout(self.frame) #Save space in the GUI self.frame.layout().setSpacing(0) self.frame.layout().setMargin(0) # self.helpLabel = qt.QLabel(self.frame) # self.helpLabel.setWordWrap(True) # #self.helpLabel.sizePolicy.setHorizontalPolicy(qt.QSizePolicy.Ignored) # #self.helpLabel.sizePolicy.setVerticalPolicy(qt.QSizePolicy.Ignored) # self.helpLabel.text = "Click on a lesion to start segmentation. \ # 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. \ # See <a href=\"https://www.slicer.org/wiki/Documentation/Nightly/Extensions/PETTumorSegmentation\">the documentation</a> for more information." # self.scriptedEffect.addOptionsWidget(self.helpLabel) # 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) #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.scriptedEffect.addOptionsWidget(self.refinementBoxesFrame) #options are hidden (collapsed) until requested self.optFrame = ctk.ctkCollapsibleGroupBox(self.frame) self.optFrame.setTitle("Options") self.optFrame.setLayout(qt.QVBoxLayout()) self.optFrame.visible = True self.optFrame.collapsed = True 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) #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) #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) #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.scriptedEffect.addOptionsWidget(self.optFrame) #advanced options, for abnormal cases such as massive necrotic objects or #low-transition scans like phantoms #infrequently used, just keep vertical self.advFrame = ctk.ctkCollapsibleGroupBox(self.frame) self.advFrame.setTitle("Advanced") self.advFrame.setLayout(qt.QVBoxLayout()) self.advFrame.visible = True self.advFrame.collapsed = True 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) #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) #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.optFrame.layout().addWidget(self.advFrame) #apply button kept at bottom of all options self.applyButton = qt.QPushButton("Apply", self.frame) self.optFrame.layout().addWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApplyParameters) self.applyButton.setToolTip( "Redo last segmentation with the same center and refinement points with any changes in options." )
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... self.dockerGroupBox = ctk.ctkCollapsibleGroupBox() self.dockerGroupBox.setTitle('Docker Settings') self.layout.addWidget(self.dockerGroupBox) dockerForm = qt.QFormLayout(self.dockerGroupBox) self.dockerPath = ctk.ctkPathLineEdit() # self.dockerPath.setMaximumWidth(300) if platform.system() == 'Darwin': self.dockerPath.setCurrentPath('/usr/local/bin/docker') if platform.system() == 'Linux': self.dockerPath.setCurrentPath('/usr/bin/docker') if platform.system() == 'Windows': self.dockerPath.setCurrentPath( "C:/Program Files/Docker/Docker/resources/bin/docker.exe") ### use nvidia-docker if it is installed nvidiaDockerPath = self.dockerPath.currentPath.replace( 'bin/docker', 'bin/nvidia-docker') if os.path.isfile(nvidiaDockerPath): self.dockerPath.setCurrentPath(nvidiaDockerPath) self.downloadButton = qt.QPushButton('Download') self.downloadButton.connect('clicked(bool)', self.onDownloadButton) dockerForm.addRow("Docker Executable Path:", self.dockerPath) dockerForm.addRow("Download the docker image:", self.downloadButton) self.progressDownload = qt.QProgressBar() self.progressDownload.setRange(0, 100) self.progressDownload.setValue(0) self.progressDownload.hide() self.dockerVolumePath = ctk.ctkPathLineEdit() defaultVolumePath = os.path.join(expanduser("~"), ".dockerVolume") if not os.path.exists(defaultVolumePath): os.makedirs(defaultVolumePath) self.dockerVolumePath.setCurrentPath(defaultVolumePath) dockerForm.addRow("Docker Volume Directory:", self.dockerVolumePath) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputVolumeSelector = slicer.qMRMLNodeComboBox() self.inputVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputVolumeSelector.selectNodeUponCreation = True self.inputVolumeSelector.addEnabled = False self.inputVolumeSelector.removeEnabled = False self.inputVolumeSelector.noneEnabled = False self.inputVolumeSelector.showHidden = False self.inputVolumeSelector.showChildNodeTypes = False self.inputVolumeSelector.setMRMLScene(slicer.mrmlScene) self.inputVolumeSelector.setCurrentNode(None) self.inputVolumeSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Volume: ", self.inputVolumeSelector) # # Apply Button # self.applyButton = qt.QPushButton("Generate Probablity Map") self.applyButton.toolTip = "Generate the probablity map." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # # output vessel model selector # self.outputModelSelector = slicer.qMRMLNodeComboBox() self.outputModelSelector.nodeTypes = ["vtkMRMLModelNode"] self.outputModelSelector.selectNodeUponCreation = True self.outputModelSelector.addEnabled = True self.outputModelSelector.removeEnabled = True self.outputModelSelector.noneEnabled = True self.outputModelSelector.showHidden = False self.outputModelSelector.showChildNodeTypes = False self.outputModelSelector.setMRMLScene(slicer.mrmlScene) self.outputModelSelector.setToolTip( "Pick the output to the algorithm.") parametersFormLayout.addRow("Output vessel model: ", self.outputModelSelector) # # threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 0.01 self.imageThresholdSliderWidget.minimum = 0.5 self.imageThresholdSliderWidget.maximum = 1.0 self.imageThresholdSliderWidget.value = 0.9 self.imageThresholdSliderWidget.setToolTip( "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero." ) parametersFormLayout.addRow("Image threshold", self.imageThresholdSliderWidget) self.createVesselModelButton = qt.QPushButton("Create Vessel Model") self.createVesselModelButton.toolTip = "Generate the vessel model." self.createVesselModelButton.enabled = False parametersFormLayout.addRow(self.createVesselModelButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.createVesselModelButton.connect('clicked(bool)', self.onCreateModelWithThreshold) self.inputVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectVolume) self.outputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectModel) # Add vertical spacer self.layout.addStretch(1) self.logic = DockerVesselSegLogic()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = ARHealthLogic() # Layout setup self.layoutManager = slicer.app.layoutManager() self.setCustomLayout() self.layoutManager.setLayout(self.customLayout_1_ID) # Set 3D only view layout #-------------------------------------------------------# #------------------- Load Models -----------------------# #-------------------------------------------------------# # Creacion layout self.collapsibleButtonInit = ctk.ctkCollapsibleButton() self.collapsibleButtonInit.text = "INITIALIZATION" self.collapsibleButtonInit.collapsed = False self.layout.addWidget(self.collapsibleButtonInit) formLayout_init = qt.QFormLayout(self.collapsibleButtonInit) # Reset button self.resetButton = qt.QPushButton("RESET") self.resetButton.toolTip = "Reset scene." self.resetButton.enabled = True formLayout_init.addRow(self.resetButton) # Mode selection self.modeSelection_GroupBox = ctk.ctkCollapsibleGroupBox() self.modeSelection_GroupBox.setTitle("Mode") self.modeSelection_GroupBox.enabled = True formLayout_init.addRow(self.modeSelection_GroupBox) modeSelection_GroupBox_Layout = qt.QFormLayout(self.modeSelection_GroupBox) modeSelection_H_Layout = qt.QHBoxLayout() modeSelection_GroupBox_Layout.addRow(modeSelection_H_Layout) ## Visualization mode radio button self.mode1_radioButton = qt.QRadioButton('Visualization') self.mode1_radioButton.checked = True modeSelection_H_Layout.addWidget(self.mode1_radioButton) ## Registration mode radio button self.mode2_radioButton = qt.QRadioButton('Registration') modeSelection_H_Layout.addWidget(self.mode2_radioButton) ## Mode icons display icons_path = slicer.modules.arhealth.path.replace("ARHealth.py", "") + "Resources/Icons/" self.mode_1_icon = qt.QLabel() self.mode_1_icon_pixmap = qt.QPixmap(icons_path + '/Mode1.jpg') self.mode_1_icon.setPixmap(self.mode_1_icon_pixmap.scaledToWidth(400)) self.mode_1_icon.visible = True modeSelection_GroupBox_Layout.addRow(self.mode_1_icon) self.mode_2_icon = qt.QLabel() self.mode_2_icon_pixmap = qt.QPixmap(icons_path + '/Mode2.jpg') self.mode_2_icon.setPixmap(self.mode_2_icon_pixmap.scaledToWidth(400)) self.mode_2_icon.visible = False modeSelection_GroupBox_Layout.addRow(self.mode_2_icon) # Button Load Marker Model self.loadMarkerButton = qt.QPushButton("Load Marker Model") self.loadMarkerButton.toolTip = "Load Marker Model" self.loadMarkerButton.enabled = True formLayout_init.addRow(self.loadMarkerButton) """ # Text to load model self.inputModel_label = qt.QLabel("Model Path: ") self.inputModel_textInput = qt.QLineEdit() self.inputModel_textInput.text = "" formLayout_init.addRow(self.inputModel_label, self.inputModel_textInput) """ ## Load Models self.LoadModelsGroupBox = ctk.ctkCollapsibleGroupBox() self.LoadModelsGroupBox.setTitle("Load Models") self.LoadModelsGroupBox.collapsed = True formLayout_init.addRow(self.LoadModelsGroupBox) LoadModelsGroupBox_Layout = qt.QFormLayout(self.LoadModelsGroupBox) # Data Stream File Path Selector self.modelsPathEdit = ctk.ctkPathLineEdit() self.modelsPathEdit.enabled = False LoadModelsGroupBox_Layout.addRow("Model Path: ", self.modelsPathEdit) # Button to load model self.loadModelButton = qt.QPushButton("Load Model") self.loadModelButton.toolTip = "Load Model" self.loadModelButton.enabled = False LoadModelsGroupBox_Layout.addRow(self.loadModelButton) # Create List self.modelsListWidget = qt.QListWidget() LoadModelsGroupBox_Layout.addRow(self.modelsListWidget) # Create buttons to delete models o delete all deleteOneOrAllModels_Layout = qt.QHBoxLayout() LoadModelsGroupBox_Layout.addRow(deleteOneOrAllModels_Layout) self.removeSelectedModelButton = qt.QPushButton("Remove Model") self.removeSelectedModelButton.enabled = False deleteOneOrAllModels_Layout.addWidget(self.removeSelectedModelButton) self.removeAllModelsButton = qt.QPushButton("Remove All") self.removeAllModelsButton.enabled = False deleteOneOrAllModels_Layout.addWidget(self.removeAllModelsButton) # Button to move models to origin self.moveToOriginlButton = qt.QPushButton("Finish and Center") self.moveToOriginlButton.enabled = False formLayout_init.addRow(self.moveToOriginlButton) # self.layout.addStretch(1) #-------------------------------------------------------# #------------------- Positioning -----------------------# #-------------------------------------------------------# # Creacion layout self.collapsibleButtonPos = ctk.ctkCollapsibleButton() self.collapsibleButtonPos.text = "POSITIONING" self.collapsibleButtonPos.collapsed = True # self.collapsibleButtonPos.enabled = False self.layout.addWidget(self.collapsibleButtonPos) formLayout_pos = qt.QFormLayout(self.collapsibleButtonPos) ## Base Model Height self.BaseGroupBox = ctk.ctkCollapsibleGroupBox() self.BaseGroupBox.setTitle("AR Marker Adaptor Height") self.BaseGroupBox.visible = False formLayout_pos.addRow(self.BaseGroupBox) BaseGroupBox_Layout = qt.QFormLayout(self.BaseGroupBox) self.baseHeightSliderWidget = ctk.ctkSliderWidget() self.baseHeightSliderWidget.singleStep = 10 self.baseHeightSliderWidget.minimum = 10 self.baseHeightSliderWidget.maximum = 50 self.baseHeightSliderWidget.value = 10 BaseGroupBox_Layout.addRow("[mm]: ", self.baseHeightSliderWidget) ## Slider Scale ScaleGroupBox = ctk.ctkCollapsibleGroupBox() ScaleGroupBox.setTitle("Scale") formLayout_pos.addRow(ScaleGroupBox) ScaleGroupBox_Layout = qt.QFormLayout(ScaleGroupBox) self.scaleSliderWidget = ctk.ctkSliderWidget() self.scaleSliderWidget.singleStep = 1 self.scaleSliderWidget.minimum = 0.0000000001 self.scaleSliderWidget.maximum = 500 self.scaleSliderWidget.value = 100 ScaleGroupBox_Layout.addRow("[%]: ", self.scaleSliderWidget) ## Slider Translation TranslationGroupBox = ctk.ctkCollapsibleGroupBox() TranslationGroupBox.setTitle("Translation") formLayout_pos.addRow(TranslationGroupBox) TranlationGroupBox_Layout = qt.QFormLayout(TranslationGroupBox) self.lrTranslationSliderWidget = ctk.ctkSliderWidget() self.lrTranslationSliderWidget.singleStep = 0.5 self.lrTranslationSliderWidget.minimum = -1000 self.lrTranslationSliderWidget.maximum = 1000 self.lrTranslationSliderWidget.value = 0 self.lrTranslationSliderWidget.setToolTip("Z Translation Transform") TranlationGroupBox_Layout.addRow("LR: ", self.lrTranslationSliderWidget) self.paTranslationSliderWidget = ctk.ctkSliderWidget() self.paTranslationSliderWidget.singleStep = 0.5 self.paTranslationSliderWidget.minimum = -1000 self.paTranslationSliderWidget.maximum = 1000 self.paTranslationSliderWidget.value = 0 self.paTranslationSliderWidget.setToolTip("Z Translation Transform") TranlationGroupBox_Layout.addRow("PA: ", self.paTranslationSliderWidget) self.isTranslationSliderWidget = ctk.ctkSliderWidget() self.isTranslationSliderWidget.singleStep = 0.5 self.isTranslationSliderWidget.minimum = -1000 self.isTranslationSliderWidget.maximum = 1000 self.isTranslationSliderWidget.value = 0 self.isTranslationSliderWidget.setToolTip("Z Translation Transform") TranlationGroupBox_Layout.addRow("IS: ", self.isTranslationSliderWidget) ## Slider Rotation RotationGroupBox = ctk.ctkCollapsibleGroupBox() RotationGroupBox.setTitle("Rotation") formLayout_pos.addRow(RotationGroupBox) RotationGroupBox_Layout = qt.QFormLayout(RotationGroupBox) self.lrRotationSliderWidget = ctk.ctkSliderWidget() self.lrRotationSliderWidget.singleStep = 1 self.lrRotationSliderWidget.minimum = -180 self.lrRotationSliderWidget.maximum = 180 self.lrRotationSliderWidget.value = 0 self.lrRotationSliderWidget.setToolTip("LR Rotation") RotationGroupBox_Layout.addRow("LR: ", self.lrRotationSliderWidget) self.paRotationSliderWidget = ctk.ctkSliderWidget() self.paRotationSliderWidget.singleStep = 1 self.paRotationSliderWidget.minimum = -180 self.paRotationSliderWidget.maximum = 180 self.paRotationSliderWidget.value = 0 self.paRotationSliderWidget.setToolTip("PA Rotation") RotationGroupBox_Layout.addRow("PA: ", self.paRotationSliderWidget) self.isRotationSliderWidget = ctk.ctkSliderWidget() self.isRotationSliderWidget.singleStep = 1 self.isRotationSliderWidget.minimum = -180 self.isRotationSliderWidget.maximum = 180 self.isRotationSliderWidget.value = 0 self.isRotationSliderWidget.setToolTip("IS Rotation") RotationGroupBox_Layout.addRow("IS: ", self.isRotationSliderWidget) ## Button reset self.resetPosButton = qt.QPushButton("Reset Position") self.resetPosButton.enabled = True formLayout_pos.addRow(self.resetPosButton) """ #-------------------------------------------------------# #------------------- Appereance -----------------------# #-------------------------------------------------------# # Init layout collapsibleButtonAppereance = ctk.ctkCollapsibleButton() collapsibleButtonAppereance.text = "Appereance" self.layout.addWidget(collapsibleButtonAppereance) formLayout_init = qt.QFormLayout(collapsibleButtonAppereance) """ #-------------------------------------------------------# #------------------- Save Models -----------------------# #-------------------------------------------------------# # Init layout self.collapsibleButtonSaveModels = ctk.ctkCollapsibleButton() self.collapsibleButtonSaveModels.text = "SAVE MODELS" self.collapsibleButtonSaveModels.collapsed = True self.layout.addWidget(self.collapsibleButtonSaveModels) formLayout_saveModels = qt.QFormLayout(self.collapsibleButtonSaveModels) # Data Stream File Path Selector self.saveDirectoryButton = ctk.ctkDirectoryButton() formLayout_saveModels.addRow("Save Model Path: ", self.saveDirectoryButton) # Button to load model self.saveModelButton = qt.QPushButton("Save Models") self.saveModelButton.toolTip = "Save Models" self.saveModelButton.enabled = False formLayout_saveModels.addRow(self.saveModelButton) # incluimos el boton al layout # Info Save Models self.saveModels_InfoText = qt.QLabel('') formLayout_saveModels.addRow(self.saveModels_InfoText) self.layout.addStretch(1) ######################################################################################### ######################################################################################### ######################################################################################### # Connections self.resetButton.connect("clicked(bool)", self.onResetButton) self.mode1_radioButton.connect('clicked(bool)', self.onModeSelected) self.mode2_radioButton.connect('clicked(bool)', self.onModeSelected) self.loadMarkerButton.connect("clicked(bool)", self.onLoadMarkerButton) self.loadModelButton.connect("clicked(bool)", self.onLoadModelsButton) self.removeSelectedModelButton.connect("clicked(bool)", self.onRemoveSelectedModelButton) self.removeAllModelsButton.connect("clicked(bool)", self.onRemoveAllModelsButton) self.moveToOriginlButton.connect("clicked(bool)", self.onMoveToOriginlButton) self.baseHeightSliderWidget.connect("valueChanged(double)", self.onBaseHeightSliderWidgetChanged) self.scaleSliderWidget.connect("valueChanged(double)", self.onScaleSliderWidgetChanged) self.lrTranslationSliderWidget.connect("valueChanged(double)", self.onLRTranslationSliderWidgetChanged) self.paTranslationSliderWidget.connect("valueChanged(double)", self.onPATranslationSliderWidgetChanged) self.isTranslationSliderWidget.connect("valueChanged(double)", self.onISTranslationSliderWidgetChanged) self.lrRotationSliderWidget.connect("valueChanged(double)", self.onLRRotationSliderWidgetChanged) self.paRotationSliderWidget.connect("valueChanged(double)", self.onPARotationSliderWidgetChanged) self.isRotationSliderWidget.connect("valueChanged(double)", self.onISRotationSliderWidgetChanged) self.resetPosButton.connect("clicked(bool)", self.onResetPosButton) self.saveModelButton.connect("clicked(bool)", self.onsaveModelButton)
def setup(self): self.developerMode = True ScriptedLoadableModuleWidget.setup(self) self.logic = RegistrationLogic() self.cropVolumeParameterNode = slicer.vtkMRMLCropVolumeParametersNode() # why initializing them here? self.VIEW_MODE_Preop_Only = 0 self.VIEW_MODE_Intraop_Only = 1 self.VIEW_MODE_ThreeCompare = 2 self.VIEW_MODE_Axial = 3 self.VIEW_MODE_Sagittal = 4 self.VIEW_MODE_Coronal = 5 self.PREOP_VOLUME = None self.INTRAOP_VOLUME = None volumes = slicer.util.getNodesByClass("vtkMRMLScalarVolumeNode") for i in range(0,len(volumes)): if 'Preop' in volumes[i].GetName(): self.PREOP_VOLUME = volumes[i] elif 'Intraop' in volumes[i].GetName(): self.INTRAOP_VOLUME = volumes[i] scansCollapsibleButton = ctk.ctkCollapsibleButton() scansCollapsibleButton.text = "Volumes" self.layout.addWidget(scansCollapsibleButton) scansFormLayout = qt.QFormLayout(scansCollapsibleButton) # Layout within the dummy collapsible button # input inputBackVol self.inputBackVol = slicer.qMRMLNodeComboBox() self.inputBackVol.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputBackVol.selectNodeUponCreation = True self.inputBackVol.setAutoFillBackground(self.INTRAOP_VOLUME) self.inputBackVol.addEnabled = False self.inputBackVol.removeEnabled = False self.inputBackVol.noneEnabled = True self.inputBackVol.showHidden = False self.inputBackVol.showChildNodeTypes = False self.inputBackVol.setMRMLScene( slicer.mrmlScene ) self.inputBackVol.setToolTip( "Pick the input scan to the algorithm." ) # self.layout.addWidget("Input Background Volume: ", self.inputBackVol) # input vol node connection self.inputBackVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputBackVol) # input inputBackVol self.inputForVol = slicer.qMRMLNodeComboBox() self.inputForVol.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputForVol.selectNodeUponCreation = True self.inputForVol.setAutoFillBackground(self.PREOP_VOLUME) self.inputForVol.addEnabled = False self.inputForVol.removeEnabled = False self.inputForVol.noneEnabled = True self.inputForVol.showHidden = False self.inputForVol.showChildNodeTypes = False self.inputForVol.setMRMLScene( slicer.mrmlScene ) self.inputForVol.setToolTip( "Pick the input scan to the algorithm." ) # self.layout.addWidget("Input Foreground Volume: ", self.inputForVol) # input vol node connection self.inputForVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputForVol) scansFormLayout.addRow("Input Intraop Volume: ", self.inputBackVol) scansFormLayout.addRow("Input Preop Volume: ", self.inputForVol) # # ROI Area # self.roiCollapsibleGroupBox = ctk.ctkCollapsibleGroupBox() self.roiCollapsibleGroupBox.title = "Define ROI" self.roiCollapsibleGroupBox.collapsed = True self.layout.addWidget(self.roiCollapsibleGroupBox) # Layout within the dummy collapsible button roiFormLayout = qt.QFormLayout(self.roiCollapsibleGroupBox) # input intraop/fixed volume selector self.inputVol = slicer.qMRMLNodeComboBox() self.inputVol.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputVol.selectNodeUponCreation = True self.inputVol.setAutoFillBackground(False) self.inputVol.addEnabled = False self.inputVol.removeEnabled = False self.inputVol.noneEnabled = True self.inputVol.showHidden = False self.inputVol.showChildNodeTypes = False self.inputVol.setMRMLScene( slicer.mrmlScene ) self.inputVol.setToolTip( "Pick the input scan to the algorithm." ) roiFormLayout.addRow("Input Volume: ", self.inputVol) # input vol node connection self.inputVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputVol) # ROI Buttons self.defineROIButton = qt.QPushButton("Define ROI") self.defineROIButton.enabled = False self.defineROIButton.toolTip = "Define the region/vertebrae of the interest" self.applyROIButton = qt.QPushButton("Crop the ROI") self.applyROIButton.enabled = False self.defineROIButton.toolTip = "Crop the region/vertebrae of the interest" # place them on GUI side by side roiFormLayout.addWidget(self.createHLayout([self.defineROIButton, self.applyROIButton])) self.defineROIButton.connect("clicked(bool)", self.onDefineROIButton) self.applyROIButton.connect("clicked(bool)", self.onApplyROIButton) self.thresholdGroupBox = ctk.ctkCollapsibleGroupBox() self.thresholdGroupBox.title = "Generate Mesh" self.thresholdGroupBox.collapsed = True roiFormLayout.addRow(self.thresholdGroupBox) self.thresholdGroupBox.connect('clicked(bool)' , self.onGenerateMeshGroupBox) thresholdGroupBoxLayout = qt.QFormLayout(self.thresholdGroupBox) # threshold value self.threshold = ctk.ctkRangeWidget() self.threshold.spinBoxAlignment = 0xff # put enties on top self.threshold.singleStep = 0.1 self.threshold.minimum = -1000 self.threshold.maximum = 3000 self.threshold.setToolTip( "Set the range of the background values that should be labeled.") thresholdGroupBoxLayout.addRow("Image threshold", self.threshold) # Generate Mesh based on the cursour movment self.generateMeshButton = qt.QPushButton("Generate Mesh") self.generateMeshButton.enabled = False self.generateMeshButton.toolTip = "Crop the region/vertebrae of the interest" # place them on GUI side by side thresholdGroupBoxLayout.addRow(self.generateMeshButton) self.generateMeshButton.connect('clicked()', self.onMeshButton) # connection # Instantiate and connect widgets ... self.displayLayoutBox = qt.QGroupBox('Display Layout') self.displayLayout = qt.QGridLayout() self.displayLayoutBox.setLayout(self.displayLayout) self.layout.addWidget(self.displayLayoutBox) # button to only show preop volume self.PreopOnlyButton = qt.QPushButton("Preop Only") self.PreopOnlyButton.name = "Preop Only" self.PreopOnlyButton.setCheckable(True) self.PreopOnlyButton.setFlat(True) self.displayLayout.addWidget(self.PreopOnlyButton, 0, 0) self.PreopOnlyButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Preop_Only)) # button to only show intraop volume self.IntraopOnlyButton = qt.QPushButton("Intraop Only") self.IntraopOnlyButton.name = "Intraop Only" self.IntraopOnlyButton.setCheckable(True) self.IntraopOnlyButton.setFlat(True) self.displayLayout.addWidget(self.IntraopOnlyButton, 0, 1) self.IntraopOnlyButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Intraop_Only)) # button to show the overalp of the intraop and preop volumes self.OverlapButton = qt.QPushButton("Ax/Sa/Co") self.OverlapButton.name = "Ax/Sa/Co" self.OverlapButton.setCheckable(True) self.OverlapButton.setFlat(True) self.displayLayout.addWidget(self.OverlapButton, 0, 2) self.OverlapButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_ThreeCompare)) # button to only show Axial view of preop, intraop, and overlap self.AxialButton = qt.QPushButton("Axial View") self.AxialButton.name = "Axial View" self.AxialButton.setCheckable(True) self.AxialButton.setFlat(True) self.displayLayout.addWidget(self.AxialButton, 1, 0) self.AxialButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Axial)) # button to only show Sagittal view of preop, intraop, and overlap self.SagittalButton = qt.QPushButton("Sagittal View") self.SagittalButton.name = "Sagittal View" self.SagittalButton.setCheckable(True) self.SagittalButton.setFlat(True) self.displayLayout.addWidget(self.SagittalButton, 1, 1) self.SagittalButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Sagittal)) # button to only show Coronal view of preop, intraop, and overlap self.CoronalButton = qt.QPushButton("Coronal View") self.CoronalButton.name = "Coronal View" self.CoronalButton.setCheckable(True) self.CoronalButton.setFlat(True) self.displayLayout.addWidget(self.CoronalButton, 1, 2) self.CoronalButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Coronal)) # extra visualization self.VisualizationGroupBox = ctk.ctkCollapsibleGroupBox() self.VisualizationGroupBox.title = "Visualization" self.VisualizationGroupBox.collapsed = True self.layout.addWidget(self.VisualizationGroupBox) VisualizationFormLayout = qt.QFormLayout(self.VisualizationGroupBox) self.visualizationWidget = RegistrationLib.VisualizationWidget(self.logic) b = self.visualizationWidget.widget allChildren = b.children()[1].children()[1].children() groupbox = b.children()[1].children()[1] groupbox.setTitle('') allChildren[1].hide() allChildren[2].hide() allChildren[3].hide() allChildren[4].hide() VisualizationFormLayout.addWidget(b) # Landmark Registration Area fiducialregistrationwizardModuleWidget = slicer.modules.fiducialregistrationwizard.createNewWidgetRepresentation() fiducialregistrationwizardModuleWidgetGroupBoxes = fiducialregistrationwizardModuleWidget.findChildren("ctkCollapsibleGroupBox") fiducialregistrationwizardModuleWidgetQGroupBoxes = fiducialregistrationwizardModuleWidget.findChildren("QGroupBox") self.FidRegWizRegResultComboBox = fiducialregistrationwizardModuleWidgetQGroupBoxes[3].children()[1] fiducialregistrationwizardModuleWidgetGroupBoxes[2].hide() #hide the landmark from transform # hide extra crap extra = fiducialregistrationwizardModuleWidget.children()[1].children() self.FiducialRegWizNode = slicer.vtkMRMLFiducialRegistrationWizardNode() slicer.mrmlScene.AddNode(self.FiducialRegWizNode) tag = self.FiducialRegWizNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.onFiducialRegWizNode) extra[1].setCurrentNode(self.FiducialRegWizNode) extra[1].hide() extra[3].hide() extra[4].hide() #registrationResult = extra[8] #initialregTransformBox = registrationResult.children()[1] #self.initialLandmarkTransform #initialregTransformBox.setCurrentNode(slicer.util.getNode('FromPreopToIntraopInitialTransform')) fiducialregistrationwizardModuleWidgetCollapsibleButton = fiducialregistrationwizardModuleWidget.findChildren("ctkCollapsibleButton") fiducialregistrationwizardModuleWidgetCollapsibleButton[0].setText('Landmark Registration') fiducialregistrationwizardModuleWidgetCollapsibleButton[0].collapsed = True #fiducialregistrationwizardModuleWidgetGroupBoxes[3].setText('') self.layout.addWidget(fiducialregistrationwizardModuleWidget) AutoCollapsibleButton = ctk.ctkCollapsibleButton() AutoCollapsibleButton.text = "Auto Registrationn" self.layout.addWidget(AutoCollapsibleButton) AutoCollapsibleButton.collapsed = True # Layout within the dummy collapsible button autoFormLayout = qt.QFormLayout(AutoCollapsibleButton) self.rigidCheckmarkBox = qt.QCheckBox() self.rigidCheckmarkBox.checked = 1 self.rigidCheckmarkBox.setToolTip("If checked, the rigid registration is performed (6 DOF)") self.rigidscaleCheckmarkBox = qt.QCheckBox() self.rigidscaleCheckmarkBox.checked = 0 self.rigidscaleCheckmarkBox.setToolTip("If checked, the rigid and scaling is performed (7 DOF)") # Auto Rigid Registration Button self.autoRegButton = qt.QPushButton("Run Registration") self.autoRegButton.toolTip = "Run the automatic brains rigid registration algorithm." self.autoRegButton.enabled = True self.autoRegButton.connect('clicked(bool)', self.onautoRegButton) # connection # input moving mesh self.inputMovingMesh = slicer.qMRMLNodeComboBox() self.inputMovingMesh.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.inputMovingMesh.selectNodeUponCreation = True self.inputMovingMesh.addEnabled = False self.inputMovingMesh.removeEnabled = False self.inputMovingMesh.noneEnabled = True self.inputMovingMesh.showHidden = False self.inputMovingMesh.showChildNodeTypes = False self.inputMovingMesh.setMRMLScene( slicer.mrmlScene ) self.inputMovingMesh.setToolTip( "Pick the input mesh for intraop scan" ) #self.inputVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputPreopMesh) # input fixed mesh self.inputFixedMesh = slicer.qMRMLNodeComboBox() self.inputFixedMesh.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.inputFixedMesh.selectNodeUponCreation = True self.inputFixedMesh.addEnabled = False self.inputFixedMesh.removeEnabled = False self.inputFixedMesh.noneEnabled = True self.inputFixedMesh.showHidden = False self.inputFixedMesh.showChildNodeTypes = False self.inputFixedMesh.setMRMLScene( slicer.mrmlScene ) self.inputFixedMesh.setToolTip( "Pick the input mesh for intraop scan" ) # self.inputMovingMesh.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputPreopMesh) # self.inputFixedMesh.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputIntraopMesh) autoFormLayout.addRow('Rigid (6 DOF)', self.rigidCheckmarkBox) autoFormLayout.addRow('Rigid+Scaling (7 DOF)', self.rigidscaleCheckmarkBox) autoFormLayout.addRow("Input Intraop Mesh: ", self.inputFixedMesh) autoFormLayout.addRow("Input Preop Mesh: ", self.inputMovingMesh) autoFormLayout.addRow(self.autoRegButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # File area # filesCollapsibleButton = ctk.ctkCollapsibleButton() filesCollapsibleButton.text = "Input files" filesCollapsibleButton.collapsed = False self.layout.addWidget(filesCollapsibleButton) # Layout within the files collapsible button filesFormLayout = qt.QFormLayout(filesCollapsibleButton) # select one file buttonLayout = qt.QHBoxLayout() self.archetypeText = qt.QLineEdit() buttonLayout.addWidget(self.archetypeText) self.addFromArchetype = qt.QPushButton("Browse...") buttonLayout.addWidget(self.addFromArchetype) self.archetypeStartNumber = 0 filesFormLayout.addRow("Filename pattern: ", buttonLayout) # file list group fileListGroupBox = ctk.ctkCollapsibleGroupBox() fileListGroupBox.title = "File list" fileListLayout = qt.QVBoxLayout() fileListGroupBox.setLayout(fileListLayout) filesFormLayout.addRow("", fileListGroupBox) self.addByBrowsingButton = qt.QPushButton("Select files...") fileListLayout.addWidget(self.addByBrowsingButton) self.fileTable = qt.QTextBrowser() fileListLayout.addWidget(self.fileTable) fileListGroupBox.collapsed = True # original volume size self.originalVolumeSizeLabel = qt.QLabel() filesFormLayout.addRow("Size: ", self.originalVolumeSizeLabel) # reverse slice order self.reverseCheckBox = qt.QCheckBox() self.reverseCheckBox.toolTip = "Read the images in reverse order (flips loaded volume along IS axis)" filesFormLayout.addRow("Reverse: ", self.reverseCheckBox) # original spacing self.spacingWidget = slicer.qMRMLCoordinatesWidget() self.spacingWidget.setMRMLScene(slicer.mrmlScene) self.spacingWidget.decimalsOption = ctk.ctkDoubleSpinBox.DecimalsByKey | ctk.ctkDoubleSpinBox.DecimalsByShortcuts | ctk.ctkDoubleSpinBox.DecimalsByValue self.spacingWidget.minimum = 0.0 self.spacingWidget.maximum = 1000000000.0 self.spacingWidget.quantity = "length" self.spacingWidget.unitAwareProperties = slicer.qMRMLCoordinatesWidget.Precision | slicer.qMRMLCoordinatesWidget.Prefix | slicer.qMRMLCoordinatesWidget.Scaling | slicer.qMRMLCoordinatesWidget.Suffix self.spacingWidget.coordinates = "1,1,1" self.spacingWidget.toolTip = "Set the colunm, row, slice spacing; original spacing not including downsample" filesFormLayout.addRow("Spacing: ", self.spacingWidget) # # output area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" outputCollapsibleButton.collapsed = False self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = [ "vtkMRMLScalarVolumeNode", "vtkMRMLVectorVolumeNode" ] self.outputSelector.showChildNodeTypes = False self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.selectNodeUponCreation = True self.outputSelector.noneEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.renameEnabled = True self.outputSelector.addEnabled = True self.outputSelector.noneDisplay = "(Create new volume)" self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip( "Pick the output volume to populate or None to autogenerate.") outputFormLayout.addRow("Output Volume: ", self.outputSelector) # # output ROI selector # self.outputROISelector = slicer.qMRMLNodeComboBox() self.outputROISelector.nodeTypes = [ "vtkMRMLAnnotationROINode", "vtkMRMLMarkupsROINode" ] self.outputROISelector.showChildNodeTypes = False self.outputROISelector.showHidden = False self.outputROISelector.showChildNodeTypes = False self.outputROISelector.noneEnabled = True self.outputROISelector.removeEnabled = True self.outputROISelector.renameEnabled = True self.outputROISelector.addEnabled = False self.outputROISelector.noneDisplay = "(Full volume)" self.outputROISelector.setMRMLScene(slicer.mrmlScene) self.outputROISelector.setToolTip( "Set the region of the volume that will be loaded") outputFormLayout.addRow("Region of interest: ", self.outputROISelector) # # Quality selector # qualityLayout = qt.QVBoxLayout() self.qualityPreviewRadioButton = qt.QRadioButton("preview") self.qualityHalfRadioButton = qt.QRadioButton("half resolution") self.qualityFullRadioButton = qt.QRadioButton("full resolution") qualityLayout.addWidget(self.qualityPreviewRadioButton) qualityLayout.addWidget(self.qualityHalfRadioButton) qualityLayout.addWidget(self.qualityFullRadioButton) self.qualityPreviewRadioButton.setChecked(True) outputFormLayout.addRow("Quality: ", qualityLayout) self.sliceSkipSpinBox = qt.QSpinBox() self.sliceSkipSpinBox.toolTip = "Skips the selected number of slices between each pair of output volume slices (use, for example, on long thin samples with more slices than in-plane resolution)" outputFormLayout.addRow("Slice skip: ", self.sliceSkipSpinBox) # Force grayscale output self.grayscaleCheckBox = qt.QCheckBox() self.grayscaleCheckBox.toolTip = "Force reading the image in grayscale. Only makes a difference if the input has color (RGB or RGBA) voxels." self.grayscaleCheckBox.checked = True outputFormLayout.addRow("Grayscale: ", self.grayscaleCheckBox) # output volume size self.outputVolumeSizeLabel = qt.QLabel() outputFormLayout.addRow("Output size: ", self.outputVolumeSizeLabel) # output volume spacing self.outputSpacingWidget = slicer.qMRMLCoordinatesWidget() self.outputSpacingWidget.setMRMLScene(slicer.mrmlScene) self.outputSpacingWidget.readOnly = True self.outputSpacingWidget.frame = False self.outputSpacingWidget.decimalsOption = ctk.ctkDoubleSpinBox.DecimalsByKey | ctk.ctkDoubleSpinBox.DecimalsByShortcuts | ctk.ctkDoubleSpinBox.DecimalsByValue self.outputSpacingWidget.minimum = 0.0 self.outputSpacingWidget.maximum = 1000000000.0 self.outputSpacingWidget.quantity = "length" self.outputSpacingWidget.unitAwareProperties = slicer.qMRMLCoordinatesWidget.Precision | slicer.qMRMLCoordinatesWidget.Prefix | slicer.qMRMLCoordinatesWidget.Scaling | slicer.qMRMLCoordinatesWidget.Suffix self.outputSpacingWidget.coordinates = "1,1,1" self.outputSpacingWidget.toolTip = "Slice spacing of the volume that will be loaded" outputFormLayout.addRow("Output spacing: ", self.outputSpacingWidget) self.loadButton = qt.QPushButton("Load files") self.loadButton.toolTip = "Load files as a 3D volume" self.loadButton.enabled = False outputFormLayout.addRow(self.loadButton) # connections self.reverseCheckBox.connect('toggled(bool)', self.updateLogicFromWidget) self.sliceSkipSpinBox.connect("valueChanged(int)", self.updateLogicFromWidget) self.spacingWidget.connect("coordinatesChanged(double*)", self.updateLogicFromWidget) self.qualityPreviewRadioButton.connect( "toggled(bool)", lambda toggled, widget=self.qualityPreviewRadioButton: self. onQualityToggled(toggled, widget)) self.qualityHalfRadioButton.connect( "toggled(bool)", lambda toggled, widget=self.qualityHalfRadioButton: self. onQualityToggled(toggled, widget)) self.qualityFullRadioButton.connect( "toggled(bool)", lambda toggled, widget=self.qualityFullRadioButton: self. onQualityToggled(toggled, widget)) self.grayscaleCheckBox.connect('toggled(bool)', self.updateLogicFromWidget) self.outputROISelector.connect("currentNodeChanged(vtkMRMLNode*)", self.setOutputROINode) self.addByBrowsingButton.connect('clicked()', self.addByBrowsing) self.addFromArchetype.connect('clicked()', self.selectArchetype) self.archetypeText.connect('textChanged(const QString &)', self.populateFromArchetype) self.loadButton.connect('clicked()', self.onLoadButton) # Add vertical spacer self.layout.addStretch(1) self.loadButton.enabled = False
def create(self): """create the segmentation helper box""" # # Master Frame # self.masterFrame = qt.QFrame(self.parent) self.masterFrame.setLayout(qt.QVBoxLayout()) self.parent.layout().addWidget(self.masterFrame) # # the master volume selector # self.masterSelectorFrame = qt.QFrame(self.parent) self.masterSelectorFrame.objectName = 'MasterVolumeFrame' self.masterSelectorFrame.setLayout(qt.QHBoxLayout()) self.masterFrame.layout().addWidget(self.masterSelectorFrame) self.masterSelectorLabel = qt.QLabel("Master Volume: ", self.masterSelectorFrame) self.masterSelectorLabel.setToolTip( "Select the master volume (background grayscale scalar volume node)" ) self.masterSelectorFrame.layout().addWidget(self.masterSelectorLabel) self.masterSelector = slicer.qMRMLNodeComboBox( self.masterSelectorFrame) self.masterSelector.objectName = 'MasterVolumeNodeSelector' # TODO self.masterSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.masterSelector.selectNodeUponCreation = False self.masterSelector.addEnabled = False self.masterSelector.removeEnabled = False self.masterSelector.noneEnabled = True self.masterSelector.showHidden = False self.masterSelector.showChildNodeTypes = False self.masterSelector.setMRMLScene(slicer.mrmlScene) # TODO: need to add a QLabel # self.masterSelector.SetLabelText( "Master Volume:" ) self.masterSelector.setToolTip( "Pick the master structural volume to define the segmentation. A label volume with the with \"%s\" appended to the name will be created if it doesn't already exist." % self.mergeVolumePostfix) self.masterSelectorFrame.layout().addWidget(self.masterSelector) # # merge label name and set button # self.mergeSelectorFrame = qt.QFrame(self.masterFrame) self.mergeSelectorFrame.objectName = 'MergeVolumeFrame' self.mergeSelectorFrame.setLayout(qt.QHBoxLayout()) self.masterFrame.layout().addWidget(self.mergeSelectorFrame) mergeNameToolTip = "Composite label map containing the merged structures (be aware that merge operations will overwrite any edits applied to this volume)" self.mergeNameLabel = qt.QLabel("Merge Volume: ", self.mergeSelectorFrame) self.mergeNameLabel.setToolTip(mergeNameToolTip) self.mergeSelectorFrame.layout().addWidget(self.mergeNameLabel) self.mergeSelector = slicer.qMRMLNodeComboBox(self.mergeSelectorFrame) self.mergeSelector.objectName = 'MergeVolumeNodeSelector' self.mergeSelector.setToolTip(mergeNameToolTip) self.mergeSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.mergeSelector.addEnabled = False self.mergeSelector.removeEnabled = False self.mergeSelector.noneEnabled = False self.mergeSelector.showHidden = False self.mergeSelector.showChildNodeTypes = False self.mergeSelector.setMRMLScene(slicer.mrmlScene) self.mergeSelectorFrame.layout().addWidget(self.mergeSelector) self.newMergeVolumeAction = qt.QAction("Create new LabelMapVolume", self.mergeSelector) self.newMergeVolumeAction.connect("triggered()", self.newMerge) self.mergeSelector.addMenuAction(self.newMergeVolumeAction) # # Structures Frame # self.structuresFrame = ctk.ctkCollapsibleGroupBox(self.masterFrame) self.structuresFrame.objectName = 'PerStructureVolumesFrame' self.structuresFrame.title = "Per-Structure Volumes" self.structuresFrame.collapsed = True self.structuresFrame.setLayout(qt.QVBoxLayout()) self.masterFrame.layout().addWidget(self.structuresFrame) self.structureListWidget = LabelStructureListWidget() self.structureListWidget.mergeVolumePostfix = self.mergeVolumePostfix self.structuresFrame.layout().addWidget(self.structureListWidget) # # signals, slots, and observers # # signals/slots on qt widgets are automatically when # this class destructs, but observers of the scene must be explicitly # removed in the destuctor # node selected self.masterSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.mergeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onMergeSelect) # so buttons will initially be disabled self.master = None self.structureListWidget.updateStructures()
def setup(self): self.developerMode = True ScriptedLoadableModuleWidget.setup(self) self.logic = LoadDataLogic() self.intraopVolCounter = 0 self.intraopVolComing = False self.targetPose1AddedFlag = False self.entryPose1AddedFlag = False self.targetPose2AddedFlag = False self.entryPose2AddedFlag = False # initialize global variables self.identity = vtk.vtkMatrix4x4() self.probe1Model = None self.probe1path = None self.probe1PathTransform = None self.probe2Model = None self.probe2path = None self.probe2PathTransform = None self.selectionNode = slicer.mrmlScene.GetNodeByID( "vtkMRMLSelectionNodeSingleton") # # Load DICOM data # self.dicomGroupBox = ctk.ctkCollapsibleGroupBox() self.dicomGroupBox.title = "Load DICOM" self.dicomGroupBox.collapsed = True self.layout.addWidget(self.dicomGroupBox) dicomGroupBoxFromLayout = qt.QFormLayout(self.dicomGroupBox) dicommodule = slicer.modules.dicom.createNewWidgetRepresentation() dicomchildren = dicommodule.children() dicomchildren[1].collapsed = True dicomchildren[3].hide() dicomGroupBoxFromLayout.addWidget(dicommodule) # Pre-op parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Pre-Op Treatment Plan" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input pre-op CT (medical scan) # self.inputScanSelector = slicer.qMRMLNodeComboBox() self.inputScanSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputScanSelector.selectNodeUponCreation = True self.inputScanSelector.addEnabled = False self.inputScanSelector.removeEnabled = True self.inputScanSelector.renameEnabled = True self.inputScanSelector.noneEnabled = False self.inputScanSelector.showHidden = False self.inputScanSelector.showChildNodeTypes = False self.inputScanSelector.setMRMLScene(slicer.mrmlScene) self.inputScanSelector.setToolTip( "Pick the input pre-operative medical Scan") parametersFormLayout.addRow("Pre-op Volume: ", self.inputScanSelector) # take care of change in preop medical scan self.inputScanSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onPreopVolumeChanged) # # input the segmentation (pre-op plan) # self.inputPlanSelector = slicer.qMRMLNodeComboBox() self.inputPlanSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.inputPlanSelector.selectNodeUponCreation = True self.inputPlanSelector.addEnabled = False self.inputPlanSelector.removeEnabled = True self.inputPlanSelector.renameEnabled = True self.inputPlanSelector.noneEnabled = False self.inputPlanSelector.showHidden = False self.inputPlanSelector.showChildNodeTypes = False self.inputPlanSelector.setMRMLScene(slicer.mrmlScene) self.inputPlanSelector.setToolTip("Input the segmentation") parametersFormLayout.addRow("Pre-op Segmentation: ", self.inputPlanSelector) # take care of change of preop treatment plan self.inputPlanSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onPreopSegmentationChanged) # # Generate Model Button # self.modelGenButton = qt.QPushButton( "Generate 3D Model from Preop Plan") self.modelGenButton.toolTip = "generates a 3d triangulated surface model from the preop segmentation data" if self.inputPlanSelector.currentNode != None: self.modelGenButton.enabled = True else: self.modelGenButton.enabled = False parametersFormLayout.addRow(self.modelGenButton) self.modelGenButton.connect('clicked(bool)', self.onGenerateModel) # connection # # input the Probe poses, the entry and the the tip points for probe 1 and 2 # nText = qt.QLabel("Total Number of Probes: ") self.probes = qt.QComboBox() self.tprobes = ('1', '2') self.probes.addItems(self.tprobes) parametersFormLayout.addRow(nText, self.probes) # implement if case for total number of entry and target points appearing based on number of probes self.probes.connect("activated(QString)", self.onProbeNum) # Probe 1 self.entryPose1Selector = slicer.qMRMLNodeComboBox() self.entryPose1Selector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"] self.entryPose1Selector.selectNodeUponCreation = True self.entryPose1Selector.addEnabled = True self.entryPose1Selector.removeEnabled = False self.entryPose1Selector.noneEnabled = False self.entryPose1Selector.showHidden = False self.entryPose1Selector.showChildNodeTypes = False self.entryPose1Selector.baseName = "Entry1" self.entryPose1Selector.setMRMLScene(slicer.mrmlScene) self.entryPose1Selector.setToolTip("Input probe 1 entry point") self.entryPose1Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onEntryPose1SelectorChanged) self.targetPose1Selector = slicer.qMRMLNodeComboBox() self.targetPose1Selector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"] self.targetPose1Selector.selectNodeUponCreation = True self.targetPose1Selector.addEnabled = True self.targetPose1Selector.removeEnabled = False self.targetPose1Selector.noneEnabled = False self.targetPose1Selector.showHidden = False self.targetPose1Selector.showChildNodeTypes = False self.targetPose1Selector.baseName = "Target1" self.targetPose1Selector.setMRMLScene(slicer.mrmlScene) self.targetPose1Selector.setToolTip("Input probe 1 entry point") self.targetPose1Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onTargetPose1SelectorChanged) self.showProbe1ModelCheckBox = qt.QCheckBox() self.showProbe1ModelCheckBox.checked = 1 self.showProbe1ModelCheckBox.setToolTip( "If checked, the probe model is shown in the display") self.showProbe1ModelCheckBox.connect('stateChanged(int)', self.onProbeModelCheckBox) self.probe1Button = qt.QPushButton("Delete Probe 1 Poses") self.probe1Button.toolTip = "Deletes probe 1 entry and target poses." self.probe1Button.enabled = True self.probe1Button.connect('clicked(bool)', self.onDeleteProbe1Button) self.probe1GroupBox = ctk.ctkCollapsibleGroupBox() self.probe1GroupBox.title = "Probe 1" self.probe1GroupBox.collapsed = False parametersFormLayout.addRow(self.probe1GroupBox) probe1GroupBoxLayout = qt.QFormLayout(self.probe1GroupBox) probe1GroupBoxLayout.addRow("Input Probe 1 entry point: ", self.entryPose1Selector) probe1GroupBoxLayout.addRow("Input Probe 1 target point: ", self.targetPose1Selector) probe1GroupBoxLayout.addRow("Show Probe Model in the views", self.showProbe1ModelCheckBox) probe1GroupBoxLayout.addRow(self.probe1Button) # Probe 2 self.entryPose2Selector = slicer.qMRMLNodeComboBox() self.entryPose2Selector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"] self.entryPose2Selector.selectNodeUponCreation = True self.entryPose2Selector.addEnabled = True self.entryPose2Selector.removeEnabled = False self.entryPose2Selector.noneEnabled = False self.entryPose2Selector.showHidden = False self.entryPose2Selector.showChildNodeTypes = False self.entryPose2Selector.baseName = "Entry2" self.entryPose2Selector.setMRMLScene(slicer.mrmlScene) self.entryPose2Selector.setToolTip("Input probe 2 entry point") self.entryPose2Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onEntryPose2SelectorChanged) self.targetPose2Selector = slicer.qMRMLNodeComboBox() self.targetPose2Selector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"] self.targetPose2Selector.selectNodeUponCreation = True self.targetPose2Selector.addEnabled = True self.targetPose2Selector.removeEnabled = False self.targetPose2Selector.noneEnabled = False self.targetPose2Selector.showHidden = False self.targetPose2Selector.showChildNodeTypes = False self.targetPose2Selector.baseName = "Target2" self.targetPose2Selector.setMRMLScene(slicer.mrmlScene) self.targetPose2Selector.setToolTip("Input probe 2 entry point") self.targetPose2Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onTargetPose2SelectorChanged) self.showProbe2ModelCheckBox = qt.QCheckBox() self.showProbe2ModelCheckBox.checked = 1 self.showProbe2ModelCheckBox.setToolTip( "If checked, the probe model is shown in the display") self.showProbe2ModelCheckBox.connect('stateChanged(int)', self.onProbeModelCheckBox) self.probe2Button = qt.QPushButton("Delete Probe 1 Poses") self.probe2Button.toolTip = "Deletes probe 1 entry and target poses." self.probe2Button.enabled = True self.probe2Button.connect('clicked(bool)', self.onDeleteProbe2Button) self.probe2GroupBox = ctk.ctkCollapsibleGroupBox() self.probe2GroupBox.title = "Probe 2" self.probe2GroupBox.collapsed = False parametersFormLayout.addRow(self.probe2GroupBox) probe2GroupBoxLayout = qt.QFormLayout(self.probe2GroupBox) probe2GroupBoxLayout.addRow("Input Probe 2 entry point: ", self.entryPose2Selector) probe2GroupBoxLayout.addRow("Input Probe 2 target point: ", self.targetPose2Selector) probe2GroupBoxLayout.addRow("Show Probe Model in the views", self.showProbe2ModelCheckBox) probe2GroupBoxLayout.addRow(self.probe2Button) self.onProbeNum()
def create(self): """create the segmentation helper box""" # # Master Frame # self.masterFrame = qt.QFrame(self.parent) self.masterFrame.setLayout(qt.QVBoxLayout()) self.parent.layout().addWidget(self.masterFrame) # # the master volume selector # self.masterSelectorFrame = qt.QFrame(self.parent) self.masterSelectorFrame.objectName = 'MasterVolumeFrame' self.masterSelectorFrame.setLayout(qt.QHBoxLayout()) self.masterFrame.layout().addWidget(self.masterSelectorFrame) self.masterSelectorLabel = qt.QLabel("Master Volume: ", self.masterSelectorFrame) self.masterSelectorLabel.setToolTip( "Select the master volume (background grayscale scalar volume node)") self.masterSelectorFrame.layout().addWidget(self.masterSelectorLabel) self.masterSelector = slicer.qMRMLNodeComboBox(self.masterSelectorFrame) self.masterSelector.objectName = 'MasterVolumeNodeSelector' # TODO self.masterSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.masterSelector.selectNodeUponCreation = False self.masterSelector.addEnabled = False self.masterSelector.removeEnabled = False self.masterSelector.noneEnabled = True self.masterSelector.showHidden = False self.masterSelector.showChildNodeTypes = False self.masterSelector.setMRMLScene( slicer.mrmlScene ) # TODO: need to add a QLabel # self.masterSelector.SetLabelText( "Master Volume:" ) self.masterSelector.setToolTip( "Pick the master structural volume to define the segmentation. A label volume with the with \"%s\" appended to the name will be created if it doesn't already exist." % self.mergeVolumePostfix) self.masterSelectorFrame.layout().addWidget(self.masterSelector) # # merge label name and set button # self.mergeSelectorFrame = qt.QFrame(self.masterFrame) self.mergeSelectorFrame.objectName = 'MergeVolumeFrame' self.mergeSelectorFrame.setLayout(qt.QHBoxLayout()) self.masterFrame.layout().addWidget(self.mergeSelectorFrame) mergeNameToolTip = "Composite label map containing the merged structures (be aware that merge operations will overwrite any edits applied to this volume)" self.mergeNameLabel = qt.QLabel("Merge Volume: ", self.mergeSelectorFrame) self.mergeNameLabel.setToolTip( mergeNameToolTip ) self.mergeSelectorFrame.layout().addWidget(self.mergeNameLabel) self.mergeSelector = slicer.qMRMLNodeComboBox(self.mergeSelectorFrame) self.mergeSelector.objectName = 'MergeVolumeNodeSelector' self.mergeSelector.setToolTip( mergeNameToolTip ) self.mergeSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.mergeSelector.addEnabled = False self.mergeSelector.removeEnabled = False self.mergeSelector.noneEnabled = False self.mergeSelector.showHidden = False self.mergeSelector.showChildNodeTypes = False self.mergeSelector.setMRMLScene( slicer.mrmlScene ) self.mergeSelectorFrame.layout().addWidget(self.mergeSelector) self.newMergeVolumeAction = qt.QAction("Create new LabelMapVolume", self.mergeSelector) self.newMergeVolumeAction.connect("triggered()", self.newMerge) self.mergeSelector.addMenuAction(self.newMergeVolumeAction) # # Structures Frame # self.structuresFrame = ctk.ctkCollapsibleGroupBox(self.masterFrame) self.structuresFrame.objectName = 'PerStructureVolumesFrame' self.structuresFrame.title = "Per-Structure Volumes" self.structuresFrame.collapsed = True self.structuresFrame.setLayout(qt.QVBoxLayout()) self.masterFrame.layout().addWidget(self.structuresFrame) self.structureListWidget = LabelStructureListWidget() self.structureListWidget.mergeVolumePostfix = self.mergeVolumePostfix self.structuresFrame.layout().addWidget(self.structureListWidget) # # signals, slots, and observers # # signals/slots on qt widgets are automatically when # this class destructs, but observers of the scene must be explicitly # removed in the destuctor # node selected self.masterSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.mergeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onMergeSelect) # so buttons will initially be disabled self.master = None self.structureListWidget.updateStructures()
def setup(self): ScriptedLoadableModuleWidget.setup(self) ######################################################## ############# Transform Definition Area ################ ######################################################## transformsCollapsibleButton = ctk.ctkCollapsibleButton() transformsCollapsibleButton.text = "Transform Definition" self.layout.addWidget(transformsCollapsibleButton) parametersFormLayout = qt.QFormLayout(transformsCollapsibleButton) # ApplicatorToTracker transform selector self.applicatorToTrackerSelector = slicer.qMRMLNodeComboBox() self.applicatorToTrackerSelector.nodeTypes = (( "vtkMRMLLinearTransformNode"), "") self.applicatorToTrackerSelector.selectNodeUponCreation = True self.applicatorToTrackerSelector.addEnabled = False self.applicatorToTrackerSelector.removeEnabled = False self.applicatorToTrackerSelector.noneEnabled = False self.applicatorToTrackerSelector.showHidden = False self.applicatorToTrackerSelector.showChildNodeTypes = False self.applicatorToTrackerSelector.setMRMLScene(slicer.mrmlScene) self.applicatorToTrackerSelector.setToolTip( "Pick the applicatorToTracker transform.") parametersFormLayout.addRow("ApplicatorToTracker transform: ", self.applicatorToTrackerSelector) # LiacToTracker transform selector self.liacToTrackerSelector = slicer.qMRMLNodeComboBox() self.liacToTrackerSelector.nodeTypes = (("vtkMRMLLinearTransformNode"), "") self.liacToTrackerSelector.selectNodeUponCreation = True self.liacToTrackerSelector.addEnabled = False self.liacToTrackerSelector.removeEnabled = False self.liacToTrackerSelector.noneEnabled = False self.liacToTrackerSelector.showHidden = False self.liacToTrackerSelector.showChildNodeTypes = False self.liacToTrackerSelector.setMRMLScene(slicer.mrmlScene) self.liacToTrackerSelector.setToolTip( "Pick the LiacToTracker transform.") parametersFormLayout.addRow("LiacToTracker transform: ", self.liacToTrackerSelector) ######################################################## ################## Calibration Area #################### ######################################################## calibrationCollapsibleButton = ctk.ctkCollapsibleButton() calibrationCollapsibleButton.text = "Calibration" self.layout.addWidget(calibrationCollapsibleButton) parametersFormLayout = qt.QFormLayout(calibrationCollapsibleButton) # # Icons retrieval # sordinaLIACGuidanceModuleDirectoryPath = slicer.modules.sordinaliacguidance.path.replace( "SordinaLIACGuidance.py", "") recordIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/recordIcon.png') stopIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/stopIcon.png') restartIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/restartIcon.png') saveIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/saveIcon.png') # # Up-down movement recording # upDownMovementGroupBox = ctk.ctkCollapsibleGroupBox() upDownMovementGroupBox.setTitle("Up-Down Movement") upDownMovementGroupBoxFormLayout = qt.QFormLayout( upDownMovementGroupBox) parametersFormLayout.addRow(upDownMovementGroupBox) upDownMovementLayout = qt.QHBoxLayout() upDownMovementGroupBoxFormLayout.addRow(upDownMovementLayout) self.upDownRecordButton = qt.QPushButton(" Record") self.upDownRecordButton.setIcon(recordIcon) self.upDownRecordButton.enabled = True upDownMovementLayout.addWidget(self.upDownRecordButton) # upDownMovementGroupBoxFormLayout.addRow(self.upDownRecordButton) self.upDownStopButton = qt.QPushButton(" Stop") self.upDownStopButton.setIcon(stopIcon) self.upDownStopButton.enabled = False upDownMovementLayout.addWidget(self.upDownStopButton) # upDownMovementGroupBoxFormLayout.addRow(self.upDownStopButton) self.upDownRestartButton = qt.QPushButton(" Restart") self.upDownRestartButton.setIcon(restartIcon) self.upDownRestartButton.enabled = False upDownMovementLayout.addWidget(self.upDownRestartButton) # upDownMovementGroupBoxFormLayout.addRow(self.upDownRestartButton) # # Roll movement recording # rollMovementGroupBox = ctk.ctkCollapsibleGroupBox() rollMovementGroupBox.setTitle("Roll Movement") rollMovementGroupBoxFormLayout = qt.QFormLayout(rollMovementGroupBox) parametersFormLayout.addRow(rollMovementGroupBox) rollMovementLayout = qt.QHBoxLayout() rollMovementGroupBoxFormLayout.addRow(rollMovementLayout) self.rollRecordButton = qt.QPushButton(" Record") self.rollRecordButton.setIcon(recordIcon) self.rollRecordButton.enabled = True rollMovementLayout.addWidget(self.rollRecordButton) # rollMovementGroupBoxFormLayout.addRow(self.rollRecordButton) self.rollStopButton = qt.QPushButton(" Stop") self.rollStopButton.setIcon(stopIcon) self.rollStopButton.enabled = False rollMovementLayout.addWidget(self.rollStopButton) # rollMovementGroupBoxFormLayout.addRow(self.rollStopButton) self.rollRestartButton = qt.QPushButton(" Restart") self.rollRestartButton.setIcon(restartIcon) self.rollRestartButton.enabled = False rollMovementLayout.addWidget(self.rollRestartButton) # rollMovementGroupBoxFormLayout.addRow(self.rollRestartButton) # # Save/load calibration file # self.saveCalibrationButton = qt.QPushButton(" Save Calibration") self.saveCalibrationButton.setIcon(saveIcon) self.saveCalibrationButton.enabled = True self.saveCalibrationButton.adjustSize() self.loadCalibrationButton = qt.QPushButton(" Load Calibration") self.loadCalibrationButton.setIcon(saveIcon) self.loadCalibrationButton.enabled = True self.loadCalibrationButton.adjustSize() self.calibrationErrorLabel = qt.QLabel('Calibration error: - mm') self.calibrationErrorLabel.setStyleSheet( "QLabel { color : #000000; font: bold}") parametersFormLayout.addRow(self.loadCalibrationButton, self.saveCalibrationButton) parametersFormLayout.addRow(self.calibrationErrorLabel) ######################################################### #################### Guidance Area ###################### ######################################################### guidanceCollapsibleButton = ctk.ctkCollapsibleButton() guidanceCollapsibleButton.text = "Guidance" self.layout.addWidget(guidanceCollapsibleButton) parametersFormLayout = qt.QFormLayout(guidanceCollapsibleButton) # Load Models Button self.loadModelsButton = qt.QPushButton() self.loadModelsButton.toolTip = "Soft tissue visibility." self.loadModelsButton.enabled = True self.loadModelsButton.text = "Load 3D Models" parametersFormLayout.addRow(self.loadModelsButton) # connections self.applicatorToTrackerSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.onSelect) self.liacToTrackerSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onSelect) self.upDownRecordButton.connect('clicked(bool)', self.onUpDownRecordButton) self.upDownStopButton.connect('clicked(bool)', self.onUpDownStopButton) self.upDownRestartButton.connect('clicked(bool)', self.onUpDownRestartButton) self.rollRecordButton.connect('clicked(bool)', self.onRollRecordButton) self.rollStopButton.connect('clicked(bool)', self.onRollStopButton) self.rollRestartButton.connect('clicked(bool)', self.onRollRestartButton) self.loadModelsButton.connect('clicked(bool)', self.onLoadModelsButton) self.SordinaLIACGuidanceLogic = SordinaLIACGuidanceLogic() # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.NeuromodulationNavLogic = NeuromodulationNavLogic() self.pivotCalibrationLogic=slicer.modules.pivotcalibration.logic() self.defaultStyleSheet = "QLabel { color : #000000; \ font: bold 14px}" #Definimos el layout con dos vistas self.layoutManager= slicer.app.layoutManager() layoutLogic = self.layoutManager.layoutLogic() customLayout = ("<layout type=\"horizontal\" split=\"false\" >" " <item>" " <view class=\"vtkMRMLViewNode\" singletontag=\"1\">" " <property name=\"viewlabel\" action=\"default\">1</property>" " </view>" " </item>" " <item>" " <view class=\"vtkMRMLViewNode\" singletontag=\"2\" type=\"secondary\">" " <property name=\"viewlabel\" action=\"default\">2</property>" " </view>" " </item>" "</layout>") self.dual3dviewLayout=509 layoutLogic.GetLayoutNode().AddLayoutDescription(self.dual3dviewLayout, customLayout) # Trajectory Definition Area # Load sacro model first self.NeuromodulationNavModuleDataPath = slicer.modules.neuromodulationnav.path.replace("NeuromodulationNav.py","") + 'Resources/Models/' self.sacroModel = slicer.util.getNode('sacroModel') if not self.sacroModel: slicer.util.loadModel(self.NeuromodulationNavModuleDataPath + 'sacroModel.stl') self.sacroModel = slicer.util.getNode(pattern="sacroModel") self.sacroModelDisplay=self.sacroModel.GetModelDisplayNode() self.sacroModelDisplay.SetColor([1,1,1]) '''self.softTissueModel = slicer.util.getNode('SoftTissueModel') if not self.softTissueModel: slicer.util.loadModel(NeuromodulationNavModuleDataPath + 'SoftTissueModel.stl') self.softTissueModel = slicer.util.getNode(pattern="SoftTissueModel") self.softTissueModelDisplay=self.softTissueModel.GetModelDisplayNode() self.softTissueModelDisplay.SetColor([1,0.7,0.53]) ''' trajectoryCollapsibleButton = ctk.ctkCollapsibleButton() trajectoryCollapsibleButton.text = "Trajectory Definition" self.layout.addWidget(trajectoryCollapsibleButton) parametersFormLayout = qt.QFormLayout(trajectoryCollapsibleButton) self.layoutManager.setLayout(self.dual3dviewLayout) layoutManager1 = slicer.app.layoutManager() threeDWidget = layoutManager1.threeDWidget(0) threeDView1 = threeDWidget.threeDView() threeDView1.resetFocalPoint() layoutManager2 = slicer.app.layoutManager() threeDWidget = layoutManager2.threeDWidget(1) threeDView2 = threeDWidget.threeDView() threeDView2.resetFocalPoint() #Enable two camerasview self.positionateTwoCamerasButton = qt.QPushButton() self.positionateTwoCamerasButton.enabled = True self.positionateTwoCamerasButton.setText('Positionate two cameras') parametersFormLayout.addRow(self.positionateTwoCamerasButton) # Calculate Distance Button self.setTargetButton = qt.QPushButton("Set Target") self.setTargetButton.enabled = True #self.setTargetButton.checkable = True parametersFormLayout.addRow(self.setTargetButton) self.setConeButton = qt.QPushButton("Set Cone") self.setConeButton.enabled = True #self.setTargetButton.checkable = True parametersFormLayout.addRow(self.setConeButton) # Transform Definition Area transformsCollapsibleButton = ctk.ctkCollapsibleButton() transformsCollapsibleButton.text = "Navigation" transformsCollapsibleButton.collapsed = True self.layout.addWidget(transformsCollapsibleButton) parametersFormLayout = qt.QFormLayout(transformsCollapsibleButton) #Load transformations self.pointerToTracker = slicer.util.getNode('PointerToTracker') if not self.pointerToTracker: print('ERROR: pointerToTracker transform node was not found') self.needleToTracker = slicer.util.getNode('NeedleToTracker') if not self.needleToTracker: print('ERROR: needleToTracker transform node was not found') self.referenceToTracker = slicer.util.getNode('ReferenceToTracker') if not self.referenceToTracker: print('ERROR: referenceToTracker transform node was not found') self.trackerToReference = slicer.util.getNode('TrackerToReference') if not self.trackerToReference: print('ERROR: TrackerToReference transform node was not found') self.pointerTipToPointer = slicer.util.getNode('PointerTipToPointer') if not self.pointerTipToPointer: print('ERROR: pointerTipToPointer transform node was not found') self.needleTipToNeedle = slicer.util.getNode('NeedleTipToNeedle') if not self.needleTipToNeedle: print('ERROR: needleTipToNeedle transform node was not found') self.sacroToReference = slicer.util.getNode('sacroToReference') if not self.sacroToReference: print('ERROR: sacroToReference transform node was not found') # Apply Transforms For Navigation Button self.applyTransformsForNavigationButton = qt.QPushButton("Apply Transforms For Navigation") self.applyTransformsForNavigationButton.toolTip = "Apply selected transforms." self.applyTransformsForNavigationButton.enabled = False parametersFormLayout.addRow(self.applyTransformsForNavigationButton) #Orientate model into 3D view button self.setupModelOrientationButton = qt.QPushButton("Record Front Position") parametersFormLayout.addRow(self.setupModelOrientationButton) # Soft Tissue Visibility Button '''self.softTissueVisibilityButton = qt.QPushButton() self.softTissueVisibilityButton.toolTip = "Soft tissue visibility." self.softTissueVisibilityButton.enabled = True self.softTissueVisibilityButtonState = 0 self.softTissueVisibilityButtonStateText0 = "Make Soft Tissue Invisible" self.softTissueVisibilityButtonStateText1 = "Make Soft Tissue Visible" self.softTissueVisibilityButton.setText(self.softTissueVisibilityButtonStateText0) parametersFormLayout.addRow(self.softTissueVisibilityButton) ''' # Navigation Area distanceCollapsibleButton = ctk.ctkCollapsibleButton() distanceCollapsibleButton.text = "Distance to Target" distanceCollapsibleButton.collapsed = True self.layout.addWidget(distanceCollapsibleButton) parametersFormLayout = qt.QFormLayout(distanceCollapsibleButton) # Calculate Distance Button self.calculateDistanceButton = qt.QPushButton("Calculate Distance") self.calculateDistanceButton.enabled = True self.calculateDistanceButton.checkable = True parametersFormLayout.addRow(self.calculateDistanceButton) # Calculate Distance Label self.calculateDistanceLabel = qt.QLabel('-') self.calculateDistanceLabel.setStyleSheet(self.defaultStyleSheet) self.QFormLayoutLabel = qt.QLabel('Distance to target (mm): ') self.QFormLayoutLabel.setStyleSheet(self.defaultStyleSheet) parametersFormLayout.addRow(self.QFormLayoutLabel, self.calculateDistanceLabel) # Navigation Point of View Area navigationViewCollapsibleButton = ctk.ctkCollapsibleButton() navigationViewCollapsibleButton.text = "Navigation Point of View" navigationViewCollapsibleButton.collapsed = True self.layout.addWidget(navigationViewCollapsibleButton) parametersFormLayout = qt.QFormLayout(navigationViewCollapsibleButton) # Cameras logging.debug('Create cameras') self.LeftCamera = slicer.util.getNode('Left Camera') if not self.LeftCamera: self.LeftCamera=slicer.vtkMRMLCameraNode() self.LeftCamera.SetName("Left Camera") slicer.mrmlScene.AddNode(self.LeftCamera) self.RightCamera = slicer.util.getNode('Right Camera') if not self.RightCamera: self.RightCamera=slicer.vtkMRMLCameraNode() self.RightCamera.SetName("Right Camera") slicer.mrmlScene.AddNode(self.RightCamera) #Enable two camerasview self.enableTwoCamerasButton = qt.QPushButton() self.enableTwoCamerasButton.enabled = True self.enableTwoCamerasButton.setText('Enable two cameras') parametersFormLayout.addRow(self.enableTwoCamerasButton) # #Viewpoint # self.cameraSelector = slicer.qMRMLNodeComboBox() self.cameraSelector.nodeTypes = ( ("vtkMRMLCameraNode"), "" ) self.cameraSelector.selectNodeUponCreation = True self.cameraSelector.addEnabled = False self.cameraSelector.removeEnabled = False self.cameraSelector.noneEnabled = False self.cameraSelector.showHidden = False self.cameraSelector.showChildNodeTypes = False self.cameraSelector.setMRMLScene( slicer.mrmlScene ) parametersFormLayout.addRow("Select camera: ", self.cameraSelector) viewPointGroupBox = ctk.ctkCollapsibleGroupBox() viewPointGroupBox.setTitle("ViewPoint") viewPointGroupBoxFormLayout = qt.QFormLayout(viewPointGroupBox) parametersFormLayout.addRow(viewPointGroupBox) horizontaLBox1 = qt.QHBoxLayout() self.leftSideViewPointRadioButton = qt.QRadioButton('Left Side View') horizontaLBox1.addWidget(self.leftSideViewPointRadioButton) self.rightSideViewPointRadioButton = qt.QRadioButton('Right Side View') horizontaLBox1.addWidget(self.rightSideViewPointRadioButton) self.frontViewPointRadioButton = qt.QRadioButton('Front View') horizontaLBox1.addWidget(self.frontViewPointRadioButton) viewPointGroupBoxFormLayout.addRow(horizontaLBox1) horizontalBox2 = qt.QHBoxLayout() self.backViewPointRadioButton = qt.QRadioButton('Back View') horizontalBox2.addWidget(self.backViewPointRadioButton) self.superiorViewPointRadioButton = qt.QRadioButton('Superior View') horizontalBox2.addWidget(self.superiorViewPointRadioButton) self.inferiorViewPointRadioButton = qt.QRadioButton('Inferior View') horizontalBox2.addWidget(self.inferiorViewPointRadioButton) viewPointGroupBoxFormLayout.addRow(horizontalBox2) # Needle Viewpoint Button self.needleViewpointButton = qt.QPushButton() self.needleViewpointButton.toolTip = "Apply needle viewpoint." self.needleViewpointButton.enabled = True self.enableNeedleViewpointButtonState = 0 self.enableNeedleViewpointButtonTextState0 = "Enable Needle Viewpoint" self.enableNeedleViewpointButtonTextState1 = "Disable Needle Viewpoint" self.needleViewpointButton.setText(self.enableNeedleViewpointButtonTextState0) parametersFormLayout.addRow(self.needleViewpointButton) # Pointer Viewpoint Button self.pointerViewpointButton = qt.QPushButton() self.pointerViewpointButton.toolTip = "Apply pointer viewpoint." self.pointerViewpointButton.enabled = True self.enablePointerViewpointButtonState = 0 self.enablePointerViewpointButtonTextState0 = "Enable Pointer Viewpoint" self.enablePointerViewpointButtonTextState1 = "Disable Pointer Viewpoint" self.pointerViewpointButton.setText(self.enablePointerViewpointButtonTextState0) parametersFormLayout.addRow(self.pointerViewpointButton) # connections #self.pointerTipToPointerSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectForRegistration) #self.needleTipToNeedleSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectForRegistration) #self.applyTransformsForRegistrationButton.connect('clicked(bool)', self.onApplyTransformsForRegistrationClicked) self.cameraSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onCameraSelected) self.applyTransformsForNavigationButton.connect('clicked(bool)', self.onApplyTransformsForNavigationClicked) #self.softTissueVisibilityButton.connect('clicked(bool)', self.onSoftTissueVisibilityButtonClicked) self.calculateDistanceButton.connect('clicked(bool)', self.onCalculateDistanceClicked) self.needleViewpointButton.connect('clicked(bool)', self.onNeedleViewpointButtonClicked) self.pointerViewpointButton.connect('clicked(bool)', self.onPointerViewpointButtonClicked) self.enableTwoCamerasButton.connect('clicked(bool)', self.onEnableTwoCamerasButtonClicked) self.positionateTwoCamerasButton.connect('clicked(bool)', self.onPositionateTwoCamerasButtonClicked) self.leftSideViewPointRadioButton.connect('clicked(bool)', self.onViewpointChecked) self.rightSideViewPointRadioButton.connect('clicked(bool)', self.onViewpointChecked) self.frontViewPointRadioButton.connect('clicked(bool)', self.onViewpointChecked) self.backViewPointRadioButton.connect('clicked(bool)', self.onViewpointChecked) self.superiorViewPointRadioButton.connect('clicked(bool)', self.onViewpointChecked) self.inferiorViewPointRadioButton.connect('clicked(bool)', self.onViewpointChecked) self.setTargetButton.connect('clicked(bool)', self.onsetTargetButtonClicked) self.setConeButton.connect('clicked(bool)', self.onsetConeButtonClicked) self.setupModelOrientationButton.connect('clicked()', self.onSetupModelOrientationClicked) # Layout setup self.layoutManager= slicer.app.layoutManager() self.registerCustomLayoutsNeuroMod() # Add vertical spacer self.layout.addStretch(1) view = slicer.util.getNode('View1') view.SetBoxVisible(False) view.SetAxisLabelsVisible(False)
def __init__(self): toolTip = 'Draw a structure in the image to move it to the nearest visible model. When finished, corresponding fixed points will be added.' WarpAbstractEffect.__init__(self, 'Draw', toolTip) # sample distance self.sampleDistanceSlider = ctk.ctkSliderWidget() self.sampleDistanceSlider.singleStep = 0.1 self.sampleDistanceSlider.minimum = 0.1 self.sampleDistanceSlider.maximum = 10 self.sampleDistanceSlider.decimals = 1 self.sampleDistanceSlider.value = float( self.parameterNode.GetParameter("DrawSampleDistance")) self.sampleDistanceSlider.setToolTip('Set drawing sample distance.') self.parametersFrame.layout().addRow("Sample Distance (mm):", self.sampleDistanceSlider) # Spread (RBF Radius) self.spreadSlider = ctk.ctkSliderWidget() self.spreadSlider.singleStep = 1 self.spreadSlider.minimum = 5 self.spreadSlider.maximum = 50 self.spreadSlider.decimals = 0 self.spreadSlider.value = float( self.parameterNode.GetParameter("DrawSpread")) self.spreadSlider.setToolTip( 'Specify up to how far away from the drawing the warp will be modified.' ) self.parametersFrame.layout().addRow("Spread (mm):", self.spreadSlider) # stiffness self.stiffnessSlider = ctk.ctkSliderWidget() self.stiffnessSlider.singleStep = 0.1 self.stiffnessSlider.minimum = 0 self.stiffnessSlider.maximum = 10 self.stiffnessSlider.decimals = 1 self.stiffnessSlider.value = float( self.parameterNode.GetParameter("DrawStiffness")) self.stiffnessSlider.setToolTip('Regularization parameter.') self.parametersFrame.layout().addRow("Stiffness:", self.stiffnessSlider) # persistent mode self.persistentCheckBox = qt.QCheckBox() self.parametersFrame.layout().addRow("Persistent:", self.persistentCheckBox) # persistent options self.persistentParametersGroupBox = ctk.ctkCollapsibleGroupBox() self.persistentParametersGroupBox.setTitle('Persistent Options') self.persistentParametersGroupBox.setLayout(qt.QVBoxLayout()) self.persistentParametersGroupBox.collapsed = True self.parametersFrame.layout().addRow(self.persistentParametersGroupBox) self.numberOfOperationsLabel = qt.QLabel('Number Of Operations: 0') self.persistentParametersGroupBox.layout().addWidget( self.numberOfOperationsLabel) recalculateButton = qt.QPushButton('Re-calculate warp') self.persistentParametersGroupBox.layout().addWidget(recalculateButton) removeLastButton = qt.QPushButton('Remove last operation') self.persistentParametersGroupBox.layout().addWidget(removeLastButton) setTargetAsFixedButton = qt.QPushButton('Set target points as fixed') self.persistentParametersGroupBox.layout().addWidget( setTargetAsFixedButton) # connections recalculateButton.connect('clicked(bool)', self.onRecalculateButton) removeLastButton.connect('clicked(bool)', self.onRemoveLastButton) setTargetAsFixedButton.connect('clicked(bool)', self.onSetTargetAsFixedButton) self.spreadSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.sampleDistanceSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.stiffnessSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.persistentCheckBox.connect('stateChanged(int)', self.updateMRMLFromGUI)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # This module is often used in developer mode, therefore # collapse reload & test section by default. if hasattr(self, "reloadCollapsibleButton"): self.reloadCollapsibleButton.collapsed = True self.observerTags = [] self.logic = SampleDataLogic(self.logMessage) numberOfColumns = 3 iconPath = os.path.join(os.path.dirname(__file__).replace('\\','/'), 'Resources','Icons') desktop = qt.QDesktopWidget() mainScreenSize = desktop.availableGeometry(desktop.primaryScreen) iconSize = qt.QSize(mainScreenSize.width()/15,mainScreenSize.height()/10) categories = slicer.modules.sampleDataSources.keys() categories.sort() if 'BuiltIn' in categories: categories.remove('BuiltIn') categories.insert(0,'BuiltIn') for category in categories: frame = ctk.ctkCollapsibleGroupBox(self.parent) self.layout.addWidget(frame) frame.title = category frame.name = '%sCollapsibleGroupBox' % category layout = qt.QGridLayout(frame) columnIndex = 0 rowIndex = 0 for source in slicer.modules.sampleDataSources[category]: name = source.sampleName if not name: name = source.nodeNames[0] b = qt.QToolButton() b.setText(name) # Set thumbnail if source.thumbnailFileName: # Thumbnail provided thumbnailImage = source.thumbnailFileName else: # Look for thumbnail image with the name of any node name with .png extension thumbnailImage = None for nodeName in source.nodeNames: if not nodeName: continue thumbnailImageAttempt = os.path.join(iconPath, nodeName+'.png') if os.path.exists(thumbnailImageAttempt): thumbnailImage = thumbnailImageAttempt break if thumbnailImage and os.path.exists(thumbnailImage): b.setIcon(qt.QIcon(thumbnailImage)) b.setIconSize(iconSize) b.setToolButtonStyle(qt.Qt.ToolButtonTextUnderIcon) qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) b.setSizePolicy(qSize) b.name = '%sPushButton' % name layout.addWidget(b, rowIndex, columnIndex) columnIndex += 1 if columnIndex==numberOfColumns: rowIndex += 1 columnIndex = 0 if source.customDownloader: b.connect('clicked()', source.customDownloader) else: b.connect('clicked()', lambda s=source: self.logic.downloadFromSource(s)) self.log = qt.QTextEdit() self.log.readOnly = True self.layout.addWidget(self.log) self.logMessage('<p>Status: <i>Idle</i>\n') # Add spacer to layout self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) ######################################################## ############# Transform Definition Area ################ ######################################################## transformsCollapsibleButton = ctk.ctkCollapsibleButton() transformsCollapsibleButton.text = "Transform Definition" self.layout.addWidget(transformsCollapsibleButton) parametersFormLayout = qt.QFormLayout(transformsCollapsibleButton) # ApplicatorToTracker transform selector self.applicatorToTrackerSelector = slicer.qMRMLNodeComboBox() self.applicatorToTrackerSelector.nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" ) self.applicatorToTrackerSelector.selectNodeUponCreation = True self.applicatorToTrackerSelector.addEnabled = False self.applicatorToTrackerSelector.removeEnabled = False self.applicatorToTrackerSelector.noneEnabled = False self.applicatorToTrackerSelector.showHidden = False self.applicatorToTrackerSelector.showChildNodeTypes = False self.applicatorToTrackerSelector.setMRMLScene( slicer.mrmlScene ) self.applicatorToTrackerSelector.setToolTip( "Pick the applicatorToTracker transform." ) parametersFormLayout.addRow("ApplicatorToTracker transform: ", self.applicatorToTrackerSelector) # LiacToTracker transform selector self.liacToTrackerSelector = slicer.qMRMLNodeComboBox() self.liacToTrackerSelector.nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" ) self.liacToTrackerSelector.selectNodeUponCreation = True self.liacToTrackerSelector.addEnabled = False self.liacToTrackerSelector.removeEnabled = False self.liacToTrackerSelector.noneEnabled = False self.liacToTrackerSelector.showHidden = False self.liacToTrackerSelector.showChildNodeTypes = False self.liacToTrackerSelector.setMRMLScene( slicer.mrmlScene ) self.liacToTrackerSelector.setToolTip( "Pick the LiacToTracker transform." ) parametersFormLayout.addRow("LiacToTracker transform: ", self.liacToTrackerSelector) ######################################################## ################## Calibration Area #################### ######################################################## calibrationCollapsibleButton = ctk.ctkCollapsibleButton() calibrationCollapsibleButton.text = "Calibration" self.layout.addWidget(calibrationCollapsibleButton) parametersFormLayout = qt.QFormLayout(calibrationCollapsibleButton) # # Icons retrieval # sordinaLIACGuidanceModuleDirectoryPath = slicer.modules.sordinaliacguidance.path.replace("SordinaLIACGuidance.py","") recordIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/recordIcon.png') stopIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/stopIcon.png') restartIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/restartIcon.png') saveIcon = qt.QIcon(sordinaLIACGuidanceModuleDirectoryPath + '/Resources/Icons/saveIcon.png') # # Up-down movement recording # upDownMovementGroupBox = ctk.ctkCollapsibleGroupBox() upDownMovementGroupBox.setTitle("Up-Down Movement") upDownMovementGroupBoxFormLayout = qt.QFormLayout(upDownMovementGroupBox) parametersFormLayout.addRow(upDownMovementGroupBox) upDownMovementLayout = qt.QHBoxLayout() upDownMovementGroupBoxFormLayout.addRow(upDownMovementLayout) self.upDownRecordButton = qt.QPushButton(" Record") self.upDownRecordButton.setIcon(recordIcon) self.upDownRecordButton.enabled = True upDownMovementLayout.addWidget(self.upDownRecordButton) # upDownMovementGroupBoxFormLayout.addRow(self.upDownRecordButton) self.upDownStopButton = qt.QPushButton(" Stop") self.upDownStopButton.setIcon(stopIcon) self.upDownStopButton.enabled = False upDownMovementLayout.addWidget(self.upDownStopButton) # upDownMovementGroupBoxFormLayout.addRow(self.upDownStopButton) self.upDownRestartButton = qt.QPushButton(" Restart") self.upDownRestartButton.setIcon(restartIcon) self.upDownRestartButton.enabled = False upDownMovementLayout.addWidget(self.upDownRestartButton) # upDownMovementGroupBoxFormLayout.addRow(self.upDownRestartButton) # # Roll movement recording # rollMovementGroupBox = ctk.ctkCollapsibleGroupBox() rollMovementGroupBox.setTitle("Roll Movement") rollMovementGroupBoxFormLayout = qt.QFormLayout(rollMovementGroupBox) parametersFormLayout.addRow(rollMovementGroupBox) rollMovementLayout = qt.QHBoxLayout() rollMovementGroupBoxFormLayout.addRow(rollMovementLayout) self.rollRecordButton = qt.QPushButton(" Record") self.rollRecordButton.setIcon(recordIcon) self.rollRecordButton.enabled = True rollMovementLayout.addWidget(self.rollRecordButton) # rollMovementGroupBoxFormLayout.addRow(self.rollRecordButton) self.rollStopButton = qt.QPushButton(" Stop") self.rollStopButton.setIcon(stopIcon) self.rollStopButton.enabled = False rollMovementLayout.addWidget(self.rollStopButton) # rollMovementGroupBoxFormLayout.addRow(self.rollStopButton) self.rollRestartButton = qt.QPushButton(" Restart") self.rollRestartButton.setIcon(restartIcon) self.rollRestartButton.enabled = False rollMovementLayout.addWidget(self.rollRestartButton) # rollMovementGroupBoxFormLayout.addRow(self.rollRestartButton) # # Save/load calibration file # self.saveCalibrationButton = qt.QPushButton(" Save Calibration") self.saveCalibrationButton.setIcon(saveIcon) self.saveCalibrationButton.enabled = True self.saveCalibrationButton.adjustSize() self.loadCalibrationButton = qt.QPushButton(" Load Calibration") self.loadCalibrationButton.setIcon(saveIcon) self.loadCalibrationButton.enabled = True self.loadCalibrationButton.adjustSize() self.calibrationErrorLabel = qt.QLabel('Calibration error: - mm') self.calibrationErrorLabel.setStyleSheet("QLabel { color : #000000; font: bold}" ) parametersFormLayout.addRow(self.loadCalibrationButton, self.saveCalibrationButton) parametersFormLayout.addRow(self.calibrationErrorLabel) ######################################################### #################### Guidance Area ###################### ######################################################### guidanceCollapsibleButton = ctk.ctkCollapsibleButton() guidanceCollapsibleButton.text = "Guidance" self.layout.addWidget(guidanceCollapsibleButton) parametersFormLayout = qt.QFormLayout(guidanceCollapsibleButton) # Load Models Button self.loadModelsButton = qt.QPushButton() self.loadModelsButton.toolTip = "Soft tissue visibility." self.loadModelsButton.enabled = True self.loadModelsButton.text = "Load 3D Models" parametersFormLayout.addRow(self.loadModelsButton) # connections self.applicatorToTrackerSelector.connect('currentNodeChanged(vtkMRMLNode*)',self.onSelect) self.liacToTrackerSelector.connect('currentNodeChanged(vtkMRMLNode*)',self.onSelect) self.upDownRecordButton.connect('clicked(bool)', self.onUpDownRecordButton) self.upDownStopButton.connect('clicked(bool)', self.onUpDownStopButton) self.upDownRestartButton.connect('clicked(bool)', self.onUpDownRestartButton) self.rollRecordButton.connect('clicked(bool)', self.onRollRecordButton) self.rollStopButton.connect('clicked(bool)', self.onRollStopButton) self.rollRestartButton.connect('clicked(bool)', self.onRollRestartButton) self.loadModelsButton.connect('clicked(bool)', self.onLoadModelsButton) self.SordinaLIACGuidanceLogic = SordinaLIACGuidanceLogic() # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setupOptionsFrame(self): self.methodSelectorComboBox = qt.QComboBox() self.methodSelectorComboBox.addItem("Median", MEDIAN) self.methodSelectorComboBox.addItem("Opening (remove extrusions)", MORPHOLOGICAL_OPENING) self.methodSelectorComboBox.addItem("Closing (fill holes)", MORPHOLOGICAL_CLOSING) self.methodSelectorComboBox.addItem("Gaussian", GAUSSIAN) self.methodSelectorComboBox.addItem("Joint smoothing", JOINT_TAUBIN) self.scriptedEffect.addLabeledOptionsWidget( "Smoothing method:", self.methodSelectorComboBox) self.kernelSizeMMSpinBox = slicer.qMRMLSpinBox() self.kernelSizeMMSpinBox.setMRMLScene(slicer.mrmlScene) self.kernelSizeMMSpinBox.setToolTip( "Diameter of the neighborhood that will be considered around each voxel. Higher value makes smoothing stronger (more details are suppressed)." ) self.kernelSizeMMSpinBox.quantity = "length" self.kernelSizeMMSpinBox.minimum = 0.0 self.kernelSizeMMSpinBox.value = 3.0 self.kernelSizeMMSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip( "Diameter of the neighborhood in pixel. Computed from the segment's spacing and the specified kernel size." ) kernelSizeFrame = qt.QHBoxLayout() kernelSizeFrame.addWidget(self.kernelSizeMMSpinBox) kernelSizeFrame.addWidget(self.kernelSizePixel) self.kernelSizeMMLabel = self.scriptedEffect.addLabeledOptionsWidget( "Kernel size:", kernelSizeFrame) self.gaussianStandardDeviationMMSpinBox = slicer.qMRMLSpinBox() self.gaussianStandardDeviationMMSpinBox.setMRMLScene(slicer.mrmlScene) self.gaussianStandardDeviationMMSpinBox.setToolTip( "Standard deviation of the Gaussian smoothing filter coefficients. Higher value makes smoothing stronger (more details are suppressed)." ) self.gaussianStandardDeviationMMSpinBox.quantity = "length" self.gaussianStandardDeviationMMSpinBox.value = 3.0 self.gaussianStandardDeviationMMSpinBox.singleStep = 1.0 self.gaussianStandardDeviationMMLabel = self.scriptedEffect.addLabeledOptionsWidget( "Standard deviation:", self.gaussianStandardDeviationMMSpinBox) self.jointTaubinSmoothingFactorSlider = ctk.ctkSliderWidget() self.jointTaubinSmoothingFactorSlider.setToolTip( "Higher value means stronger smoothing.") self.jointTaubinSmoothingFactorSlider.minimum = 0.01 self.jointTaubinSmoothingFactorSlider.maximum = 1.0 self.jointTaubinSmoothingFactorSlider.value = 0.5 self.jointTaubinSmoothingFactorSlider.singleStep = 0.01 self.jointTaubinSmoothingFactorSlider.pageStep = 0.1 self.jointTaubinSmoothingFactorLabel = self.scriptedEffect.addLabeledOptionsWidget( "Smoothing factor:", self.jointTaubinSmoothingFactorSlider) self.applyToAllVisibleSegmentsCheckBox = qt.QCheckBox() self.applyToAllVisibleSegmentsCheckBox.setToolTip( "Apply smoothing effect to all visible segments in this segmentation node. \ This operation may take a while." ) self.applyToAllVisibleSegmentsCheckBox.objectName = self.__class__.__name__ + 'ApplyToAllVisibleSegments' self.applyToAllVisibleSegmentsLabel = self.scriptedEffect.addLabeledOptionsWidget( "Apply to all segments:", self.applyToAllVisibleSegmentsCheckBox) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Apply smoothing to selected segment") self.scriptedEffect.addOptionsWidget(self.applyButton) self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI) self.kernelSizeMMSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.gaussianStandardDeviationMMSpinBox.connect( "valueChanged(double)", self.updateMRMLFromGUI) self.jointTaubinSmoothingFactorSlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.applyToAllVisibleSegmentsCheckBox.connect("stateChanged(int)", self.updateMRMLFromGUI) self.applyButton.connect('clicked()', self.onApply) # Customize smoothing brush self.scriptedEffect.setColorSmudgeCheckboxVisible(False) self.paintOptionsGroupBox = ctk.ctkCollapsibleGroupBox() self.paintOptionsGroupBox.setTitle("Smoothing brush options") self.paintOptionsGroupBox.setLayout(qt.QVBoxLayout()) self.paintOptionsGroupBox.layout().addWidget( self.scriptedEffect.paintOptionsFrame()) self.paintOptionsGroupBox.collapsed = True self.scriptedEffect.addOptionsWidget(self.paintOptionsGroupBox)
def setup(self): self.detailsPopup = None self.setDetailsPopup(self.getSavedDICOMDetailsWidgetType()()) # XXX Slicer 4.5 - Remove these. Here only for backward compatibility. self.dicomBrowser = self.detailsPopup.dicomBrowser self.tables = self.detailsPopup.tables layoutManager = slicer.app.layoutManager() if layoutManager is not None: layoutManager.layoutChanged.connect(self.onLayoutChanged) # connect to the 'Show DICOM Browser' button self.showBrowserButton = qt.QPushButton('Show DICOM database browser') self.showBrowserButton.setCheckable(True) self.layout.addWidget(self.showBrowserButton) self.showBrowserButton.setStyleSheet("font:Bold;" "font-size:12px") self.showBrowserButton.connect('clicked()', self.toggleDetailsPopup) self.loadedDataLabel = qt.QLabel("Loaded data") self.loadedDataLabel.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed) self.layout.addWidget(self.loadedDataLabel) font = qt.QFont() font.setBold(True) font.setPointSize(12) self.loadedDataLabel.setFont(font) self.layout.addWidget(self.loadedDataLabel) self.subjectHierarchyTree = slicer.qMRMLSubjectHierarchyTreeView() self.layout.addWidget(self.subjectHierarchyTree) self.subjectHierarchyTree.setMRMLScene(slicer.mrmlScene) self.subjectHierarchyTree.currentItemChanged.connect( self.onCurrentItemChanged) self.subjectHierarchyTree.currentItemModified.connect( self.onCurrentItemModified) self.subjectHierarchyCurrentVisibility = False self.subjectHierarchyTree.setColumnHidden( self.subjectHierarchyTree.model().idColumn, True) self.browserSettingsWidget = ctk.ctkCollapsibleGroupBox() self.browserSettingsWidget.title = "Browser settings" self.layout.addWidget(self.browserSettingsWidget) self.browserSettingsWidget.collapsed = True self.browserSettingsWidget.setLayout(qt.QFormLayout()) self.directoryButton = ctk.ctkDirectoryButton() self.browserSettingsWidget.layout().addRow("Local database:", self.directoryButton) self.directoryButton.directoryChanged.connect( self.onDatabaseDirectoryButtonChanged) self.onDatabaseDirectoryDetailsPopupChanged( self.detailsPopup.dicomBrowser.databaseDirectory) self.tableDensityComboBox = qt.QComboBox() self.browserSettingsWidget.layout().addRow("Table density:", self.tableDensityComboBox) self.tableDensityComboBox.currentIndexChanged.connect( self.onTableDensityChanged) self.updateTableDensityComboBox() self.horizontalCheckBox = qt.QCheckBox() self.horizontalCheckBox.checked = settingsValue( 'DICOM/horizontalTables', 0, converter=int) self.horizontalCheckBox.stateChanged.connect( self.onHorizontalStateChanged) self.browserSettingsWidget.layout().addRow("Horizontal:", self.horizontalCheckBox) self.browserPersistentCheckBox = qt.QCheckBox() self.browserPersistentCheckBox.checked = settingsValue( 'DICOM/BrowserPersistent', False, converter=toBool) self.browserPersistentCheckBox.stateChanged.connect( self.onBrowserPersistentStateChanged) self.browserSettingsWidget.layout().addRow( "Browser persistent:", self.browserPersistentCheckBox) self.additionalSettingsLayout = qt.QHBoxLayout() # # servers # # testing server - not exposed (used for development) self.localFrame = ctk.ctkCollapsibleButton(self.parent) self.localFrame.setLayout(qt.QVBoxLayout()) self.localFrame.setText("Servers") self.layout.addWidget(self.localFrame) self.localFrame.collapsed = True self.toggleServer = qt.QPushButton("Start Testing Server") self.localFrame.layout().addWidget(self.toggleServer) self.toggleServer.connect('clicked()', self.onToggleServer) self.verboseServer = qt.QCheckBox("Verbose") self.localFrame.layout().addWidget(self.verboseServer) # advanced options - not exposed to end users # developers can uncomment these lines to access testing server self.toggleServer.hide() self.verboseServer.hide() # Listener settings = qt.QSettings() self.toggleListener = qt.QPushButton() self.toggleListener.checkable = True if hasattr(slicer, 'dicomListener'): self.toggleListener.text = "Stop Listener" slicer.dicomListener.process.connect( 'stateChanged(QProcess::ProcessState)', self.onListenerStateChanged) else: self.toggleListener.text = "Start Listener" self.localFrame.layout().addWidget(self.toggleListener) self.toggleListener.connect('clicked()', self.onToggleListener) self.runListenerAtStart = qt.QCheckBox( "Start Listener when Slicer Starts") self.localFrame.layout().addWidget(self.runListenerAtStart) self.runListenerAtStart.checked = settingsValue( 'DICOM/RunListenerAtStart', False, converter=toBool) self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart) # connect to the main window's dicom button mw = slicer.util.mainWindow() if mw: try: action = slicer.util.findChildren(mw, name='LoadDICOMAction')[0] action.connect('triggered()', self.onOpenDetailsPopup) except IndexError: logging.error( 'Could not connect to the main window DICOM button') if hasattr(slicer, 'dicomListener'): slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged) # the recent activity frame self.activityFrame = ctk.ctkCollapsibleButton(self.parent) self.activityFrame.collapsed = True self.activityFrame.setLayout(qt.QVBoxLayout()) self.activityFrame.setText("Recent DICOM Activity") self.layout.addWidget(self.activityFrame) self.recentActivity = DICOMLib.DICOMRecentActivityWidget( self.activityFrame, detailsPopup=self.detailsPopup) self.activityFrame.layout().addWidget(self.recentActivity) self.requestUpdateRecentActivity()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # This module is often used in developer mode, therefore # collapse reload & test section by default. if hasattr(self, "reloadCollapsibleButton"): self.reloadCollapsibleButton.collapsed = True self.observerTags = [] self.logic = SampleDataLogic(self.logMessage) numberOfColumns = 3 iconPath = os.path.join( os.path.dirname(__file__).replace('\\', '/'), 'Resources', 'Icons') desktop = qt.QDesktopWidget() mainScreenSize = desktop.availableGeometry(desktop.primaryScreen) iconSize = qt.QSize(mainScreenSize.width() / 15, mainScreenSize.height() / 10) categories = slicer.modules.sampleDataSources.keys() categories.sort() if 'BuiltIn' in categories: categories.remove('BuiltIn') categories.insert(0, 'BuiltIn') for category in categories: frame = ctk.ctkCollapsibleGroupBox(self.parent) self.layout.addWidget(frame) frame.title = category frame.name = '%sCollapsibleGroupBox' % category layout = qt.QGridLayout(frame) columnIndex = 0 rowIndex = 0 for source in slicer.modules.sampleDataSources[category]: name = source.sampleName if not name: name = source.nodeNames[0] b = qt.QToolButton() b.setText(name) # Set thumbnail if source.thumbnailFileName: # Thumbnail provided thumbnailImage = source.thumbnailFileName else: # Look for thumbnail image with the name of any node name with .png extension thumbnailImage = None for nodeName in source.nodeNames: if not nodeName: continue thumbnailImageAttempt = os.path.join( iconPath, nodeName + '.png') if os.path.exists(thumbnailImageAttempt): thumbnailImage = thumbnailImageAttempt break if thumbnailImage and os.path.exists(thumbnailImage): b.setIcon(qt.QIcon(thumbnailImage)) b.setIconSize(iconSize) b.setToolButtonStyle(qt.Qt.ToolButtonTextUnderIcon) qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) b.setSizePolicy(qSize) b.name = '%sPushButton' % name layout.addWidget(b, rowIndex, columnIndex) columnIndex += 1 if columnIndex == numberOfColumns: rowIndex += 1 columnIndex = 0 if source.customDownloader: b.connect('clicked()', source.customDownloader) else: b.connect( 'clicked()', lambda s=source: self.logic.downloadFromSource(s)) self.log = qt.QTextEdit() self.log.readOnly = True self.layout.addWidget(self.log) self.logMessage('<p>Status: <i>Idle</i>\n') # Add spacer to layout self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Connection connectionCollapsibleButton = ctk.ctkCollapsibleButton() connectionCollapsibleButton.text = "OSC server connection" self.layout.addWidget(connectionCollapsibleButton) connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton) self.hostnameLineEdit = qt.QLineEdit("localhost") connectionFormLayout.addRow("Host name: ", self.hostnameLineEdit) self.portLineEdit = qt.QLineEdit("7400") self.portLineEdit.setValidator( qt.QIntValidator(0, 65535, self.portLineEdit)) connectionFormLayout.addRow("Port: ", self.portLineEdit) self.addressRootLineEdit = qt.QLineEdit("SoundNav") self.addressRootLineEdit.setToolTip( "OSC address root. Complete address: /<address root>/<instrument name>/<parameter name>." ) connectionFormLayout.addRow("Address root: ", self.addressRootLineEdit) self.enableConnectionCheckBox = qt.QCheckBox() self.enableConnectionCheckBox.checked = False self.enableConnectionCheckBox.setToolTip( "If checked, then transform changes will be immediately sent to specified OSC server." ) connectionFormLayout.addRow("Transmission active: ", self.enableConnectionCheckBox) self.enableConnectionCheckBox.connect('stateChanged(int)', self.setTransmissionActive) # Parameters Area parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) parameterNode = self.logic.getParameterNode() maxNumberOfInstruments = int( parameterNode.GetParameter("MaxNumberOfInstruments")) for instrumentIndex in range(maxNumberOfInstruments): instrumentGroupBox = ctk.ctkCollapsibleGroupBox() instrumentGroupBox.title = "Instrument " + str(instrumentIndex + 1) parametersFormLayout.addWidget(instrumentGroupBox) instrumentLayout = qt.QFormLayout(instrumentGroupBox) nameLineEdit = qt.QLineEdit() instrumentLayout.addRow("Instrument name: ", nameLineEdit) nameLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) instrumentSourceSelector = slicer.qMRMLNodeComboBox() instrumentNodeTypes = ["vtkMRMLLinearTransformNode"] if hasattr(slicer.modules, 'breachwarning'): instrumentNodeTypes.append("vtkMRMLBreachWarningNode") instrumentSourceSelector.nodeTypes = instrumentNodeTypes instrumentSourceSelector.addEnabled = True instrumentSourceSelector.removeEnabled = True instrumentSourceSelector.noneEnabled = True instrumentSourceSelector.renameEnabled = True instrumentSourceSelector.setMRMLScene(slicer.mrmlScene) instrumentSourceSelector.setToolTip( "Defines position and orientation of the instrument (transform or breach warning node)" ) instrumentLayout.addRow("Instrument node: ", instrumentSourceSelector) instrumentSourceSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) instrumentReferenceSelector = slicer.qMRMLNodeComboBox() instrumentReferenceSelector.nodeTypes = [ "vtkMRMLLinearTransformNode" ] instrumentReferenceSelector.addEnabled = True instrumentReferenceSelector.removeEnabled = True instrumentReferenceSelector.noneEnabled = True instrumentReferenceSelector.renameEnabled = True instrumentReferenceSelector.setMRMLScene(slicer.mrmlScene) instrumentReferenceSelector.setToolTip( "Position and orientation is defined relative to this transform" ) instrumentLayout.addRow("Reference transform: ", instrumentReferenceSelector) instrumentReferenceSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) widgets = {} widgets['instrumentGroupBox'] = instrumentGroupBox widgets['nameLineEdit'] = nameLineEdit widgets['instrumentSourceSelector'] = instrumentSourceSelector widgets[ 'instrumentReferenceSelector'] = instrumentReferenceSelector self.instrumentWidgets.append(widgets) self.updateGUIFromMRML() self.hostnameLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) self.portLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) self.addressRootLineEdit.connect('editingFinished()', self.updateMRMLFromGUI) for instrumentIndex in range(len(self.instrumentWidgets)): widgets = self.instrumentWidgets[instrumentIndex] # Collapse unused instrument groupboxes widgets['instrumentGroupBox'].collapsed = not widgets[ 'nameLineEdit'].text # Observe widget changes to update MRML node immediately (this way always up-to-date values will be saved in the scene) widgets['nameLineEdit'].connect('editingFinished()', self.updateMRMLFromGUI) widgets['instrumentSourceSelector'].connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) widgets['instrumentReferenceSelector'].connect( "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI) self.parameterNodeObserverTag = parameterNode.AddObserver( vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML) # Add vertical spacer self.layout.addStretch(1)