#! /usr/bin/python import os import sys import string from molecule import * from AtomSel import AtomSel from Tkinter import * import VMDCallback import VMDMenu import molecule import molrep copyright = '\ ResWin: An add on python script for VMD (Visual Molecular Dynamics)\n\ Authors: V. Bhagwat, R. Schneider, J. Vincent, B. Lee\n\n\ This work is the property of the U.S. Government.\n\n\ The ResWin program and documentation may not be sold or incorporated\n\ into a commercial product, in whole or in part, without the written\n\ consent of the authors.\n\n\ For further information please contact:\n\ James Vincent jjv5@nih.gov\n\ B. K. Lee bklee@helix.nih.gov' def about(): aboutwin=VMDMenu.VMDMenu() aboutwin.title('The Creators') Label(aboutwin, text=copyright).pack(side=LEFT) #Label(aboutwin, text=' This vicious script was created by the two marvelous programming\n gurus Vineet Bhagwat and Robert Schneider at the NIH (Building 37, NCI) in \n Bethesda, Maryland during their summer job of 2001.\n They will be graduating from Paint Branch High School in\n Burtonsville, Maryland in the spring of 2002.').pack(side=LEFT) ##def callback(): ## print "called the callback!" ## a = residentry.get() ## b = chainentry.get() ## print a,b class Command: def __init__(self, func, *args, **kw): self.func=func self.args=args self.kw=kw def __call__(self, *args, **kw): args=self.args+args kw.update(self.kw) apply(self.func, args, kw) class MolChange: def __init__ (self): self.root = VMDMenu.VMDMenu() self.root.protocol ("WM_DELETE_WINDOW", self.__del__()) #self.my_master_rep_list = [] self.my_object_list = [] self.my_mol_list=molecule.listall() for count in range (len (self.my_mol_list)): self.my_object_list.append (ResClass (molid = self.my_mol_list[count])) VMDCallback.add_callback ('initialize_structure', self.change, self) main (self.root, self.my_object_list) def change (self, args): if (args [1] == 1): print 'you just loaded molecule number: ', args[0] elif (args [1] == 0): print 'you just deleted molecule number: ', args [0] self.update(args[0], args [1]) self.root.destroy() self.recreate() def update (self, molid, action): #action = 0 if a molecule just deleted #action = 1 if a molecule just added #molid is the id of the molecule just added or deleted print molid,action if (action == 0): count = 0 deleted = 0 #false while not deleted: #count in range (len (self.my_object_list)): print 'count = ', count, 'objlist[count].molid = ', self.my_object_list[count].my_molid, 'molid = ', molid if (self.my_object_list[count].my_molid == molid): del self.my_object_list[count] deleted = 1 count += 1 if (action == 1): print 'Action =',action self.my_object_list.append (ResClass (molid = molid)) def recreate (self): self.root = VMDMenu.VMDMenu() print 'Called recreate' main (self.root, self.my_object_list) def __del__(self): try: VMDCallback.del_callback ('initialize_structure', self.change, self) except: pass class RepColorClass: def __init__(self,color): self.color = color def set(self,color): self.color = color def get(self): return self.color class ResClass: def __init__ (self, molid = 0): self.my_molid = molid self.my_convert_dict = {'GLY': 'G', 'ALA': 'A', 'VAL': 'V', 'LEU': 'L', 'ILE': 'I', 'SER': 'S', 'CYS': 'C', 'THR': 'T', 'MET': 'M', 'PHE': 'F', 'TYR': 'Y', 'TRP': 'W', 'HIS': 'H', 'LYS': 'K', 'ARG': 'R', 'ASP': 'D', 'GLU': 'E', 'ASN': 'N', 'GLN': 'Q', 'PRO': 'P', 'ACE': ' ', 'CBX': ' ', 'LYR': ' '} self.my_oneletter_list = [] self.my_resid_list = [] self.my_resname_list = [] self.my_chain_list = [] self.my_selchain_list = [] self.my_selresid_list = [] self.start = 0 self.stop = 0 #self.my_selected_text = '' #self.my_selected_list = [] self.my_rep_list = [] self.my_repstr_list = [] self.my_atoms = [] self.ranges=[] self.my_name = '' self.seltext='' self.start_line = '' self.start_col = '' self.end_line = '' self.end_col = '' self.numlines = '' self.color_tags=[0.0,0.0] self.set() def set (self): self.my_atoms = AtomSel ('name CA', self.my_molid) self.my_resid_list = self.my_atoms.get ('resid') self.my_resname_list = self.my_atoms.get ('resname') self.my_chain_list = self.my_atoms.get ('chain') self.my_name = molecule.structure_file(self.my_molid) self.convert_name() self.oneletter_convert () def oneletter_convert (self): try: for count in self.my_resname_list: self.my_oneletter_list.append (self.my_convert_dict [count]) except KeyError: print '\n\nYour .pdb file contains an error!', count, 'is not a valid three letter residue code!\n\n' def convert_name(self): buff = '' for a in self.my_name: if (a == '/') or (a == '\\'): buff = '' else: buff += a self.my_name = buff def highlight (self, sty = "Tube 0.6 8", col = '4' ): print 'Entered Highlight' counter = 0 current_chain = self.my_selchain_list [counter] prev_chain = self.my_selchain_list [counter] repstr = '(chain ' + current_chain + ' and resid ' for x in range(self.start, self.stop): print 'x = ', x, 'counter = ', counter, 'current_chain = ', current_chain, 'prev_chain = ', prev_chain if current_chain == prev_chain: repstr += str(self.my_selresid_list[counter]) + ' ' print 'repstr = ', repstr else: repstr += ') or (chain ' + current_chain + ' and resid ' + str(self.my_selresid_list[counter]) + ' ' print 'repstr = ', repstr counter += 1 print 'counter = ', counter, 'len(self.my_chain_list) = ', len(self.my_selchain_list) if not (counter >= len (self.my_selchain_list)): current_chain = self.my_selchain_list [counter] prev_chain = self.my_selchain_list [counter-1] repstr += ')' print 'repstr = ', repstr col = "ColorID " + col counter = 0 changed = 0 #FALSE while (not changed) and (counter < len (self.my_rep_list)): current_sel = molrep.get_selection(self.my_molid, self.my_rep_list[counter]) current_color = molrep.get_color(self.my_molid, self.my_rep_list[counter]) current_style = molrep.get_style(self.my_molid, self.my_rep_list[counter]) if (repstr == current_sel) and (sty == current_style) and (col == current_color): changed = 1 #TRUE print 'you have selected the same thing again.....' elif (repstr == current_sel) and (sty == current_style) and (col != current_color): molrep.modrep (self.my_molid, self.my_rep_list[counter], color = col) changed = 2 #TRUE print 'we changed the color for you in the same representation id....' counter += 1 if (not changed): numrep = molrep.num (self.my_molid) molrep.addrep (self.my_molid) molrep.modrep (self.my_molid, numrep, style = sty, sel = repstr, color = col) self.my_repstr_list.append(repstr) self.my_rep_list.append (numrep) self.my_selresid_list = [] self.my_selchain_list = [] else: print '\nno new representation was added.....\n' def draw (self, start, stop, style = "Tube 0.5 8", color = '4'): print 'Entered Draw' self.my_selchain_list = self.my_chain_list [start : stop] self.my_selresid_list = self.my_resid_list [start : stop] self.start = start self.stop = stop self.highlight (sty = style, col = color) def clear(self): self.my_rep_list.sort() self.my_rep_list.reverse() del_list = [] numrep = molrep.num(self.my_molid) for counter in range(numrep): current_sel = molrep.get_selection(self.my_molid, counter) for a in self.my_repstr_list: if current_sel == a: del_list.append(counter) del_list.reverse() for counter in del_list: molrep.delrep(self.my_molid, counter) self.my_repstr_list = [] self.my_rep_list = [] self.my_selresid_list = [] self.my_selchain_list = [] def output_str (self): line = '' for counter in self.my_oneletter_list: line += counter line += '\n' return line def color(self,start,stop,text): print 'Entered Color\n*************' text.tag_add('colored',start,stop) print 'Tag Added at',start,stop self.color_tags[0] = start self.color_tags[1] = stop print 'self.color_tags ==',self.color_tags print ' Ended Color\n*************' ##------------------------------------------------------------------------------------- ##********************************************************************************** ## END OF CLASS ##*********************************************************************************** ##----------------------------------------------------------------------------------------- def view_info (value, textbox): #value is of ResClass print def adddecimal(dchar): #ADD A DECIMAL AT THE BEGINNING OF dchar temp = '.' for a in range(len(dchar)): temp+=dchar[a] return temp def deldecimal(dchar): temp = '' for a in range(len(dchar)): if (dchar[a]!='.'): temp+=dchar[a] return temp def takedecimal(fchar, keep = 1): #Returns the decimal point with the number if keep is 1, else no decimal returned #print 'Entered TakeDecimal' temp = '' for a in range(len(fchar)): if fchar[a] == '.': temp = '' else: if temp == '' and keep==1: temp = '.' temp += fchar[a] return temp def takeint(ichar): #print 'Entered TakeInt' temp = '' go = 1 for a in range(len(ichar)): if ichar[a] == '.': go = 0 if go == 1: temp += ichar[a] return temp def clear_all(object_list,text): del_selections(object_list,text) for x in object_list: x.clear() ##extract_text(Text Widget, List Of Original Text On The Line, Integer Line Number, List Of Start And End Ranges)- ## Returns the true start and end values of the nonspace text in the highlighted region of the text box. ##Returns the original start value as both the start and end values of the list if there are no nonspace characters. def extract_text(text,original,line,val): print 'Entered Extract_Text' print 'On entry, val ==',val ### Convert original list to a string temp = '' for a in range(len(original)): temp+=original[a] original = temp print 'The original string ==',original current = text.get(str(line) + '.0',END) print 'The current string ==',current selected = text.get(val[0],val[1]) print 'The selected string ==',selected num_spaces_before = 0 num_nonspaces_in = 0 ### Find the number of dashes before the highlighted selection. for a in range(int(takedecimal(val[0],0))): print 'if text.get(',(str(line)+'.'+str(a)),',',(str(line)+'.'+str(a+1)),') == -:' print '(',text.get(str(line)+'.'+str(a)),',',(str(line)+'.'+str(a+1)),')' if text.get((str(line)+'.'+str(a)), (str(line)+'.'+str(a+1))) == '-': num_spaces_before+=1 print 'The number of spaces before the selection ==',num_spaces_before ### Delete all dashes from the selected string. temp = '' for a in range(len(selected)): if selected[a] != '-': temp+=selected[a] selected = temp ## ### Find the number of dashes in the highlighted selection. ## print 'for a in range(',int(takedecimal(val[0],0)),int(takedecimal(val[1],0)),'do:' ## for a in range(int(takedecimal(val[0],0)),int(takedecimal(val[1],0))): ## print 'if',(text.get(str(line+1)+'.'+str(a),str(line+1)+'.'+str(a+1))),'!= -' ## print '(',text.get(str(line+1)+'.'+str(a)),',',(str(line+1)+'.'+str(a+1)),')' ## if text.get(str(line+1)+'.'+str(a),str(line+1)+'.'+str(a+1)) != '-': ## num_nonspaces_in+=1 ## print 'The number of nonspaces in the selection ==',num_nonspaces_in if len(selected) > 0: val[0] = takeint(val[0]) + '.' + str(int(takedecimal(val[0],0))-num_spaces_before) val[1] = takeint(val[0]) + '.' + str(int(takedecimal(val[0],0)) + len(selected)) else: print 'Line',line+1,'is all dashes.' val[1] = val[0] print 'Returning val ==',val if val[0] != val[1]: print 'Selected string is now ==',text.get((takeint(val[0]) + '.' + str( int( takedecimal(val[0],0)) + num_spaces_before)), (takeint(val[1]) + '.' + str( int( takedecimal(val[1],0)) + num_spaces_before))) else: print 'Val[0] == Val[1]' print 'Exited Extract_Text' return val, num_spaces_before ##is_all_space(String)- ## Returns 1 (TRUE) if the string is made up of only dashes. ##Otherwise it returns 0 (FALSE) if there is atleast one nondash. def is_all_space(selection): temp = 1 for a in range(len(selection)): if selection[a] != '-': temp = 0 return temp ##create(Text Widget, Object_List Of ResClass, Character Value Of Radius, Character Value Of Representation Color)- ## This find which part of each line needs to be highlighted in the text widget and which needs to be highlighted in ##the graphics window in VMD. def create (text, object_list, radius, RepresentationColor): ##Algorithm: ##Figure how many lines were selected. (Store to numlines) ##For each line- ## Highlight entire selected string in text widget. ## Store highlighted coloring ranges in class. ## Find nondash part. ## Highlight nondash part in VMD graphics window. print 'Entered Create' ranges=text.tag_ranges(SEL) print 'Ranges:',ranges #(takeint(ranges[0]) != takeint(ranges[1])) or (takedecimal(ranges[0],0) != takedecimal(ranges[1],0)) spaces_before = 0 if (len(ranges)==0): print else: print '(takeint(ranges[0]) != takeint(ranges[1])) and (takedecimal(ranges[0],0) != takedecimal(ranges[1],0))' color = RepresentationColor.get() #seltext='' val=['',''] #local_ranges=[] #r=text.tag_ranges(SEL) #print r start_line = takeint(ranges[0]) start_col = takedecimal(ranges[0],0) end_line = takeint(ranges[1]) end_col = takedecimal(ranges[1],0) numlines = (int(end_line) - int(start_line)) + 1 ## ==== SELECTION CHECKING ==== ## 0123456789 ## ABCDEFGHIJ ## Assume: 01234[6789 ## User selects from 5 to C. AB]DEFGHIJ ## Interpretation: 012[4]6789 ## User selected from 3 to E. ABC[E]GHIJ ## [ denotes start of highlighting. ## ] denotes end of highlighting. if int(start_col) >= int(end_col): print 'ENTERED ERROR CHECKING' r=['',''] print start_col,'(start_col) >',end_col,'(end_col)' val[0]= str(int(string.atof(ranges[0]))) + '.' + str(int(takedecimal(ranges[1],0)) - 0) val[1]= str(int(string.atof(ranges[1]))) + '.' + str(int(takedecimal(ranges[0],0)) + 1) r=val print 'Ranges[0]:',ranges[0],'Ranges[1]:',ranges[1],'Val[0]:',val[0],'Val[1]:',val[1] start_line = takeint(r[0]) print 'Start_line:',start_line start_col = takedecimal(r[0]) print 'Start_col:',start_col end_line = takeint(r[1]) print 'End_line:',end_line end_col = takedecimal(r[1]) print 'End_col:',end_col numlines = (string.atoi(end_line) - string.atoi(start_line)) + 1 print 'EXITED ERROR CHECKING' # ==== END SELECTION CHECKING ==== print 'StartLine =',start_line,'StartColumn =',start_col,'EndLine =',end_line,'EndCol =',end_col,'NumberOfLines =',numlines for counter in range(int(start_line),int(start_line)+numlines): # ==== TEXT SELECTION COLORING ==== print 'ENTERED TEXT SELECTION COLORING PART OF CREATE FUNCTION' object_list[counter-1].color(str(counter)+'.'+start_col,str(counter)+'.'+end_col,text) print 'Call color from object_list[',counter-1,'(counter)]. Send',start_col,'(start_col) and',end_col,'(end_col).' print 'ENDED TEXT SELECTION COLORING PART OF CREATE FUNCTION' # == END TEXT SELECTION COLORING == ranges=[] val=['',''] val[0] = ( str( counter )) + '.' + start_col print 'Val[0] =',val[0] val[1] = ( str( counter )) + '.' + end_col print 'Val[1] =',val[1] val,spaces_before = extract_text(text,object_list[counter-1].my_oneletter_list,counter,val) if val[0] != val[1]: object_list[counter-1].draw(int(takedecimal(val[0],0)),int(takedecimal(val[1],0)),style='Tube ' + radius + ' 8',color = color) seltext = str( text.get( takeint(val[0]) + '.' + str( int( takedecimal(val[0],0)) + spaces_before), takeint(val[1]) + '.' + str( int( takedecimal(val[1],0)) + spaces_before))) print 'This line consists of',seltext else: val=['',''] print val ### ## else: ## seltext = str(text.get(r[0],r[1])) ## val = ['',''] ## val = [r[0],r[1]] ## coloring_ranges.append(val) ## val = extract_text(text,object_list[int(takeint(r[0]))-1].my_oneletter_list,int(takeint(r[0]))-1,val) ## ranges.append(val) ## print seltext ## #DRAW WHAT WAS SELECTED ## alength = len(ranges) ## dec_ranges = [] ## val = [0,0] ## for a in range(alength): ## val[0] = int(takedecimal(ranges[a][0],0)) ## val[1] = int(takedecimal(ranges[a][1],0)) ## dec_ranges.append(val) ## print dec_ranges ## counter = -1 ## for a in range(int(takeint(ranges[0][0]))-1,int(takeint(ranges[len(ranges)-1][1]))): ## counter += 1 ## object_list[a].draw(dec_ranges[counter][0],dec_ranges[counter][1],style='Tube ' + radius + ' 8',color = color) def create_w_event(text, object_list, radius, RepresentationColor, event): create(text, object_list, radius, RepresentationColor) def view_information (text): infowin=VMDMenu.VMDMenu() infowin.title('Information Window') ## START ERROR MESSAGE t=Text(infowin) t.insert(END,'This function has not been implemented') t.pack(side=LEFT) ## END ERROR MESSAGE ## t=Text(infowin) ## t.grid(row=0,column=0,sticky='nesw') ## scroll=Scrollbar(infowin,command=t.yview) ## scroll.grid(row=0,column=1,sticky='nesw') ## t.configure(yscrollcommand=scroll.set) ## t.tag_configure('norm',font=('Verdana',16),wrap=NONE) ## for x in selection: ## t.insert(END, 'Selection=' + `x` + ' Resid=' + `resid_list[x-1]` + ' Chain=' + `chain_list[x-1]` + ' Resname=' + `resname_list[x-1]` + '\n', 'norm') ## #Menu Bar ## menubar = Menu(infowin) ## filemenu = Menu(menubar, tearoff=0) ## filemenu.add_command(label="Exit", command=infowin.destroy) ## menubar.add_cascade(label="File", menu=filemenu) ## # display the menu ## infowin.config(menu=menubar) def del_selections(object_list,text): print 'Entered DelSelections' for a in range(len(object_list)): print 'For',a,'(a) in range',len(object_list),'(len(object_list))' if object_list[a].color_tags != [0.0,0.0]: print 'Object_list[a].color_tags != [0.0,0.0], object_list[a].color_tags ==',object_list[a].color_tags text.tag_delete('colored',object_list[a].color_tags[0],object_list[a].color_tags[1]) object_list[a].color_tags = [0.0,0.0] print 'Deleted Tag' text.tag_configure('colored', font=('Courier', 16), wrap = NONE, background='yellow') print 'Created the colored tag for the text box.' print 'Ended DelSelections' def del_selections_w_event(object_list,text,event): del_selections(object_list,text) def delete1(text,object_list,counter): delindx = takeint(object_list[counter].color_tags[0]) + '.' + str(int(takedecimal(object_list[counter].color_tags[0],0)) - 1) if text.get(delindx,object_list[counter].color_tags[0]) == '-': text.delete(delindx,object_list[counter].color_tags[0]) object_list[counter].color_tags[0] = takeint(object_list[counter].color_tags[0]) + '.' + str(int(takedecimal(object_list[counter].color_tags[0],0))-1) object_list[counter].color_tags[1] = takeint(object_list[counter].color_tags[1]) + '.' + str(int(takedecimal(object_list[counter].color_tags[1],0))-1) def prep_delete1(text,object_list,event): text.config(state=NORMAL) for a in range(len(object_list)): if object_list[a].color_tags != [0.0,0.0]: delete1(text,object_list,a) text.config(state=DISABLED) def enter_dashes(object_list,text): print 'Entered Enter_Dashes\n********************' text.config(state=NORMAL) for a in range(len(object_list)): print 'For',a,'(a) in range(',len(object_list),') (len(object_list)) do' if object_list[a].color_tags != [0.0,0.0]: print object_list[a].color_tags,'(object_list[a].color_tags) != [0.0,0.0]' text.insert(object_list[a].color_tags[0],'-') #text.insert('1.12','-') print 'Inserted - at',object_list[a].color_tags[0] object_list[a].color_tags[0] = takeint(object_list[a].color_tags[0]) + '.' + str(int(takedecimal(object_list[a].color_tags[0],0))+1) object_list[a].color_tags[1] = takeint(object_list[a].color_tags[1]) + '.' + str(int(takedecimal(object_list[a].color_tags[1],0))+1) print 'object_list[a].color_tags[0] now =',object_list[a].color_tags[0] text.config(state=DISABLED) print 'Exited Enter_Dashes \n********************' def prep_dashes(object_list,text,event): print 'Entered Prep_Dashes' #text.insert('1.2','new','norm') print 'object_list[0].color_tags =',object_list[0].color_tags enter_dashes(object_list,text) print 'object_list[0].color_tags =',object_list[0].color_tags print 'Exited Prep_Dashes' #------------------------------------------------------------------------------------- #-------------------------------------Main Loop--------------------------------------- #------------------------------------------------------------------------------------- def main (root, object_list): #root = VMDMenu.VMDMenu() root.title('VMD Residue Selector') RepColor = RepColorClass('4') mol_list = molecule.listall() #root.columnconfigure(0, weight = 1) #root.rowconfigure(0, weight = 1) ## addon = 0 ## height = len(object_list) ## if height > 30: ## addon = 9 ## elif height > 25: ## addon = 6 ## elif height > 20: ## addon = 5 ## elif height > 15: ## addon = 4 ## elif height > 10: ## addon = 3 ## elif height > 5: ## addon = 2 ## else: ## addon = 1 ## #Addon was added to len(object_list) and stored in height so characters wouldn't get cut off. #creates a new text box and inserts the name of the molecule(s) nametxt = Text(root,height=len(object_list),width=16) nametxt.grid(row=0,column=0,sticky='nesw') nametxt.tag_configure('namenorm',font=('Courier',16),wrap=NONE) for a in range( len( object_list )): nametxt.insert(END,object_list[a].my_name,'namenorm') if (a != len(object_list)-1): nametxt.insert(END,'\n','namenorm') nametxt.configure(state=DISABLED) #sets height of sequence text box - height was 3 when only two lines needed to be displayed text = Text(root, height = len(object_list), width = 100,font=('Courier',16),wrap=NONE,foreground='black',background='white') #height is two more than the number of molecules text.grid(row=0,column=1,columnspan=3,sticky='nesw') scroll = Scrollbar(root, command = text.xview, orient = HORIZONTAL) scroll.grid(row=1,column=1,columnspan=3,sticky='nesw') text.configure(xscrollcommand=scroll.set) text.tag_configure('colored', font=('Courier', 16), wrap = NONE, background='yellow') text.tag_configure('norm',font=('Courier',16),wrap=NONE, background='white', foreground='black') reslen = 0 #------------------------------ Output ------------------------------ #Print the one letter resname code (in string format, received from the ResClass object) output_s = '' for x in range(len(mol_list)): output_s = object_list[x].output_str() print output_s if (x == (len (mol_list) - 1 )): output_s = string.strip (output_s) text.insert(END, output_s) #---------------------------- End Output ----------------------------- scroll.config(command = text.xview) #BINDINGS text.bind("",Command(create_w_event, text, object_list, '0.5', RepColor)) text.bind("",Command(del_selections_w_event, object_list, text)) root.bind("",Command(prep_dashes, object_list, text)) root.bind("",Command(prep_delete1, text, object_list)) text.configure(state=DISABLED) Button(root, text='View Info', command=Command(view_information, text)).grid(row=2, column=1, sticky='nesw') Button(root, text='Select', command=Command(create, text, object_list, '0.5', RepColor)).grid(row=2, column=2, sticky='nesw') Button(root, text='Clear All', command=Command(clear_all, object_list, text)).grid(row=2, column=3, sticky='nesw') #Menu Bar menubar = Menu(root) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Exit", command=root.destroy) menubar.add_cascade(label="File", menu=filemenu) selectmenu = Menu(menubar, tearoff=0) colormenu = Menu(menubar, tearoff=0) colormenu.add_radiobutton(label="Blue", command=Command(RepColor.set, '0')) colormenu.add_radiobutton(label="Red", command=Command(RepColor.set, '1')) colormenu.add_radiobutton(label="Gray", command=Command(RepColor.set, '2')) colormenu.add_radiobutton(label="Orange", command=Command(RepColor.set, '3')) colormenu.add_radiobutton(label="Yellow", command=Command(RepColor.set, '4')) colormenu.add_radiobutton(label="Tan", command=Command(RepColor.set, '5')) colormenu.add_radiobutton(label="Silver", command=Command(RepColor.set, '6')) colormenu.add_radiobutton(label="Green", command=Command(RepColor.set, '7')) colormenu.add_radiobutton(label="White", command=Command(RepColor.set, '8')) colormenu.add_radiobutton(label="Pink", command=Command(RepColor.set, '9')) colormenu.add_radiobutton(label="Cyan", command=Command(RepColor.set, '10')) colormenu.add_radiobutton(label="Purple", command=Command(RepColor.set, '11')) colormenu.add_radiobutton(label="Lime", command=Command(RepColor.set, '12')) colormenu.add_radiobutton(label="Mauve", command=Command(RepColor.set, '13')) colormenu.add_radiobutton(label="Ochre", command=Command(RepColor.set, '14')) colormenu.add_radiobutton(label="IceBlue", command=Command(RepColor.set, '15')) colormenu.add_radiobutton(label="Black", command=Command(RepColor.set, '16')) colormenu.invoke(colormenu.index('Yellow')) selectmenu.add_cascade(label="Color", menu=colormenu) menubar.add_cascade(label="Options", menu=selectmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", command=about) menubar.add_cascade(label="Help", menu=helpmenu) # display the menu root.config(menu=menubar) #------------------------------------------------------------------------------------- #-------------------------------------- Start ---------------------------------------- #------------------------------------------------------------------------------------- MoleculeChangeLists = MolChange ()