#!/usr/bin/env python3 """ The main code. This code will look at the command line arguments. If an invalid number of arguments are given, it will return an error. Otherwise, it will read the commandline arguments. If one argument is given, the code will assume the class name is the same as the module name, and try to import the class. Otherwise, it will import the given class from the given module and try to make an instance of it. This code will first try to run ._parameters and ._facilities method of the instance. Then, it will check the dictionaryOfVariables of the Insar class to see what components may be required. If it is not empty, it will make a GUI with the following components: - Label to indicate the component name, and whether or not its optional - An entry box for the user to input the value for the component - Buttons for each facility to allow user to change the component of each one - A Save button to save the component values, as well as the components of the facilities that the user has saved - A button to switch between saving a single xml file or saving the xml file using multiple xml files - A Reset all button, which resets all the inputted data in program - A button to allow the user to use an existing xml file to change data - A quit button to quit the GUI Global Variables Used: parameters, dictionaryOfFacilities, facilityButtons, facilityDirs, classInstance, description, allParams, singleFile, directory, facilityParams """ import sys import os from StringIO import StringIO import Tkinter as tk import tkFileDialog, tkMessageBox, tkFont import xml.etree.ElementTree as ElementTree import isce from iscesys.Compatibility import Compatibility Compatibility.checkPythonVersion() #from insarApp import Insar import traceback from xml.parsers.expat import ExpatError """ Global Definitions: classInstance - The instance of Insar that is created. This is the instance which has the dictionaryOfVariables and dictionaryOfFacilities attributes. allParams - A dictionary of dictionaries containing all the parameters that have been set so far. parameters - a list containing class instances of class parameter, used to access the user entry and the name and whether or not it is optional in a clean manner. description - a description of variables for parameters facilityParams - a list containing instances of class parameter, used to access the user entry for the facility's parameter more easily, similar to global variable parameters. dictionaryOfFaciliites - the dictionaryOfFacilities, contains the names of all the facilities, as well as its factorymodule, which is the path to the module containing its factoryname, which creates an instance of the facility facilitiyButtons - The buttons, which causes a GUI for the facility to pop up when pressed. They are disabled when a facility GUI is already present. facilityDirs - A dictionary containing the locations that the user saved the xml file for each key, which is the facility name. root2 - The Tk instance for the second GUI, whcih should be the GUI for the facility's parameters. rootName - The name that the component in the xml is saved under. This value is either the name of a facility or 'insarApp'. directory - The directory at which the most recent file was saved. singleFile - A boolean which indicates whether or not to save the final XML file as a single file or multiple XML in catalog format. """ class RefactorWarning(DeprecationWarning): """put in to alert uses that the code needs to be refactored. Take out the raising if you don't like it""" pass class parameter: """Class parameter used to keep track of a parameter and its related objects Class Members: key: The name of the parameter text: The text widget used for inputting data of this parameter optional: Indicates whether or not this parameter is optional attrib: The name this parameter has as an Insar class attribute """ def __init__(self, key=None, text=None, optional=None, attrib = None): self.key = key self.text = text self.optional = optional self.attrib = attrib def indent(elem, level=0): """Indent an XML ElementTree""" i = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: indent(elem, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i ## Creates the Input XML file given the user's inputs. ## If the user has missed a mandatory field in the current level GUI, ## this will cause a pop-up box to appear and tell the user to ## fill in the mandatory fields. Otherwise, it will ask the ## user for a directory to save the xml file in and create the ## xml file given their inputs. If making the final xml file, ## i.e the input file for the insarApp, it will also add any ## directories created by using a catalog. ## ## global variables used - directory, facilityDirs, facilityButtons, ## singleFile, allParams def createInputXML(parameters, rootName): """Creates the Input XML File given the user inputs Arguments: parameters - A list of parameters to be inputted into the xml file rootName - The name of the root """ # Get necessary global variables global directory global facilityDirs global facilityButtons global facilityRequired global singleFile global allParams # Checks if any of the manadatory fields are blank. for param in parameters: if(not(param.optional) and param.text.get()==''): tkMessageBox.showerror('ERROR!', 'Mandatory Field(s) is blank!') return False # If rootName is insarApp, and it is in multi file XML mode, # then the user should have, by either loading an XML which is # in that form or creating multiple files, a file for each facility. if(rootName == 'insarApp' and not singleFile): for x in zip(facilityButtons,facilityRequired): button = x[0] req = x[1] try: if(facilityDirs[button.cget('text')]=='' and req): raise KeyError except KeyError: tkMessageBox.showerror('ERROR!', 'Facility parameters not saved in a file for:\n' + button.cget('text')) return False # If rootName is insarApp and it is in single file XML mode, # then the user should have, by either loading an XML file or # by inputting and saving, have data for each facility. elif(rootName == 'insarApp' and singleFile): for x in zip(facilityButtons,facilityRequired): button = x[0] req = x[1] try: if(allParams[button.cget('text')] == {} and req): raise KeyError except KeyError: tkMessageBox.showerror('ERROR!', 'Facility parameters not set in:\n' + button.cget('text')) return False # Get a directory from the user to save in if we are in multi file XML # mode and/or is saving the insarApp input file. if(not singleFile or rootName == 'insarApp'): directory = tkFileDialog.asksaveasfilename(initialfile=rootName+'.xml', title="Choose where to save:", defaultextension='.xml', filetypes=[('xml files', '.xml')]) if(not directory): return False else: # Create the input xml file using ElementTree. top = ElementTree.Element(rootName) top.text='\n' root = ElementTree.SubElement(top,'component', {'name':rootName}) for param in parameters: if(param.text.get()!=''): property = ElementTree.SubElement(root,'property', {'name':param.key}) value = ElementTree.SubElement(property,'value') value.text = param.text.get() # If this is the insarApp input file, we must put the # directory of all the input xml files for the facilities if(rootName == 'insarApp'): # If we are in sigleFile mode, write all the parameters # into the file that we were writing to. if singleFile: for key in allParams.keys(): if allParams[key]: facility = ElementTree.SubElement(root, 'component', {'name':key}) for paramKey in allParams[key].keys(): if allParams[key][paramKey]: param = ElementTree.SubElement(facility, 'property', {'name':paramKey}) value = ElementTree.SubElement(param, 'value') value.text = allParams[key][paramKey] # Otherwise, write the directory of each facility into # the file that we were writing to. else: for key in facilityDirs.keys(): if facilityDirs[key]: property = ElementTree.SubElement(root, 'component', {'name':key}) catalog = ElementTree.SubElement(property, 'catalog') catalog.text = facilityDirs[key] # Write the file using ElementTree # If the file we are saving is the insarApp input file, # we want insarApp tag on top of it. Otherwise, just # put the data in to the xml file if(rootName == 'insarApp'): tempTree = ElementTree.ElementTree(root) indent(tempTree.getroot()) tree = ElementTree.ElementTree(top) else: tree = ElementTree.ElementTree(root) indent(tree.getroot()) tree.write(directory) # Since the user is saving a facility in the single file XML mode, # save the values in the global variable allParams else: allParams[rootName] = {} for param in parameters: allParams[rootName][param.key] = param.text.get() return True ## Creates the input XML for a toplevel GUI, which ## should be for the facility's components. After ## saving the XML file, it will exit the toplevel ## GUI and save the directory that it was saved to ## in a dictionary with the key as the name of the ## facility. ## ## global variables used - facilityComponents, dir, rootName, facilityDirs def facilityInputXML(): """Creates an XML file for a facility's parameters""" global facilityParams global directory global rootName global facilityDirs # Create the XML using the facilityParameters # and the rootName, which was set as the facility name # when the facility GUI was made if(createInputXML(facilityParams, rootName)): facilityQuit() if(directory): facilityDirs[rootName] = directory return ## Creates the input XML for insarApp, which is ## at the root. def componentInputXML(): """Creates an XML file for the InsarApp""" global parameters global facilityDirs createInputXML(parameters, 'insarApp') ###The event that is called when a facilityButton is ## pressed by the user. When the button is pressed, ## the code will first try to create an instance of ## the class using the argument given in the ## dictionaryOfFacilities and the method given in it. ## If it fails, it will return an error ## message, indicating a matching argument for the method ## was not found. If it succeeds, it will disable the facility ## buttons, since we can only have one other GUI open at once. ## Then, it will also disable the inputs to the components, ## since those should not be changed, since the facility could ## depend on the values. It will then proceed to make ## a GUI with entries for each component found in the ## attribute dictionaryOfVariables of the instance. def facilityEvent(event): """Creates a pop-up GUI for inputting facility parameters""" # Load all the global variables used in this function global parameters global dictionaryOfFacilities global facilityButtons global facilityParams global rootName global root2 global classInstance global singleFile global allParams global facilityDocs # Find which facility button the user pressed # through its text, and set it as the rootName text = event.widget.cget('text') rootName = text # Initiate instance as None instance = None # Initiate a StringIO and set it as stdout to # catch any error messages the factory # method produces temp = sys.stdout errorStr = StringIO('') sys.stdout = errorStr # Call the parameters method to restore the # default value of facilities try: classInstance._parameters() except: pass for param in parameters: if param.text.get(): # exec 'classInstance.' + param.attrib + '= \'' + param.text.get() + '\'' setattr(classInstance, param.attrib, eval('\'' + param.text.get() + '\'')) pass pass try: classInstance._facilities() except: pass # Try to use the arguments in the dictionaryOfFacilities # to instantiate an instance of the facility try: args = dictionaryOfFacilities[text]['args'] kwargs = dictionaryOfFacilities[text]['kwargs'] # May need to be modified if a factory takes # the None argument modified = ['']*len(args) for i in range(0, len(args)): if(args[i] == None): modified[i] = 'None' else: modified[i] = args[i] pass pass modified = tuple(modified) # raise RefactorWarning("refactor with appy built-in") instance = eval( dictionaryOfFacilities[text]['factoryname']+'(*' + modified.__str__() + ', **' + kwargs.__str__() + ')' ) except Exception as e: traceback.print_exc(file=sys.stdout) tkMessageBox.showerror('ERROR!', 'Unknown error occurred:\n'+errorStr.getvalue()+'\n%s' %e) return None # If the instance is still none, this means # that an error message was produced, and # that it failed to make an instance. # Print out the error message # produced, which is contained in the StringIO sys.stdout = temp if instance is None: tkMessageBox.showerror('ERROR!', 'Bad argument for: ' + dictionaryOfFacilities[text]['factoryname'] + '\n' + errorStr.getvalue()) return # Try to run the ._parameters() and ._facilities() # methods of the instance, and then get its # dictionaryOfVariables try: instance._parameters() except: pass try: instance._facilities() except: pass dictionaryOfVariables = None try: dictionaryOfVariables = instance.dictionaryOfVariables except: pass # Check if the dictionaryOfVariables is empty or does not exist if (dictionaryOfVariables is None or dictionaryOfVariables == {}): # Create a Popup Error message sys.stdout = sys.stderr tkMessageBox.showerror('ERROR!', 'DictionaryOfVariables for ' + text + ' is empty! Nothing to do...') return # Disable all the facilityButtons b/c multiple facility # GUI's are not supported for button in facilityButtons: button.config(state='disabled') for param in parameters: param.text.config(state='disabled') XMLButton.config(state='disabled') # Create the new facility GUI root2 = tk.Toplevel() root2.protocol("WM_DELETE_WINDOW",facilityQuit) root2.title('Facility '+text+ ' Component Editor') tempFont = ('Times New Roman', 14) # Create a font with underlines uFont = tkFont.Font(family='Times New Roman', size=14, underline=True) # First column gives the name nameLabel = tk.Label(root2, text='Name (Click a name for help)', font=uFont) # Second column allows user to input values for each attribute valueLabel = tk.Label(root2, text='Value', font=uFont) # The third column is for units unitsLabel = tk.Label(root2, text='Units', font=uFont) # The fourth column indicates to users whether or not an # attribute is optional or mandatory. requiredLabel = tk.Label(root2, text='Optional/Mandatory', font=uFont) # Put each label in respective locations nameLabel.grid(row=0, column=0) valueLabel.grid(row=0, column=1) unitsLabel.grid(row=0, column=2) requiredLabel.grid(row=0, column=3) r = 1 # Reset facilityParams, since we are using a new # facility facilityParams = [] try: units = instance.unitsOfVariables except: pass try: facilityDocs = instance.descriptionOfVariables except: pass for key in dictionaryOfVariables.keys(): label = tk.Label(root2, text=key) label.grid(row=r, column=0) if(dictionaryOfVariables[key][2].lower() == 'optional'): opt = tk.Label(root2, text='Optional', fg='green') facilityParams.append(parameter(key, tk.Entry(root2), True)) else: opt = tk.Label(root2, text='Mandatory', fg='red') facilityParams.append(parameter(key, tk.Entry(root2), False)) try: label = tk.Label(root2, text=units[key]) label.grid(row=r, column=2) except: pass button = tk.Button(root2, text=key, width=25) button.bind('', facilityHelp) button.grid(row=r, column=0) opt.grid(row=r, column=3) facilityParams[r-1].text.grid(row=r, column=1) r = r + 1 # Put the known arguments into the entry boxes before outputting # them, and also check for any "trash" values inside the dictionary # that could occur from loading an xml file with incorrect facility # parameters temp = {} temp[text] = {} for param in facilityParams: try: param.text.insert(0, allParams[text][param.key]) temp[text][param.key] = allParams[text][param.key] except: pass allParams[text] = temp[text] # Create a quit and save button, as well as a dir button so # that the user can load a directory and use that as their # facility XML file quitButton = tk.Button(root2, text='Quit', command=facilityQuit) saveButton = tk.Button(root2, text='Save', command=facilityInputXML) dirButton = tk.Button(root2, text='Use An Existing\n XML File', command=getFacilityDirectory) quitButton.grid(row=r, column=2) saveButton.grid(row=r, column=1) dirButton.grid(row=r, column=0) root2.mainloop() def facilityHelp(event): """Creates help documentation for the facility GUI""" global facilityDocs text = event.widget.cget('text') if(text in facilityDocs.keys() and facilityDocs[text] != ''): tkMessageBox.showinfo(text+' documentation:', description[text]) else: tkMessageBox.showerror('Documentation Not Found!', 'There is no documentation\nfor this parameter') ## This method is called when the button for using an already existing ## XML file is clicked on the facility GUI. The method tries to open ## the xml file given, and stores the data in the global variable ## allParams, as well as populate them in the GUI's entry boxes. ## ## Global Variables Used: rootName, facilityDirs, facilityParams def getFacilityDirectory(): """Gets the directory for the xml used for the facility's parameter""" global rootName global facilityDirs global facilityParams directory = tkFileDialog.askopenfilename(title='Locate Your XML File for ' + rootName, defaultextension='.xml', filetypes=[('xml files', '.xml')]) if(directory): try: tree = ElementTree.parse(directory) value = '' name = '' for property in tree.findall('property'): name = property.attrib['name'] value = property.find('value').text for param in facilityParams: if param.key == name: param.text.delete(0, tk.END) param.text.insert(0, value) allParams[rootName][param.key] = value name = '' break if name != '': tkMessageBox.showerror('Error!', 'Invalid XML for'+ rootName + ' facility!' + '\nParameter ' + name + ' does not exist in this facility!') return except ExpatError: tkMessageBox.showerror('Error!', 'Invalid XML error! XML is ill formed!') except Exception: tkMessageBox.showerror('Error!', 'Invalid XML error! XML is ill formed for ' + rootName + '!') facilityDirs[rootName] = directory ## This is the quit button event for the facility GUI. This ## quits out of the for facility and reenables all the ## buttons for the other facilities and entry boxes for ## the components. ## ## Global Variables Used: facilityButtons, components, root2, XMLButton def facilityQuit(): """The button event for Quit button on facility GUI. This destroys the facility GUI and restores disabled buttons on main GUI.""" root2.destroy() for button in facilityButtons: button.config(state='normal') for param in parameters: param.text.config(state='normal') XMLButton.config(state='normal') def showDoc(event): """Shows documentation for the parameter written on the button""" text = event.widget.cget('text') if(text in description.keys() and description[text] != ''): tkMessageBox.showinfo(text+' documentation:', description[text]) else: tkMessageBox.showerror('Documentation Not Found!', 'There is no documentation\nfor this parameter') def changeSave(event): """Changes the save from single file save to multiple and vice versa""" global singleFile global facilityDirs singleFile = not singleFile if(singleFile): event.widget.configure(text='Currently:\nSingle XML File Mode') facilityDirs = {} else: event.widget.configure(text = 'Currently:\nMultiple XML Mode') return def loadXML(): """Loads an XML file for the insarApp and stores the data""" global parameters global allParams global facilityDirs facilityDirs = {} # Get the directory from the user directory = '' directory = tkFileDialog.askopenfilename(title='Locate Your XML File:', defaultextension='.xml', filetypes=[('xml files', '.xml')]) # If the user specified a directory, try loading it if directory: try: # Find the insarApp component which should have all the properties # and facilities tree = ElementTree.parse(directory).find('component') text = '' name = '' # First find all the parameters listed in the main GUI for property in tree.findall('property'): name = property.attrib['name'] value = property.find('value').text for param in parameters: if param.key == name: param.text.delete(0, tk.END) param.text.insert(0, value) name = '' break pass if name: tkMessageBox.showerror('Error!', 'Invalid xml for these parameters!\n'+ 'Parameter ' + name + ' does not exist!') pass pass # Then find the parameters for the facilities for facility in tree.findall('component'): exists = False facilityName = facility.attrib['name'] for button in facilityButtons: if button.cget('text') == facilityName: exists = True pass pass if not exists: tkMessageBox.showerror('Error!', 'Invalid xml error! Facility ' + facilityName + ' does not exist!') return None # Check whether or not the xml is in catalog format or all-in-one # format catalog = None catalog = facility.find('catalog') allParams[facilityName] = {} # If there is a catalog, assume that the first component # contains every parameter of the facility if catalog is not None: catalog = catalog.text facilityDirs[facilityName] = catalog facilityTree = ElementTree.parse(catalog) for property in facilityTree.findall('property'): name = property.attrib['name'] value = property.find('value').text allParams[facilityName][name] = value pass pass # Otherwise, go through the facility and get the parameters else: for property in facility.findall('property'): name = property.attrib['name'] value = property.find('value').text allParams[facilityName][name] = value except IOError: tkMessageBox.showerror('Error!', 'Invalid XML error! One or more XML does not exist!') except ExpatError: tkMessageBox.showerror('Error!', 'Invalid XML error! XML is ill formed!') except Exception: tkMessageBox.showerror('Error!', 'Invalid XML error! XML is valid for insarApp!') return def reset(): """After asking the user, resets everything in the code used for writing to an xml""" global allParams global facilityDirs global parameters global facilityButtons global root2 # Ask the user if they want to reset everything answer = tkMessageBox.askyesno("Are you sure?", "Are you sure you want to reset all data?") if answer: # Delete all entries in the main GUI for param in parameters: param.text.delete(0, tk.END) # Erase all data stored for writing to XML's allParams = {} facilityDirs = {} # Make sure that all the main GUI buttons are enabled for button in facilityButtons: button.configure(state='normal') facilityDirs[button.cget('text')] = '' allParams[button.cget('text')] = {} XMLButton.config(state='normal') # If there is a facility GUI, get rid of it try: root2.destroy() except: pass pass pass if __name__ == "__main__": """Builds the main GUI for making an XML input for given class""" # Get the global variable global parameters global dictionaryOfFacilities global facilityButtons global facilityRequired global facilityDirs global classInstance global description global allParams global singleFile global directory global facilityParams parameters = [] facilityParams = [] dictionaryOfFacilities = {} facilityButtons = [] facilityRequired = [] facilityDirs = {} root2 = None rootName = '' directory = '' allParams = {} # Create an instance of Insar to run the _parameters() and # _facilities() function, if they exist, to create the # dictionaryOfVariables. try: if(len(sys.argv) != 2 and len(sys.argv) != 3): print("Invalid commandline arguments:") print("Usage 1, Module and Class have same names: xmlGenerator Module") print("Usage 2, Module and Class names different: xmlGenerator Module Class") print("(Module name should not include the '.py')") sys.exit() elif(len(sys.argv) == 2): if 'help' in sys.argv[1]: print("'Invalid commandline arguments:\nUsage: xmlGenerator [Module (sans '.py'] [Class]") # raise RefactorWarning("refactor with __import__ built-in") print("Assuming module name and class name are both, ", sys.argv[1]) exec('from ' + sys.argv[1] + ' import ' + sys.argv[1]) classInstance = eval(sys.argv[1] + '()') else: print("importing class %s from module %s" % (sys.argv[1], sys.argv[2])) # raise RefactorWarning("refactor with __import__ built-in") exec('from ' + sys.argv[1] + ' import ' + sys.argv[2]) # print sys.argv[2] classInstance = eval(sys.argv[2] + '()') pass pass except ImportError as e: print("Invalid arguments!") print("Either the given module or the given class does not exist,") print("or you have assumed they both have the same name and they do not.") sys.exit() pass try: classInstance._parameters() classInstance._facilities() except: pass dictionaryOfVariables = classInstance.dictionaryOfVariables try: dictionaryOfFacilities = classInstance._dictionaryOfFacilities except: pass # If the dictionaryOfVariables is not empty, create # the GUI if dictionaryOfVariables: # Since Frame class does not have scrollbars, use a # canvas to create a scrollbar in the y direction root = tk.Tk() root.title(sys.argv[1] + ' Input XML File Generator') verticalBar = tk.Scrollbar(root) verticalBar.grid(row=0, column=1, sticky='N'+'S') # Create the Canvas, which will have the scroll bar as # well as the frame. Change the width here to # change the starting width of the screen. canvas = tk.Canvas(root, yscrollcommand=verticalBar.set, width=1100, height=500) canvas.grid(row=0, column=0, sticky='N'+'S'+'E'+'W') verticalBar.config(command=canvas.yview) root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(0, weight=1) frame = tk.Frame(canvas) frame.rowconfigure(1, weight=1) frame.columnconfigure(1, weight=1) # Begin creating the GUI involved with input variables # Create a font with underlines uFont = tkFont.Font(family='Times New Roman', size=14, underline=True) # Create a parameters label paramLabel = tk.Label(frame, text='Parameters:', font=("Times New Roman", 20, "bold")) # First column gives the name nameLabel = tk.Label(frame, text='Name (Click a name for help)', font=uFont) # Second column allows user to input values for each attribute valueLabel = tk.Label(frame, text='Value', font=uFont) # The third column is for units unitsLabel = tk.Label(frame, text='Units', font=uFont) # The fourth column indicates to users whether or not an # attribute is optional or mandatory. requiredLabel = tk.Label(frame, text='Optional/Mandatory', font=uFont) # Put each label in respective locations paramLabel.grid(row=0, column=0) nameLabel.grid(row=1, column=0, columnspan=2) valueLabel.grid(row=1, column=2) unitsLabel.grid(row=1, column=4) requiredLabel.grid(row=1, column=5) # Create a variable for the row r = 2 try: description = classInstance.descriptionOfVariables except: pass units = {} try: units = classInstance.unitsOfVariables except: pass for key in dictionaryOfVariables.keys(): val = dictionaryOfVariables[key] # Make the label from the keys in the dictionary # Change the wraplength here for the names if it is too short or long. # label = tk.Label(frame, text=key, anchor = tk.W, justify=tk.LEFT, wraplength=100) # label.grid(row=r,column=0) # Indicate whether the attribute is optional or mandatory if(val[2].lower() == ('optional')): required = tk.Label(frame, text='Optional', fg='green') parameters.append(parameter(key, tk.Entry(frame, width=50), True, val[0])) else: required = tk.Label(frame, text='Mandatory', fg='red') parameters.append(parameter(key, tk.Entry(frame, width=50), False, val[0])) pass try: doc = tk.Button(frame, text=key, anchor = tk.W, justify=tk.LEFT, width=50, wraplength=348) doc.bind('', showDoc) doc.grid(row=r, column=0, columnspan=2) except: pass try: unit = tk.Label(frame, text=units[key]) unit.grid(row=r, column=2) except: pass required.grid(row=r,column=5) # Put the Entry in global variable, since it is needed # for saving inputted values into xml parameters[r-2].text.grid(row=r,column=2, columnspan=2) r = r + 1 pass if dictionaryOfFacilities: # Add a label indicating that these buttons are facilities facilityLabel = tk.Label(frame, text='Facilities:', font=("Times New Roman", 20, "bold"), justify=tk.LEFT, anchor=tk.W) facilityLabel.grid(row=r, column=0) r = r + 1 x = 0 # Make the buttons to edit facility parameters and import # the required modules using the factorymodule for key in dictionaryOfFacilities.keys(): facilityButtons.append(tk.Button(frame, text = key, width=50, justify=tk.LEFT, anchor=tk.W, wraplength=348)) facilityButtons[x].grid(row=r, column=0, columnspan=2) facilityButtons[x].bind('', facilityEvent) facilityDirs[key] = '' allParams[key] = {} if dictionaryOfFacilities[key]['mandatory']: facilityRequired.append(True) required = tk.Label(frame, text='Mandatory', fg='red') required.grid(row=r,column=5) else: facilityRequired.append(False) required = tk.Label(frame, text='Optional', fg='green') required.grid(row=r,column=5) r = r + 1 x = x + 1 try: exec ('from ' + dictionaryOfFacilities[key]['factorymodule'] + ' import ' + dictionaryOfFacilities[key]['factoryname']) raise RefactorWarning("refactor with __import__ built-in") except: pass pass pass # Buttons for saving the xml file, using an existing xml file, # changing the save settings, and quitting out of the program saveButton = tk.Button(frame, text="Save", command=componentInputXML) quitButton = tk.Button(frame, text="Quit", command=root.destroy) resetButton = tk.Button(frame, text='Reset All', command=reset) # The button for switching between multiple xml mode and single # mode. The default is multiple XML mode. singleFile = False singleFileButton = tk.Button(frame, text='Currently:\nMultiple XML Mode') singleFileButton.bind('', changeSave) # The button used to get an existing XML file XMLButton = tk.Button(frame, text='Use an existing XML File', command=loadXML) saveButton.grid(row=r+1, column=2) quitButton.grid(row=r+1, column=3) resetButton.grid(row=r+1, column=4) singleFileButton.grid(row=r+1, column=5) XMLButton.grid(row=r+1, column=1) # Have the canvas create a window in the top left corner, # which is the frame with everything on it canvas.create_window(0, 0, anchor='nw', window=frame) frame.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) root.mainloop() else: tkMessageBox.showerror('ERROR!', 'Dictionary of Variables Empty: Nothing to do') pass sys.exit()