def fillInUI(self, parent): import Pmw, Tkinter row = 0 Tkinter.Label(parent, text="Create plane for selected atoms...").grid( row=row, columnspan=2) row += 1 from chimera.tkoptions import StringOption, BooleanOption self.nameOpt = StringOption(parent, row, "Plane name", "plane", None) row += 1 self.replaceExistingOpt = BooleanOption(parent, row, "Replace existing planes", False, None) row += 1 from chimera.tkoptions import ColorOption, FloatOption self.colorOpt = ColorOption(parent, row, "Color", None, None, balloon="Plane color. If No Color, then the plane" " will be colored to match the structure") row += 1 self.autoRadiusOpt = BooleanOption(parent, row, "Set disk size to enclose atom projections", True, self._radCB) row += 1 self.radRow = row self.radOffsetOpt = FloatOption(parent, row, "Extra radius" " (padding)", 0.0, None) self.radiusOpt = FloatOption(parent, row, "Fixed radius", 10.0, None) self.radiusOpt.forget() row += 1 self.thicknessOpt = FloatOption(parent, row, "Disk thickness", prefs[PLANE_THICKNESS], None)
def __init__(self, parent, relaxColor, colorOptions=True): self._relaxConstraints = Tkinter.IntVar(parent) self._relaxConstraints.set(True) Pmw.Group.__init__(self, parent, ring_relief='ridge', tag_pyclass=Tkinter.Checkbutton, tag_text='Relax H-bond constraints', tag_variable=self._relaxConstraints) self._relaxLabel = Tkinter.Label(self.interior(), text="Relax constraints by: ") self._relaxLabel.grid(row=0, column=0, rowspan=2, sticky='e') self._relaxDist = Pmw.EntryField(self.interior(), labelpos='e', label_text='angstroms', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recDistSlop), entry_width=5) self._relaxDist.grid(row=0, column=1, sticky='w') self._relaxAngle = Pmw.EntryField(self.interior(), labelpos='e', label_text='degrees', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recAngleSlop), entry_width=5) self._relaxAngle.grid(row=1, column=1, sticky='w') if not colorOptions: return self._useRelaxColor = Tkinter.IntVar(parent) self._useRelaxColor.set(0) f = Tkinter.Frame(self.interior()) f.grid(row=2, column=0, columnspan=2) Tkinter.Checkbutton(f, text="Color H-bonds not meeting " "precise criteria differently:", variable=self._useRelaxColor).grid(row=0, column=0, sticky='e') self._relaxColor = ColorOption(f, 0, "", relaxColor, None, startCol=1, noneOkay=0)
def gridUIElements(self): _onEditColor = lambda i: self.onEdit() c = 0 for k,v in self.fields.items(): _ui = self.fields[k][1] _data = self.fields[k][0] _label = self.fields[k][2] if isinstance(_ui,Entry): _label.grid(column=c,row=0,sticky="E") c+=1 _ui.grid(column=c,row=0,pady=5,padx=3) c+=1 elif inspect.isclass(_ui): if issubclass(_ui,ColorOption): _option = ColorOption(self,0,None,None,_onEditColor,\ startCol=c) _option.set(_data) self.fields[k] = (_data,_option,None,None) c+=1 elif isinstance(_ui,OptionMenu): _label.grid(column=c,row=0,sticky="E") c+=1 _ui.grid(column=c,row=0,pady=5,padx=3) c+=1 elif isinstance(_ui,FileFrame): _ui.grid(column=c,row=0,pady=5,padx=3) c+=1 elif isinstance(_ui,MapFrame): _ui.grid(column=c,row=0,pady=5,padx=3) c+=1 elif isinstance(_ui,ItemList): _ui.grid(column=0,row=1,padx=3,columnspan=5) if not self.active: self.apply.grid(column=c,row=0,pady=5,padx=3) c+=1 self.delete.grid(column=c,row=0,pady=5,padx=3) c+=1 else: self.add.grid(column=c,row=0,pady=5,padx=3) if self.active: self.empty()
def __init__(self, parent, relaxColor, colorOptions=True): self._relaxConstraints = Tkinter.IntVar(parent) self._relaxConstraints.set(True) Pmw.Group.__init__(self, parent, ring_relief='ridge', tag_pyclass=Tkinter.Checkbutton, tag_text='Relax H-bond constraints', tag_variable=self._relaxConstraints) self._relaxLabel = Tkinter.Label(self.interior(), text="Relax constraints by: ") self._relaxLabel.grid(row=0, column=0, rowspan=2, sticky='e') self._relaxDist = Pmw.EntryField(self.interior(), labelpos='e', label_text='angstroms', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recDistSlop), entry_width=5) self._relaxDist.grid(row=0, column=1, sticky='w') self._relaxAngle = Pmw.EntryField(self.interior(), labelpos='e', label_text='degrees', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recAngleSlop), entry_width=5) self._relaxAngle.grid(row=1, column=1, sticky='w') if not colorOptions: return self._useRelaxColor = Tkinter.IntVar(parent) self._useRelaxColor.set(0) f = Tkinter.Frame(self.interior()) f.grid(row=2, column=0, columnspan=2) Tkinter.Checkbutton(f, text="Color H-bonds not meeting " "precise criteria differently:", variable=self._useRelaxColor).grid(row=0, column=0, sticky='e') self._relaxColor = ColorOption(f, 0, "", relaxColor, None, startCol=1, noneOkay=0)
def fillInUI(self, master): # Create a ColorOption instance. The ColorOption will contain # a descriptive label and a color well. The arguments to the # ColorOption constructor are: # - master widget # - row number to use when 'grid'ing the ColorOption into the # master widget. The default column is 0. The tkoptions # module contains other options besides ColorOption (e.g. # StringOption), which are generally intended to be put in # vertical lists, and therefore a row number is specified in # the constructor. In this example we are only using one # option however. # - option label. This will be positioned to the left of the # color well and a ":" will be appended. # - The default value for this option. # - A callback function to call when the option is set by the # user (e.g. a color dragged to the well, or the well color # edited in the color editor) # - An optional ballon-help message # coloropt = ColorOption(master, 0, 'Backbone Color', None, self._setBackboneColor, balloon='Protein backbone color') # Call '_updateBackboneColor' to make the color displayed # in the color well reflect the current color of protein # backbone atoms. While not strictly necessary, keeping the # color in the well consistent with the color in the molecules # enhances the extension usability. self._updateBackboneColor(coloropt)
def fillInUI(self, parent): # inter/intra-model; slop; colors; models; replace current; # label # for removing labels in subsequent passes... # (use a selection so I don't have to track model closures) self.labelSelection = ItemizedSelection() self.labelMap = {} self.callbacks = [] row = 0 cols = 3 self.bondColorOption = ColorOption(parent, row, 'H-bond color', prefs[BOND_COLOR], None, noneOkay=0) class HBLineWidthOption(LineWidthOption): name = "Line width" balloon = "Width of pseudobonds (in pixels)" default = prefs[LINE_WIDTH] self.lineWidth = HBLineWidthOption(parent, row + 1, None, None, None, width=4, sticky='w') self.findMode = Pmw.RadioSelect(parent, buttontype='radiobutton', labelpos='n', pady=0, orient='vertical', label_text='Find these bonds:', hull_borderwidth=2, hull_relief='ridge') self.findMode.add('inter-model') self.findMode.add('intra-model') self.findMode.add('both') self.findMode.invoke('both') self.findMode.grid(row=row, column=2, rowspan=2) row += 2 self.relaxParams = RelaxParams(parent, prefs[RELAX_COLOR]) self.relaxParams.grid(row=row, columnspan=cols, sticky='nsew', padx=2) row += 1 self.restrictModels = Tkinter.IntVar(parent) self.restrictModels.set(0) self.modelFrame = Tkinter.Frame(parent) self.molTexts = ["Restrict to models...", "Restrict to models:"] self.restrictCheckBox = Tkinter.Checkbutton( self.modelFrame, variable=self.restrictModels, text=self.molTexts[0], command=self._restrictModelsCB) self.restrictCheckBox.grid(row=0, column=0) from chimera.widgets import MoleculeScrolledListBox self.molList = MoleculeScrolledListBox(self.modelFrame, listbox_selectmode="extended") self.modelFrame.rowconfigure(0, weight=1) self.modelFrame.grid(row=row, column=0, columnspan=cols, sticky="nsw") parent.rowconfigure(row, weight=1) row += 1 self.inSelection = Tkinter.IntVar(parent) self.inSelection.set(0) f = Tkinter.Frame(parent) f.grid(row=row, column=0, columnspan=cols, sticky="w") Tkinter.Checkbutton(f, variable=self.inSelection, text="Only find H-bonds with", command=self._useSelChange).grid(row=0, column=0, sticky="e") self.selType = Pmw.OptionMenu( f, items=["at least one end", "exactly one end", "both ends"], initialitem=0, menubutton_state="disabled", labelpos="e", label_text="selected") self.selType.grid(row=0, column=1, sticky="w") row += 1 self.revealEnds = Tkinter.IntVar(parent) self.revealEnds.set(0) Tkinter.Checkbutton( parent, variable=self.revealEnds, text="If endpoint atom hidden, show endpoint residue").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 self.retainCurrent = Tkinter.IntVar(parent) self.retainCurrent.set(0) Tkinter.Checkbutton(parent, variable=self.retainCurrent, text="Retain currently displayed H-bonds").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 self.interSubmodel = Tkinter.IntVar(parent) self.interSubmodel.set(0) # comment out the below since there seems to be no # situations where cross-submodel-same-model hbonds # are interesting. If reading pdbrun files occurs, this # may change. #Tkinter.Checkbutton(parent, variable=self.interSubmodel, # text="Find H-bonds between submodels\n" # "having same principal model number" # ).grid(row=row, column=0, columnspan=cols, sticky="w") #row += 1 self.writeFile = Tkinter.IntVar(parent) self.writeFile.set(0) Tkinter.Checkbutton(parent, variable=self.writeFile, text="Write information to file").grid( row=row, column=0, columnspan=cols, sticky="w") self.fileName = None row += 1 self.writeLog = Tkinter.IntVar(parent) self.writeLog.set(0) Tkinter.Checkbutton(parent, variable=self.writeLog, text="Write information to reply log").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1
class HBDialog(ModelessDialog): title = "H-Bond Parameters" buttons = ("OK", "Apply", "Close") default = 'OK' help = "ContributedSoftware/findhbond/findhbond.html" def fillInUI(self, parent): # inter/intra-model; slop; colors; models; replace current; # label # for removing labels in subsequent passes... # (use a selection so I don't have to track model closures) self.labelSelection = ItemizedSelection() self.labelMap = {} self.callbacks = [] row = 0 cols = 3 self.bondColorOption = ColorOption(parent, row, 'H-bond color', prefs[BOND_COLOR], None, noneOkay=0) class HBLineWidthOption(LineWidthOption): name = "Line width" balloon = "Width of pseudobonds (in pixels)" default = prefs[LINE_WIDTH] self.lineWidth = HBLineWidthOption(parent, row + 1, None, None, None, width=4, sticky='w') self.findMode = Pmw.RadioSelect(parent, buttontype='radiobutton', labelpos='n', pady=0, orient='vertical', label_text='Find these bonds:', hull_borderwidth=2, hull_relief='ridge') self.findMode.add('inter-model') self.findMode.add('intra-model') self.findMode.add('both') self.findMode.invoke('both') self.findMode.grid(row=row, column=2, rowspan=2) row += 2 self.relaxParams = RelaxParams(parent, prefs[RELAX_COLOR]) self.relaxParams.grid(row=row, columnspan=cols, sticky='nsew', padx=2) row += 1 self.restrictModels = Tkinter.IntVar(parent) self.restrictModels.set(0) self.modelFrame = Tkinter.Frame(parent) self.molTexts = ["Restrict to models...", "Restrict to models:"] self.restrictCheckBox = Tkinter.Checkbutton( self.modelFrame, variable=self.restrictModels, text=self.molTexts[0], command=self._restrictModelsCB) self.restrictCheckBox.grid(row=0, column=0) from chimera.widgets import MoleculeScrolledListBox self.molList = MoleculeScrolledListBox(self.modelFrame, listbox_selectmode="extended") self.modelFrame.rowconfigure(0, weight=1) self.modelFrame.grid(row=row, column=0, columnspan=cols, sticky="nsw") parent.rowconfigure(row, weight=1) row += 1 self.inSelection = Tkinter.IntVar(parent) self.inSelection.set(0) f = Tkinter.Frame(parent) f.grid(row=row, column=0, columnspan=cols, sticky="w") Tkinter.Checkbutton(f, variable=self.inSelection, text="Only find H-bonds with", command=self._useSelChange).grid(row=0, column=0, sticky="e") self.selType = Pmw.OptionMenu( f, items=["at least one end", "exactly one end", "both ends"], initialitem=0, menubutton_state="disabled", labelpos="e", label_text="selected") self.selType.grid(row=0, column=1, sticky="w") row += 1 self.revealEnds = Tkinter.IntVar(parent) self.revealEnds.set(0) Tkinter.Checkbutton( parent, variable=self.revealEnds, text="If endpoint atom hidden, show endpoint residue").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 self.retainCurrent = Tkinter.IntVar(parent) self.retainCurrent.set(0) Tkinter.Checkbutton(parent, variable=self.retainCurrent, text="Retain currently displayed H-bonds").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 self.interSubmodel = Tkinter.IntVar(parent) self.interSubmodel.set(0) # comment out the below since there seems to be no # situations where cross-submodel-same-model hbonds # are interesting. If reading pdbrun files occurs, this # may change. #Tkinter.Checkbutton(parent, variable=self.interSubmodel, # text="Find H-bonds between submodels\n" # "having same principal model number" # ).grid(row=row, column=0, columnspan=cols, sticky="w") #row += 1 self.writeFile = Tkinter.IntVar(parent) self.writeFile.set(0) Tkinter.Checkbutton(parent, variable=self.writeFile, text="Write information to file").grid( row=row, column=0, columnspan=cols, sticky="w") self.fileName = None row += 1 self.writeLog = Tkinter.IntVar(parent) self.writeLog.set(0) Tkinter.Checkbutton(parent, variable=self.writeLog, text="Write information to reply log").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 def addCallback(self, callback): self.callbacks.append(callback) def Apply(self): states = {} for but in self.buttonWidgets.values(): states[but] = but.cget('state') but.config(state='disabled') try: self._Apply() finally: for but, state in states.items(): but.config(state=state) for cb in self.callbacks: try: cb() except: replyobj.reportException("H-bond callback function") self.callbacks = [] def _Apply(self): intramodel = intermodel = 1 cursel = self.findMode.getcurselection() if cursel == 'inter-model': intramodel = 0 elif cursel == 'intra-model': intermodel = 0 distSlop = 0.0 angleSlop = 0.0 twoColors = False relax = self.relaxParams.relaxConstraints rc = self.relaxParams.relaxColor if relax: distSlop = self.relaxParams.relaxDist angleSlop = self.relaxParams.relaxAngle if self.relaxParams.useRelaxColor: twoColors = True prefs[RELAX_COLOR] = rc.rgba if self.inSelection.get(): selRestrict = ["any", "cross", "both"][self.selType.index(Pmw.SELECT)] else: selRestrict = None lineWidth = self.lineWidth.get() prefs[LINE_WIDTH] = lineWidth bc = self.bondColorOption.get() prefs[BOND_COLOR] = bc.rgba if self.writeFile.get(): saveFile = '-' else: saveFile = None if self.restrictModels.get(): models = self.molList.getvalue() if not models: raise ValueError, "No restriction models chosen" else: models = None from base import createHBonds createHBonds(models=models, intramodel=intramodel, intermodel=intermodel, relax=relax, distSlop=distSlop, angleSlop=angleSlop, twoColors=twoColors, selRestrict=selRestrict, lineWidth=lineWidth, saveFile=saveFile, log=self.writeLog.get(), retainCurrent=self.retainCurrent.get(), reveal=self.revealEnds.get(), color=bc, slopColor=rc) def Close(self): self.callbacks = [] ModelessDialog.Close(self) def _restrictModelsCB(self): restrict = self.restrictModels.get() self.restrictCheckBox.config(text=self.molTexts[restrict]) if restrict: self.molList.grid(row=0, column=1, sticky="ns") else: self.molList.grid_forget() def _useSelChange(self): if self.inSelection.get(): self.selType.component("menubutton").config(state="normal") else: self.selType.component("menubutton").config(state="disabled")
class RelaxParams(Pmw.Group): def __init__(self, parent, relaxColor, colorOptions=True): self._relaxConstraints = Tkinter.IntVar(parent) self._relaxConstraints.set(True) Pmw.Group.__init__(self, parent, ring_relief='ridge', tag_pyclass=Tkinter.Checkbutton, tag_text='Relax H-bond constraints', tag_variable=self._relaxConstraints) self._relaxLabel = Tkinter.Label(self.interior(), text="Relax constraints by: ") self._relaxLabel.grid(row=0, column=0, rowspan=2, sticky='e') self._relaxDist = Pmw.EntryField(self.interior(), labelpos='e', label_text='angstroms', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recDistSlop), entry_width=5) self._relaxDist.grid(row=0, column=1, sticky='w') self._relaxAngle = Pmw.EntryField(self.interior(), labelpos='e', label_text='degrees', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recAngleSlop), entry_width=5) self._relaxAngle.grid(row=1, column=1, sticky='w') if not colorOptions: return self._useRelaxColor = Tkinter.IntVar(parent) self._useRelaxColor.set(0) f = Tkinter.Frame(self.interior()) f.grid(row=2, column=0, columnspan=2) Tkinter.Checkbutton(f, text="Color H-bonds not meeting " "precise criteria differently:", variable=self._useRelaxColor).grid(row=0, column=0, sticky='e') self._relaxColor = ColorOption(f, 0, "", relaxColor, None, startCol=1, noneOkay=0) def enable(self): self.configure(tag_state=Tkinter.NORMAL) self._relaxLabel.config(state=Tkinter.NORMAL) #self._relaxDist.config(entry_state=Tkinter.NORMAL, # label_state=Tkinter.NORMAL) #self._relaxAngle.config(entry_state=Tkinter.NORMAL, # label_state=Tkinter.NORMAL) # not sure why the above doesn't work, so: for w in (self._relaxDist, self._relaxAngle): for c in ('entry', 'label'): wc = w.component(c) wc.config(state=Tkinter.NORMAL) # TODO: color def disable(self): self.configure(tag_state=Tkinter.DISABLED) self._relaxLabel.config(state=Tkinter.DISABLED) #self._relaxDist.config(entry_state=Tkinter.DISABLED, # label_state=Tkinter.DISABLED) #self._relaxAngle.config(entry_state=Tkinter.DISABLED, # label_state=Tkinter.DISABLED) # not sure why the above doesn't work, so: for w in (self._relaxDist, self._relaxAngle): for c in ('entry', 'label'): wc = w.component(c) wc.config(state=Tkinter.DISABLED) # TODO: color def __getattr__(self, attrName): if attrName == "relaxConstraints": return self._relaxConstraints.get() if attrName == "relaxDist": self._relaxDist.invoke() if not self._relaxDist.valid(): from chimera import UserError raise UserError('Invalid "relaxed" distance' ' value; must be non-negative number') return float(self._relaxDist.getvalue()) if attrName == "relaxAngle": self._relaxAngle.invoke() if not self._relaxAngle.valid(): from chimera import UserError raise UserError('Invalid "relaxed" angle' ' value; must be non-negative number') return float(self._relaxAngle.getvalue()) if attrName == "useRelaxColor": return self._useRelaxColor.get() if attrName == "relaxColor": return self._relaxColor.get() return Pmw.Group.__getattr__(self, attrName) def __setattr__(self, attrName, value): if attrName == "relaxConstraints": return self.__dict__['_relaxConstraints'].set(value) if attrName == "relaxDist": self.___dict__['relaxDist'].setvalue(str(value)) if attrName == "relaxAngle": self.___dict__['relaxAngle'].setvalue(str(value)) if attrName == "useRelaxColor": return self.___dict__['useRelaxColor'].set(value) if attrName == "relaxColor": return self.___dict__['relaxColor'].set(value) self.__dict__[attrName] = value
class CreatePlaneDialog(ModelessDialog): title = "Define Plane" help = "ContributedSoftware/structuremeas/structuremeas.html#define-plane" provideStatus = True statusPosition = "above" def fillInUI(self, parent): import Pmw, Tkinter row = 0 Tkinter.Label(parent, text="Create plane for selected atoms...").grid( row=row, columnspan=2) row += 1 from chimera.tkoptions import StringOption, BooleanOption self.nameOpt = StringOption(parent, row, "Plane name", "plane", None) row += 1 self.replaceExistingOpt = BooleanOption(parent, row, "Replace existing planes", False, None) row += 1 from chimera.tkoptions import ColorOption, FloatOption self.colorOpt = ColorOption(parent, row, "Color", None, None, balloon="Plane color. If No Color, then the plane" " will be colored to match the structure") row += 1 self.autoRadiusOpt = BooleanOption(parent, row, "Set disk size to enclose atom projections", True, self._radCB) row += 1 self.radRow = row self.radOffsetOpt = FloatOption(parent, row, "Extra radius" " (padding)", 0.0, None) self.radiusOpt = FloatOption(parent, row, "Fixed radius", 10.0, None) self.radiusOpt.forget() row += 1 self.thicknessOpt = FloatOption(parent, row, "Disk thickness", prefs[PLANE_THICKNESS], None) def Apply(self): from chimera import UserError if self.replaceExistingOpt.get(): planeManager.removePlanes(planeManager.planes) kw = { 'color': self.colorOpt.get(), 'thickness': self.thicknessOpt.get() } prefs[PLANE_THICKNESS] = kw['thickness'] if self.autoRadiusOpt.get(): kw['radiusOffset'] = self.radOffsetOpt.get() else: kw['radius'] = self.radiusOpt.get() replyobj.info("Creating plane\n") selAtoms = selection.currentAtoms() if len(selAtoms) < 3: self.enter() raise UserError("Need to select at least three" " atoms to define a plane") planeManager.createPlane(self.nameOpt.get().strip(), selAtoms, **kw) def _radCB(self, opt): if opt.get(): self.radiusOpt.forget() self.radOffsetOpt.manage() else: self.radOffsetOpt.forget() self.radiusOpt.manage()
def fillInUI(self, master): # Save ColorOption in instance. self.coloropt = ColorOption(master, 0, 'Backbone Color', None, self._setBackboneColor, balloon='Protein backbone color') self._updateBackboneColor()
class ColorWellDialog(ModelessDialog): title = 'Set Backbone Color' # Need to override '__init__' to initialize our extra state. def __init__(self, *args, **kw): # Whereas in the "Colors and Color Wells" example 'coloropt' # was a local variable, here the 'coloropt' variable is stored # in the instance because the trigger handler (which has access # to the instance) needs to update the color well contained in # the ColorOption. A new variable, 'handlerId', is created to # keep track of whether a handler is currently registered. The # handler is only created when needed. See 'map' and 'unmap' # below. (Note that the instance variables must be set before # calling the base __init__ method since the dialog may be mapped # during initialization, depending on which window system is used.) # # .. "Colors and Color Wells" Main_ColorWellUI.html self.colorOpt = None self.handlerId = None # Call the parent-class '__init__'. apply(ModelessDialog.__init__, (self,) + args, kw) def fillInUI(self, master): # Save ColorOption in instance. self.coloropt = ColorOption(master, 0, 'Backbone Color', None, self._setBackboneColor, balloon='Protein backbone color') self._updateBackboneColor() def _updateBackboneColor(self): for m in chimera.openModels.list(modelTypes=[chimera.Molecule]): for a in m.atoms: if ColorWellUI.MAINCHAIN.match(a.name): try: if a.color != theColor: self.coloropt.setMultiple() return except NameError: theColor = a.color try: self.coloropt.set(theColor) except NameError: self.coloropt.set(None) def _setBackboneColor(self, coloroption): ColorWellUI.mainchain(coloroption.get()) # Register a trigger handler to monitor changes in the # backbone atom list when we're make visible. We ignore # the event argument. def map(self, *ignore): # Synchronize with well color. self._updateBackboneColor() # If no handler is currently registered, register one. if self.handlerId is None: # Registration occurs when the 'chimera.triggers' object # is requested to add a handler. *Registration requires # three arguments*: # - the name of the trigger, # - the handler function to be invoked when the # trigger fires, and # - an additional argument to be passed to the handler # function when it is invoked. # In this case, the trigger name is the same as the name # of the class of objects being monitored, "Atom". # The handler function is '_handler', defined below. # And the additional argument is empty (None) -- it could # have been the ColorOption instance ('coloropt') but that # is accessible via the instance. The return value from # the registration is a unique handler identifier for # the handler/argument combination. This identifier is # required for deregistering the handler. # # *The handler function is always invoked by the trigger # with three arguments*: # - the name of the trigger, # - the additional argument passed in at registration # time, and # - an instance with three attributes # - created: set of created objects # - deleted: set of deleted objects # - modified: set of modified objects # Note that with a newly opened model, objects will just # appear in both the 'created' set and not in the 'modified' # set, even though the newly created objects will normally have # various of their default attributes modified by later # code sections. self.handlerId = chimera.triggers.addHandler('Atom', self._handler, None) # The '_handler' function is the trigger handler invoked when # attributes of 'Atom' instances change. def _handler(self, trigger, additional, atomChanges): # Check through modified atoms for backbone atoms. for a in atomChanges.modified: # If any of the changed atoms is a backbone atom, call # '_updateBackboneColor' to synchronize the well color # with backbone atom colors. if ColorWellUI.MAINCHAIN.match(a.name): self._updateBackboneColor() return # 'unmap' is called when the dialog disappears. We ignore the # event argument. def unmap(self, *ignore): # Check whether a handler is currently registered (*i.e.*, the # handler identifier, 'handlerId', is not 'None') and # deregister it if necessary. if self.handlerId is not None: # Deregistration requires two arguments: the name of the # trigger and the unique handler identifier returned by # the registration call. chimera.triggers.deleteHandler('Atom', self.handlerId) # Set the unique handler identifier to 'None' to indicate # that no handler is currently registered. self.handlerId = None
def fillInUI(self, parent): import Pmw, Tkinter row = 0 Tkinter.Label(parent, text="Create axis for...").grid(row=row, sticky='w') row += 1 self.modeVar = Tkinter.IntVar(parent) self.modeVar.set(self.MODE_HELICES) f = Tkinter.Frame(parent) f.grid(row=row, sticky='nsew') row += 1 Tkinter.Radiobutton(f, text="Each helix in:", command=self._helixCB, variable=self.modeVar, value=self.MODE_HELICES).grid(row=0, column=0) from chimera.widgets import MoleculeScrolledListBox self.molList = MoleculeScrolledListBox(f, listbox_selectmode='extended') self.molList.grid(row=0, column=1, sticky="nsew") parent.rowconfigure(1, weight=1) parent.columnconfigure(0, weight=1) f.rowconfigure(0, weight=1) f.columnconfigure(1, weight=1) f = Tkinter.Frame(parent) f.grid(row=row, sticky='w') row += 1 Tkinter.Radiobutton(f, text="Selected atoms (axis name:", command=self._selCB, variable=self.modeVar, value=self.MODE_SELECTION).grid(row=0, column=0) self.axisNameVar = Tkinter.StringVar(parent) self.axisNameVar.set("axis") Tkinter.Entry(f, textvariable=self.axisNameVar, width=10).grid(row=0, column=1) Tkinter.Label(f, text=")").grid(row=0, column=2) paramGroup = Pmw.Group(parent, tag_text="Axis Parameters") paramGroup.grid(row=row, column=0) row += 1 paramFrame = paramGroup.interior() prow = 0 butFrame = Tkinter.Frame(paramFrame) butFrame.grid(row=prow, column=0, columnspan=3) prow += 1 self.massWeighting = Tkinter.IntVar(parent) self.massWeighting.set(False) self._mwButton = Tkinter.Checkbutton(butFrame, command=self._mwCB, text="Mass weighting", variable=self.massWeighting) self._mwButton.grid(row=0, column=0, sticky='w') self._mwButton.grid_remove() self.helixCorrection = Tkinter.IntVar(parent) self.helixCorrection.set(True) Tkinter.Checkbutton(butFrame, text="Use helical correction", command=self._hcCB, variable=self.helixCorrection).grid(row=1, column=0, sticky='w') self.replaceExisting = Tkinter.IntVar(parent) self.replaceExisting.set(True) Tkinter.Checkbutton(butFrame, text="Replace existing axes", variable=self.replaceExisting).grid(row=2, column=0, sticky='w') f = Tkinter.Frame(paramFrame) f.grid(row=prow, column=0, columnspan=3) prow += 1 from chimera.tkoptions import ColorOption, FloatOption self.colorOpt = ColorOption( f, prow, "Color", None, None, balloon="Axis color. If No Color, then the axis" " will be colored to match the structure") Tkinter.Label(paramFrame, text="Radius:").grid(row=prow, column=0, rowspan=2) self.fixedRadiusVar = Tkinter.IntVar(parent) self.fixedRadiusVar.set(False) Tkinter.Radiobutton(paramFrame, variable=self.fixedRadiusVar, padx=0, value=False).grid(row=prow, column=1) Tkinter.Label(paramFrame, text="average axis-atom distance").grid(row=prow, column=2, sticky='w') Tkinter.Radiobutton(paramFrame, variable=self.fixedRadiusVar, padx=0, value=True).grid(row=prow + 1, column=1) f = Tkinter.Frame(paramFrame) f.grid(row=prow + 1, column=2, sticky='w') self.radiusOpt = FloatOption(f, 0, "angstroms", prefs[AXIS_RADIUS], None, min=0.01)
class CreateAxesDialog(ModelessDialog): title = "Define Axes" help = "ContributedSoftware/structuremeas/structuremeas.html#define-axes" provideStatus = True statusPosition = "above" MODE_HELICES, MODE_SELECTION = range(2) def fillInUI(self, parent): import Pmw, Tkinter row = 0 Tkinter.Label(parent, text="Create axis for...").grid(row=row, sticky='w') row += 1 self.modeVar = Tkinter.IntVar(parent) self.modeVar.set(self.MODE_HELICES) f = Tkinter.Frame(parent) f.grid(row=row, sticky='nsew') row += 1 Tkinter.Radiobutton(f, text="Each helix in:", command=self._helixCB, variable=self.modeVar, value=self.MODE_HELICES).grid(row=0, column=0) from chimera.widgets import MoleculeScrolledListBox self.molList = MoleculeScrolledListBox(f, listbox_selectmode='extended') self.molList.grid(row=0, column=1, sticky="nsew") parent.rowconfigure(1, weight=1) parent.columnconfigure(0, weight=1) f.rowconfigure(0, weight=1) f.columnconfigure(1, weight=1) f = Tkinter.Frame(parent) f.grid(row=row, sticky='w') row += 1 Tkinter.Radiobutton(f, text="Selected atoms (axis name:", command=self._selCB, variable=self.modeVar, value=self.MODE_SELECTION).grid(row=0, column=0) self.axisNameVar = Tkinter.StringVar(parent) self.axisNameVar.set("axis") Tkinter.Entry(f, textvariable=self.axisNameVar, width=10).grid(row=0, column=1) Tkinter.Label(f, text=")").grid(row=0, column=2) paramGroup = Pmw.Group(parent, tag_text="Axis Parameters") paramGroup.grid(row=row, column=0) row += 1 paramFrame = paramGroup.interior() prow = 0 butFrame = Tkinter.Frame(paramFrame) butFrame.grid(row=prow, column=0, columnspan=3) prow += 1 self.massWeighting = Tkinter.IntVar(parent) self.massWeighting.set(False) self._mwButton = Tkinter.Checkbutton(butFrame, command=self._mwCB, text="Mass weighting", variable=self.massWeighting) self._mwButton.grid(row=0, column=0, sticky='w') self._mwButton.grid_remove() self.helixCorrection = Tkinter.IntVar(parent) self.helixCorrection.set(True) Tkinter.Checkbutton(butFrame, text="Use helical correction", command=self._hcCB, variable=self.helixCorrection).grid(row=1, column=0, sticky='w') self.replaceExisting = Tkinter.IntVar(parent) self.replaceExisting.set(True) Tkinter.Checkbutton(butFrame, text="Replace existing axes", variable=self.replaceExisting).grid(row=2, column=0, sticky='w') f = Tkinter.Frame(paramFrame) f.grid(row=prow, column=0, columnspan=3) prow += 1 from chimera.tkoptions import ColorOption, FloatOption self.colorOpt = ColorOption( f, prow, "Color", None, None, balloon="Axis color. If No Color, then the axis" " will be colored to match the structure") Tkinter.Label(paramFrame, text="Radius:").grid(row=prow, column=0, rowspan=2) self.fixedRadiusVar = Tkinter.IntVar(parent) self.fixedRadiusVar.set(False) Tkinter.Radiobutton(paramFrame, variable=self.fixedRadiusVar, padx=0, value=False).grid(row=prow, column=1) Tkinter.Label(paramFrame, text="average axis-atom distance").grid(row=prow, column=2, sticky='w') Tkinter.Radiobutton(paramFrame, variable=self.fixedRadiusVar, padx=0, value=True).grid(row=prow + 1, column=1) f = Tkinter.Frame(paramFrame) f.grid(row=prow + 1, column=2, sticky='w') self.radiusOpt = FloatOption(f, 0, "angstroms", prefs[AXIS_RADIUS], None, min=0.01) def Apply(self): from chimera import UserError if self.replaceExisting.get(): axisManager.removeAxes(axisManager.axes) kw = {} kw['color'] = self.colorOpt.get() if self.fixedRadiusVar.get(): kw['radius'] = prefs[AXIS_RADIUS] = self.radiusOpt.get() kw['massWeighting'] = self.massWeighting.get() \ and self.modeVar.get() == self.MODE_SELECTION kw['helicalCorrection'] = self.helixCorrection.get() \ and not kw['massWeighting'] if kw['helicalCorrection']: replyobj.info("Creating axes with helical correction\n") elif kw['massWeighting']: replyobj.info("Creating axes with mass weighting\n") else: replyobj.info("Creating axes\n") if self.modeVar.get() == self.MODE_HELICES: mols = self.molList.getvalue() if not mols: self.enter() raise UserError("No molecules chosen") created = 0 for m in mols: createHelices(m, **kw) else: selAtoms = selection.currentAtoms() if len(selAtoms) < 3: self.enter() raise UserError("Need to select at least three" " atoms to define an axis") axisManager.createAxis(self.axisNameVar.get().strip(), selAtoms, **kw) def _helixCB(self): self._mwButton.grid_remove() def _hcCB(self): if self.helixCorrection.get() and self.massWeighting.get(): self.massWeighting.set(False) def _mwCB(self): if self.massWeighting.get() and self.helixCorrection.get(): self.helixCorrection.set(False) def _selCB(self): self._mwButton.grid()
def fillInUI(self, parent): # inter/intra-model; slop; colors; models; replace current; # label # for removing labels in subsequent passes... # (use a selection so I don't have to track model closures) self.labelSelection = ItemizedSelection() self.labelMap = {} self.callbacks = [] row = 0 cols = 3 self.bondColorOption = ColorOption(parent, row, 'H-bond color', prefs[BOND_COLOR], None, noneOkay=0) class HBLineWidthOption(LineWidthOption): name = "Line width" balloon = "Width of pseudobonds (in pixels)" default = prefs[LINE_WIDTH] self.lineWidth = HBLineWidthOption(parent, row+1, None, None, None, width=4, sticky='w') self.findMode = Pmw.RadioSelect(parent, buttontype='radiobutton', labelpos='n', pady=0, orient='vertical', label_text='Find these bonds:', hull_borderwidth=2, hull_relief='ridge') self.findMode.add('inter-model') self.findMode.add('intra-model') self.findMode.add('both') self.findMode.invoke('both') self.findMode.grid(row=row, column=2, rowspan=2) row += 2 self.relaxParams = RelaxParams(parent, prefs[RELAX_COLOR]) self.relaxParams.grid(row=row, columnspan=cols, sticky='nsew', padx=2) row += 1 self.restrictModels = Tkinter.IntVar(parent) self.restrictModels.set(0) self.modelFrame = Tkinter.Frame(parent) self.molTexts = ["Restrict to models...", "Restrict to models:"] self.restrictCheckBox = Tkinter.Checkbutton(self.modelFrame, variable=self.restrictModels, text=self.molTexts[0], command=self._restrictModelsCB) self.restrictCheckBox.grid(row=0, column=0) from chimera.widgets import MoleculeScrolledListBox self.molList = MoleculeScrolledListBox(self.modelFrame, listbox_selectmode="extended") self.modelFrame.rowconfigure(0, weight=1) self.modelFrame.grid(row=row, column=0, columnspan=cols, sticky="nsw") parent.rowconfigure(row, weight=1) row += 1 self.inSelection = Tkinter.IntVar(parent) self.inSelection.set(0) f = Tkinter.Frame(parent) f.grid(row=row, column=0, columnspan=cols, sticky="w") Tkinter.Checkbutton(f, variable=self.inSelection, text="Only find H-bonds with", command=self._useSelChange).grid( row=0, column=0, sticky="e") self.selType = Pmw.OptionMenu(f, items=["at least one end", "exactly one end", "both ends"], initialitem=0, menubutton_state="disabled", labelpos="e", label_text="selected") self.selType.grid(row=0, column=1, sticky="w") row += 1 self.revealEnds = Tkinter.IntVar(parent) self.revealEnds.set(0) Tkinter.Checkbutton(parent, variable=self.revealEnds, text="If endpoint atom hidden, show endpoint residue" ).grid(row=row, column=0, columnspan=cols, sticky="w") row += 1 self.retainCurrent = Tkinter.IntVar(parent) self.retainCurrent.set(0) Tkinter.Checkbutton(parent, variable=self.retainCurrent, text="Retain currently displayed H-bonds").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 self.interSubmodel = Tkinter.IntVar(parent) self.interSubmodel.set(0) # comment out the below since there seems to be no # situations where cross-submodel-same-model hbonds # are interesting. If reading pdbrun files occurs, this # may change. #Tkinter.Checkbutton(parent, variable=self.interSubmodel, # text="Find H-bonds between submodels\n" # "having same principal model number" # ).grid(row=row, column=0, columnspan=cols, sticky="w") #row += 1 self.writeFile = Tkinter.IntVar(parent) self.writeFile.set(0) Tkinter.Checkbutton(parent, variable=self.writeFile, text="Write information to file").grid(row=row, column=0, columnspan=cols, sticky="w") self.fileName = None row += 1 self.writeLog = Tkinter.IntVar(parent) self.writeLog.set(0) Tkinter.Checkbutton(parent, variable=self.writeLog, text="Write information to reply log").grid(row=row, column=0, columnspan=cols, sticky="w") row += 1
class HBDialog(ModelessDialog): title = "H-Bond Parameters" buttons = ("OK", "Apply", "Close") default = 'OK' help = "ContributedSoftware/findhbond/findhbond.html" def fillInUI(self, parent): # inter/intra-model; slop; colors; models; replace current; # label # for removing labels in subsequent passes... # (use a selection so I don't have to track model closures) self.labelSelection = ItemizedSelection() self.labelMap = {} self.callbacks = [] row = 0 cols = 3 self.bondColorOption = ColorOption(parent, row, 'H-bond color', prefs[BOND_COLOR], None, noneOkay=0) class HBLineWidthOption(LineWidthOption): name = "Line width" balloon = "Width of pseudobonds (in pixels)" default = prefs[LINE_WIDTH] self.lineWidth = HBLineWidthOption(parent, row+1, None, None, None, width=4, sticky='w') self.findMode = Pmw.RadioSelect(parent, buttontype='radiobutton', labelpos='n', pady=0, orient='vertical', label_text='Find these bonds:', hull_borderwidth=2, hull_relief='ridge') self.findMode.add('inter-model') self.findMode.add('intra-model') self.findMode.add('both') self.findMode.invoke('both') self.findMode.grid(row=row, column=2, rowspan=2) row += 2 self.relaxParams = RelaxParams(parent, prefs[RELAX_COLOR]) self.relaxParams.grid(row=row, columnspan=cols, sticky='nsew', padx=2) row += 1 self.restrictModels = Tkinter.IntVar(parent) self.restrictModels.set(0) self.modelFrame = Tkinter.Frame(parent) self.molTexts = ["Restrict to models...", "Restrict to models:"] self.restrictCheckBox = Tkinter.Checkbutton(self.modelFrame, variable=self.restrictModels, text=self.molTexts[0], command=self._restrictModelsCB) self.restrictCheckBox.grid(row=0, column=0) from chimera.widgets import MoleculeScrolledListBox self.molList = MoleculeScrolledListBox(self.modelFrame, listbox_selectmode="extended") self.modelFrame.rowconfigure(0, weight=1) self.modelFrame.grid(row=row, column=0, columnspan=cols, sticky="nsw") parent.rowconfigure(row, weight=1) row += 1 self.inSelection = Tkinter.IntVar(parent) self.inSelection.set(0) f = Tkinter.Frame(parent) f.grid(row=row, column=0, columnspan=cols, sticky="w") Tkinter.Checkbutton(f, variable=self.inSelection, text="Only find H-bonds with", command=self._useSelChange).grid( row=0, column=0, sticky="e") self.selType = Pmw.OptionMenu(f, items=["at least one end", "exactly one end", "both ends"], initialitem=0, menubutton_state="disabled", labelpos="e", label_text="selected") self.selType.grid(row=0, column=1, sticky="w") row += 1 self.revealEnds = Tkinter.IntVar(parent) self.revealEnds.set(0) Tkinter.Checkbutton(parent, variable=self.revealEnds, text="If endpoint atom hidden, show endpoint residue" ).grid(row=row, column=0, columnspan=cols, sticky="w") row += 1 self.retainCurrent = Tkinter.IntVar(parent) self.retainCurrent.set(0) Tkinter.Checkbutton(parent, variable=self.retainCurrent, text="Retain currently displayed H-bonds").grid( row=row, column=0, columnspan=cols, sticky="w") row += 1 self.interSubmodel = Tkinter.IntVar(parent) self.interSubmodel.set(0) # comment out the below since there seems to be no # situations where cross-submodel-same-model hbonds # are interesting. If reading pdbrun files occurs, this # may change. #Tkinter.Checkbutton(parent, variable=self.interSubmodel, # text="Find H-bonds between submodels\n" # "having same principal model number" # ).grid(row=row, column=0, columnspan=cols, sticky="w") #row += 1 self.writeFile = Tkinter.IntVar(parent) self.writeFile.set(0) Tkinter.Checkbutton(parent, variable=self.writeFile, text="Write information to file").grid(row=row, column=0, columnspan=cols, sticky="w") self.fileName = None row += 1 self.writeLog = Tkinter.IntVar(parent) self.writeLog.set(0) Tkinter.Checkbutton(parent, variable=self.writeLog, text="Write information to reply log").grid(row=row, column=0, columnspan=cols, sticky="w") row += 1 def addCallback(self, callback): self.callbacks.append(callback) def Apply(self): states = {} for but in self.buttonWidgets.values(): states[but] = but.cget('state') but.config(state='disabled') try: self._Apply() finally: for but, state in states.items(): but.config(state=state) for cb in self.callbacks: try: cb() except: replyobj.reportException( "H-bond callback function") self.callbacks = [] def _Apply(self): intramodel = intermodel = 1 cursel = self.findMode.getcurselection() if cursel == 'inter-model': intramodel = 0 elif cursel == 'intra-model': intermodel = 0 distSlop = 0.0 angleSlop = 0.0 twoColors = False relax = self.relaxParams.relaxConstraints rc = self.relaxParams.relaxColor if relax: distSlop = self.relaxParams.relaxDist angleSlop = self.relaxParams.relaxAngle if self.relaxParams.useRelaxColor: twoColors = True prefs[RELAX_COLOR] = rc.rgba if self.inSelection.get(): selRestrict = ["any", "cross", "both"][ self.selType.index(Pmw.SELECT)] else: selRestrict = None lineWidth = self.lineWidth.get() prefs[LINE_WIDTH] = lineWidth bc = self.bondColorOption.get() prefs[BOND_COLOR] = bc.rgba if self.writeFile.get(): saveFile = '-' else: saveFile = None if self.restrictModels.get(): models = self.molList.getvalue() if not models: raise ValueError, "No restriction models chosen" else: models = None from base import createHBonds createHBonds(models=models, intramodel=intramodel, intermodel=intermodel, relax=relax, distSlop=distSlop, angleSlop=angleSlop, twoColors=twoColors, selRestrict=selRestrict, lineWidth=lineWidth, saveFile=saveFile, log=self.writeLog.get(), retainCurrent=self.retainCurrent.get(), reveal=self.revealEnds.get(), color=bc, slopColor=rc) def Close(self): self.callbacks = [] ModelessDialog.Close(self) def _restrictModelsCB(self): restrict = self.restrictModels.get() self.restrictCheckBox.config(text=self.molTexts[restrict]) if restrict: self.molList.grid(row=0, column=1, sticky="ns") else: self.molList.grid_forget() def _useSelChange(self): if self.inSelection.get(): self.selType.component("menubutton").config( state="normal") else: self.selType.component("menubutton").config( state="disabled")
class RelaxParams(Pmw.Group): def __init__(self, parent, relaxColor, colorOptions=True): self._relaxConstraints = Tkinter.IntVar(parent) self._relaxConstraints.set(True) Pmw.Group.__init__(self, parent, ring_relief='ridge', tag_pyclass=Tkinter.Checkbutton, tag_text='Relax H-bond constraints', tag_variable=self._relaxConstraints) self._relaxLabel = Tkinter.Label(self.interior(), text="Relax constraints by: ") self._relaxLabel.grid(row=0, column=0, rowspan=2, sticky='e') self._relaxDist = Pmw.EntryField(self.interior(), labelpos='e', label_text='angstroms', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recDistSlop), entry_width=5) self._relaxDist.grid(row=0, column=1, sticky='w') self._relaxAngle = Pmw.EntryField(self.interior(), labelpos='e', label_text='degrees', validate={ 'validator': 'real', 'min': 0.0 }, value=str(recAngleSlop), entry_width=5) self._relaxAngle.grid(row=1, column=1, sticky='w') if not colorOptions: return self._useRelaxColor = Tkinter.IntVar(parent) self._useRelaxColor.set(0) f = Tkinter.Frame(self.interior()) f.grid(row=2, column=0, columnspan=2) Tkinter.Checkbutton(f, text="Color H-bonds not meeting " "precise criteria differently:", variable=self._useRelaxColor).grid(row=0, column=0, sticky='e') self._relaxColor = ColorOption(f, 0, "", relaxColor, None, startCol=1, noneOkay=0) def enable(self): self.configure(tag_state=Tkinter.NORMAL) self._relaxLabel.config(state=Tkinter.NORMAL) #self._relaxDist.config(entry_state=Tkinter.NORMAL, # label_state=Tkinter.NORMAL) #self._relaxAngle.config(entry_state=Tkinter.NORMAL, # label_state=Tkinter.NORMAL) # not sure why the above doesn't work, so: for w in (self._relaxDist, self._relaxAngle): for c in ('entry', 'label'): wc = w.component(c) wc.config(state=Tkinter.NORMAL) # TODO: color def disable(self): self.configure(tag_state=Tkinter.DISABLED) self._relaxLabel.config(state=Tkinter.DISABLED) #self._relaxDist.config(entry_state=Tkinter.DISABLED, # label_state=Tkinter.DISABLED) #self._relaxAngle.config(entry_state=Tkinter.DISABLED, # label_state=Tkinter.DISABLED) # not sure why the above doesn't work, so: for w in (self._relaxDist, self._relaxAngle): for c in ('entry', 'label'): wc = w.component(c) wc.config(state=Tkinter.DISABLED) # TODO: color def __getattr__(self, attrName): if attrName == "relaxConstraints": return self._relaxConstraints.get() if attrName == "relaxDist": self._relaxDist.invoke() if not self._relaxDist.valid(): from chimera import UserError raise UserError('Invalid "relaxed" distance' ' value; must be non-negative number') return float(self._relaxDist.getvalue()) if attrName == "relaxAngle": self._relaxAngle.invoke() if not self._relaxAngle.valid(): from chimera import UserError raise UserError('Invalid "relaxed" angle' ' value; must be non-negative number') return float(self._relaxAngle.getvalue()) if attrName == "useRelaxColor": return self._useRelaxColor.get() if attrName == "relaxColor": return self._relaxColor.get() return Pmw.Group.__getattr__(self, attrName) def __setattr__(self, attrName, value): if attrName == "relaxConstraints": return self.__dict__['_relaxConstraints'].set(value) if attrName == "relaxDist": self.___dict__['relaxDist'].setvalue(str(value)) if attrName == "relaxAngle": self.___dict__['relaxAngle'].setvalue(str(value)) if attrName == "useRelaxColor": return self.___dict__['useRelaxColor'].set(value) if attrName == "relaxColor": return self.___dict__['relaxColor'].set(value) self.__dict__[attrName] = value