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()
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