from schrodinger.ui.qt.appframework2 import af2
# Super = af2.App # Use for non-job panels
Super = af2.JobApp # Use for job panels
[docs]class AppTemplate(Super):
[docs] def __init__(self, **kwargs):
# Set options for JobApp or App and call the base class __init__.
# The base __init__ will call setPanelOptions, setup, setDefaults, and
# layOut, in that order.
Super.__init__(self, **kwargs)
# Anything that gets placed here will be executed after layOut().
[docs] def setPanelOptions(self):
# Define instance variables that specify the creation of the panel. Call
# the super class first.
Super.setPanelOptions(self)
self.maestro_dockable = True
self.title = 'My Application Panel'
self.allowed_run_modes = (af2.baseapp.MODE_MAESTRO,
af2.baseapp.MODE_STANDALONE)
# Or a single value, such as:
self.allowed_run_modes = af2.baseapp.MODE_STANDALONE
self.input_selector_options = {} # Formerly called input frame (_if)
# self.ui = template_ui.Ui_Form() # A UiForm instance
# Job App Options:
self.program_name = 'Program'
self.default_jobname = 'jobname'
[docs] def getConfigDialog(self):
# Define this method to get a config dialog. Only works in JobApp, not
# App.
return af2.ConfigDialog(self,
incorporation=True,
default_disp=af2.DISP_APPEND,
cpus=True,
host=True)
[docs] def setup(self):
# This is the place to initialize variables, create widgets, connect
# signals, slots, validators, etc. Generally call the super class setup
# first and then proceed with our own setup
Super.setup(self)
[docs] def setDefaults(self):
# Any default values that need to be set should be done in this method.
Super.setDefaults(self)
[docs] def layOut(self):
# Add widgets to the panel layouts
Super.layOut(self)
[docs] def defineCustomSettings(self):
# Define any custom settings for saving and restoring panel state. See
# af2.App documentation for details.
# Real example for optoelectronics_gui.py. self.propbuttons in that
# panel is just a list of check boxes, one for each optional property,
# where button.propflag is a string label for that property.
custom = [(button.propflag, button) for button in self.propbuttons]
# Custom setter/getter
custom.append(("Table", self.data_table, self.setData, self.getData))
# Custom, human-readable label
custom.append(("Temperature", self.bfactor_spinbox))
return custom
#=========================================================================
# Button methods
#=========================================================================
# Use decorators to indicate which methods are start, write, read, etc.
# By default, the start method will double as a write method. For more
# information, see the doc for the start decorator in the appmethods
# module
[docs] @af2.appmethods.start()
def startJob(self):
# Any method (but only one) can be defined as a start method. This will
# automatically be hooked up to the start button in the bottom bar, and
# can have any name.
# Passing a string argument to start() decorator will cause the Run
# button to have that name. Passing a <tooltip> argument will add a
# custom tooltip to the run button.
print('This is my start method')
[docs] @af2.appmethods.reset()
def resetPanel(self):
# This method will be called when the "Reset" action is selected, and
# can have any name. Simply defining a no-op method with the reset()
# decorator is enough to have the "Reset" action to show up - by
# default it will call the setDefaults() method. Passing a string
# argument to the reset() decorator will cause the reset action menu
# item to have that given name.
pass
[docs] @af2.appmethods.close()
def closePanel(self):
# This method will be called when the panel is closed. It can have
# any name.
print('Closing panel')
# Decorators may also be used to indicate Maestro callback methods
[docs] @af2.maestro_callback.project_changed
def onProjectChanged(self, proj):
print('The project was just updated but not closed')
[docs] @af2.maestro_callback.project_close
def onProjectClosed(self):
print('The project was just closed')
[docs] @af2.maestro_callback.workspace_changed
def onWorkspaceChanged(self, what_changed):
print('The workspace was just changed')
[docs] @af2.maestro_callback.workspace_changed_active_project
def onWorkspaceChangedWithActiveProj(self, what_changed, proj):
print('The workspace was just changed, but not due to project closure')
#=========================================================================
# Validation methods
#=========================================================================
# Decorators are also used to indicate that a method should be run at
# whenever the panel is validated.
@af2.validator()
def validatePanel(self):
# A validation should either return a True/False value or a tuple
# consisting of (True/False, message string). True with a message is
# interpreted as a warning. Note that forgetting to return something
# will return None, which will evaluate to False and fail validation.
# Multiple validation methods can be defined, and they can have any
# name.
print('Running a validation method')
return True
panel = AppTemplate.panel
if __name__ == "__main__":
panel()
#===============================================================================
# Encoding settings in job names
#===============================================================================
[docs]class SettingsInJobNamesTemplate(af2.JobApp):
"""
This class includes panel settings in its job name
"""
[docs] def setPanelOptions(self):
super(SettingsInJobNamesTemplate, self).setPanelOptions()
self.title = "Settings in Job Names Template Panel"
# Include interpolation characters in the default jobname
self.default_jobname = "jobname_%s_%i_%s"
# Either old-style or new-style interpolation may be used
# self.default_jobname = "jobname_{}_{}_{}"
# Named interpolation can also be used. For this, jobnameData should
# return a dictionary instead of a tuple
# self.default_jobname = "jobname_%(setting1)s_%(setting2)s_%(setting3)s"
# self.default_jobname = "jobname_{setting1}_{setting2}_{setting3}"
self.ui = my_ui_module.Ui_Form() # noqa
[docs] def setup(self):
"""
In setup, make sure that `self.jobnameDataChanged` is called every time
the jobname needs to be updated
"""
super(SettingsInJobNamesTemplate, self).setup()
self.ui.setting1_combo.currentIndexChanged.connect(
self.jobnameDataChanged)
self.ui.setting2_sb.valueChanged.connect(self.jobnameDataChanged)
self.ui.setting3_le.textChanged.connect(self.jobnameDataChanged)
[docs] def jobnameData(self):
"""
Reimplement `jobnameData` to return the data to be interpolated into
the job name
"""
setting1 = self.ui.setting1_combo.currentText()
setting2 = self.ui.setting2_sb.value()
setting3 = self.ui.setting3_le.text()
# santizeJobnameText() converts spaces to underscores and removes all
# other characters that are disallowed in job names
setting3 = self.sanitizeJobnameText(setting3)
return (setting1, setting2, setting3)
# If using named interpolation, return a dictionary here instead of a
# tuple
return locals()