class NewActionModulation(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.parent.title("Test") self.frameTab = Frame(self, relief=RAISED, borderwidth=1) self.frameTab.grid(row=3, column=0, columnspan=4) self.grid(row=0, column=0) self.frameTab.grid(row=0, column=0) self.note_book = Notebook(self.frameTab) self.specific_actions = ActionModulation.ActionModulation(self.note_book) self.note_book.add(self.specific_actions.getFrame(), text="specific actions") self.general_actions = GeneralActionModulation.GeneralActionModulation(self.note_book) self.note_book.add(self.general_actions.getFrame(), text="general actions") self.note_book.grid(row=0, column=0) self.frameButtons = Frame(self, relief=RAISED, borderwidth=1) self.frameButtons.grid(row=3, column=0, columnspan=4) self.buttonReset = Button(self.frameButtons, text="Reset") self.buttonReset.grid(row=0, column=0) self.buttonAbort = Button(self.frameButtons, text="Abort") self.buttonAbort.grid(row=0, column=1) self.buttonStop = Button(self.frameButtons, text="Stop") self.buttonStop.grid(row=0, column=2) self.buttonSendAction = Button(self.frameButtons, text="Send Action") self.buttonSendAction.grid(row=0, column=4) self.buttonSendEmotion = Button(self.frameButtons, text="Send Emotion") self.buttonSendEmotion.grid(row=0, column=5) def getCurrentTab(self): return self.note_book.index(self.note_book.select()) def getFirstTab(self): return self.specific_actions def getSecondTab(self): return self.general_actions def getButtonSendAction(self): return self.buttonSendAction def getButtonSendEmotion(self): return self.buttonSendEmotion def getButtonReset(self): return self.buttonReset def getButtonAbort(self): return self.buttonAbort def getButtonStop(self): return self.buttonStop
class ConverterFrame(Frame): def __init__(self, converter, master=None): Frame.__init__(self, master) master.title("Ai Variable tool") self.converter = converter self.grid(row=0, sticky=(tk.N + tk.E + tk.W + tk.S)) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.tabbedPane = Notebook(self, name="tabbed-pane") self.tabbedPane.grid(row=0, column=0, sticky=(tk.N + tk.E + tk.W + tk.S)) self.btnSave = tk.Button(self, text="Guardar", command=self.btnSaveCallback) self.btnSave.grid(row=1, column=0, sticky=(tk.N + tk.E + tk.W + tk.S)) self.rawTextPanel = RawTextPane(self.tabbedPane) self.rawTextPanel.grid(row=0, column=0, sticky=(tk.N + tk.E + tk.W + tk.S)) self.numbersPanel = NumbersPane(self.tabbedPane) self.numbersPanel.grid(row=0, column=0, sticky=(tk.N + tk.E + tk.W + tk.S)) self.tabbedPane.add(self.numbersPanel, text="Series de numeros") self.tabbedPane.add(self.rawTextPanel, text="Texto en crudo") self.panels = [self.numbersPanel, self.rawTextPanel] def btnSaveCallback(self): filename = tkFileDialog.asksaveasfilename( initialdir=".", title="Select file", filetypes=(("Xml files", "*.xml"), ("All files", "*.*"))) current_idx = self.tabbedPane.index("current") work_text = self.panels[current_idx].getText() self.converter.convert(work_text) if not self.converter.save(filename): tkMessageBox.showerror("Error", "El archivo no ha sido almacenado.") else: tkMessageBox.showinfo( "Exito", "El archivo ha sido almacenado adecuadamente.")
def _create_panel(self): panel = Frame(self, name='elastic') #panel.pack(side=TOP, fill=BOTH, expand=Y) panel.grid(row=0, column=0, sticky=NSEW) nb = Notebook(panel, name='notebook') nb.enable_traversal() #nb.pack(fill=BOTH, expand=Y, padx=2, pady=3) nb.grid(row=0, column=0, sticky=NSEW) self._create_setup_tab(nb) self._create_analyze_tab(nb)
class GUI: ## GUI variables titleText = 'PyCX Simulator' # window title timeInterval = 0 # refresh time in milliseconds running = False modelFigure = None stepSize = 1 currentStep = 0 def __init__(self,title='PyCX Simulator',interval=0,stepSize=1,parameterSetters=[]): self.titleText = title self.timeInterval = interval self.stepSize = stepSize self.parameterSetters = parameterSetters self.varEntries = {} self.statusStr = "" self.initGUI() def initGUI(self): #create root window self.rootWindow = Tk() self.statusText = StringVar(value=self.statusStr) self.setStatusStr("Simulation not yet started") self.rootWindow.wm_title(self.titleText) self.rootWindow.protocol('WM_DELETE_WINDOW',self.quitGUI) self.rootWindow.geometry('550x400') self.rootWindow.columnconfigure(0, weight=1) self.rootWindow.rowconfigure(0, weight=1) self.notebook = Notebook(self.rootWindow) self.notebook.grid(row=0,column=0,padx=2,pady=2,sticky='nswe') self.frameRun = Frame() self.frameSettings = Frame() self.frameParameters = Frame() self.frameInformation = Frame() self.notebook.add(self.frameRun,text="Run") self.notebook.add(self.frameSettings,text="Settings") self.notebook.add(self.frameParameters,text="Parameters") self.notebook.add(self.frameInformation,text="Info") self.notebook.pack(expand=YES, fill=BOTH, padx=5, pady=5 ,side=TOP) self.status = Label(self.rootWindow, width=40,height=3, relief=SUNKEN, bd=1,textvariable=self.statusText) self.status.grid(row=1,column=0,padx=2,pady=2,sticky='nswe') self.status.pack(side=TOP, fill=X, padx=1, pady=1, expand=NO) self.runPauseString = StringVar() self.runPauseString.set("Run") self.buttonRun = Button(self.frameRun,width=30,height=2,textvariable=self.runPauseString,command=self.runEvent) self.buttonRun.pack(side=TOP, padx=5, pady=5) self.showHelp(self.buttonRun,"Runs the simulation (or pauses the running simulation)") self.buttonStep = Button(self.frameRun,width=30,height=2,text='Step Once',command=self.stepOnce) self.buttonStep.pack(side=TOP, padx=5, pady=5) self.showHelp(self.buttonStep,"Steps the simulation only once") self.buttonReset = Button(self.frameRun,width=30,height=2,text='Reset',command=self.resetModel) self.buttonReset.pack(side=TOP, padx=5, pady=5) self.showHelp(self.buttonReset,"Resets the simulation") can = Canvas(self.frameSettings) lab = Label(can, width=25,height=1,text="Step size ", justify=LEFT, anchor=W,takefocus=0) lab.pack(side='left') self.stepScale = Scale(can,from_=1, to=50, resolution=1,command=self.changeStepSize,orient=HORIZONTAL, width=25,length=150) self.stepScale.set(self.stepSize) self.showHelp(self.stepScale,"Skips model redraw during every [n] simulation steps\nResults in a faster model run.") self.stepScale.pack(side='left') can.pack(side='top') can = Canvas(self.frameSettings) lab = Label(can, width=25,height=1,text="Step visualization delay in ms ", justify=LEFT, anchor=W,takefocus=0) lab.pack(side='left') self.stepDelay = Scale(can,from_=0, to=max(2000,self.timeInterval), resolution=10,command=self.changeStepDelay,orient=HORIZONTAL, width=25,length=150) self.stepDelay.set(self.timeInterval) self.showHelp(self.stepDelay,"The visualization of each step is delays by the given number of milliseconds.") self.stepDelay.pack(side='left') can.pack(side='top') scrollInfo = Scrollbar(self.frameInformation) self.textInformation = Text(self.frameInformation, width=45,height=13,bg='lightgray',wrap=WORD,font=("Courier",10)) scrollInfo.pack(side=RIGHT, fill=Y) self.textInformation.pack(side=LEFT,fill=BOTH,expand=YES) scrollInfo.config(command=self.textInformation.yview) self.textInformation.config(yscrollcommand=scrollInfo.set) for variableSetter in self.parameterSetters: can = Canvas(self.frameParameters) lab = Label(can, width=25,height=1,text=variableSetter.__name__+" ",anchor=W,takefocus=0) lab.pack(side='left') ent = Entry(can, width=11) ent.insert(0, str(variableSetter())) if variableSetter.__doc__ != None and len(variableSetter.__doc__) > 0: self.showHelp(ent,variableSetter.__doc__.strip()) ent.pack(side='left') can.pack(side='top') self.varEntries[variableSetter]=ent if len(self.parameterSetters) > 0: self.buttonSaveParameters = Button(self.frameParameters,width=50,height=1,command=self.saveParametersCmd,text="Save parameters to the running model",state=DISABLED) self.showHelp(self.buttonSaveParameters,"Saves the parameter values.\nNot all values may take effect on a running model\nA model reset might be required.") self.buttonSaveParameters.pack(side='top',padx=5,pady=5) self.buttonSaveParametersAndReset = Button(self.frameParameters,width=50,height=1,command=self.saveParametersAndResetCmd,text="Save parameters to the model and reset the model") self.showHelp(self.buttonSaveParametersAndReset,"Saves the given parameter values and resets the model") self.buttonSaveParametersAndReset.pack(side='top',padx=5,pady=5) def setStatusStr(self,newStatus): self.statusStr = newStatus self.statusText.set(self.statusStr) #model control functions def changeStepSize(self,val): self.stepSize = int(val) def changeStepDelay(self,val): self.timeInterval= int(val) def saveParametersCmd(self): for variableSetter in self.parameterSetters: variableSetter(float(self.varEntries[variableSetter].get())) self.setStatusStr("New parameter values have been set") def saveParametersAndResetCmd(self): self.saveParametersCmd() self.resetModel() def runEvent(self): self.running = not self.running if self.running: self.rootWindow.after(self.timeInterval,self.stepModel) self.runPauseString.set("Pause") self.buttonStep.configure(state=DISABLED) self.buttonReset.configure(state=DISABLED) if len(self.parameterSetters) > 0: self.buttonSaveParameters.configure(state=NORMAL) self.buttonSaveParametersAndReset.configure(state=DISABLED) else: self.runPauseString.set("Continue Run") self.buttonStep.configure(state=NORMAL) self.buttonReset.configure(state=NORMAL) if len(self.parameterSetters) > 0: self.buttonSaveParameters.configure(state=NORMAL) self.buttonSaveParametersAndReset.configure(state=NORMAL) def stepModel(self): if self.running: self.modelStepFunc() self.currentStep += 1 self.setStatusStr("Step "+str(self.currentStep)) self.status.configure(foreground='black') if (self.currentStep) % self.stepSize == 0: self.drawModel() self.rootWindow.after(int(self.timeInterval*1.0/self.stepSize),self.stepModel) def stepOnce(self): self.running = False self.runPauseString.set("Continue Run") self.modelStepFunc() self.currentStep += 1 self.setStatusStr("Step "+str(self.currentStep)) self.drawModel() if len(self.parameterSetters) > 0: self.buttonSaveParameters.configure(state=NORMAL) def resetModel(self): self.running = False self.runPauseString.set("Run") self.modelInitFunc() self.currentStep = 0; self.setStatusStr("Model has been reset") self.drawModel() def drawModel(self): if self.modelFigure == None or self.modelFigure.canvas.manager.window == None: self.modelFigure = PL.figure() PL.ion() PL.show() self.modelDrawFunc() self.modelFigure.canvas.manager.window.update() def start(self,func=[]): if len(func)==3: self.modelInitFunc = func[0] self.modelDrawFunc = func[1] self.modelStepFunc = func[2] if (self.modelStepFunc.__doc__ != None and len(self.modelStepFunc.__doc__)>0): self.showHelp(self.buttonStep,self.modelStepFunc.__doc__.strip()) if (self.modelInitFunc.__doc__ != None and len(self.modelInitFunc.__doc__)>0): self.textInformation.config(state=NORMAL) self.textInformation.delete(1.0, END) self.textInformation.insert(END, self.modelInitFunc.__doc__.strip()) self.textInformation.config(state=DISABLED) self.modelInitFunc() self.drawModel() self.rootWindow.mainloop() def quitGUI(self): PL.close('all') self.rootWindow.quit() self.rootWindow.destroy() def showHelp(self, widget,text): def setText(self): self.statusText.set(text) self.status.configure(foreground='blue') def showHelpLeave(self): self.statusText.set(self.statusStr) self.status.configure(foreground='black') widget.bind("<Enter>", lambda e : setText(self)) widget.bind("<Leave>", lambda e : showHelpLeave(self))
class GUI: ## GUI variables titleText = 'PyCX Simulator' # window title timeInterval = 0 # refresh time in milliseconds running = False modelFigure = None stepSize = 1 currentStep = 0 def __init__(self,title='PyCX Simulator',interval=0,stepSize=1,parameterSetters=[]): self.titleText = title self.timeInterval = interval self.stepSize = stepSize self.parameterSetters = parameterSetters self.varEntries = {} self.statusStr = "" self.initGUI() def initGUI(self): #create root window self.rootWindow = Tk() self.statusText = StringVar(value=self.statusStr) self.setStatusStr("Simulation not yet started") self.rootWindow.wm_title(self.titleText) self.rootWindow.protocol('WM_DELETE_WINDOW',self.quitGUI) self.rootWindow.geometry('550x400') self.rootWindow.columnconfigure(0, weight=1) self.rootWindow.rowconfigure(0, weight=1) self.notebook = Notebook(self.rootWindow) self.notebook.grid(row=0,column=0,padx=2,pady=2,sticky='nswe') self.frameRun = Frame() self.frameSettings = Frame() self.frameParameters = Frame() self.frameInformation = Frame() self.notebook.add(self.frameRun,text="Run") self.notebook.add(self.frameSettings,text="Settings") self.notebook.add(self.frameParameters,text="Parameters") self.notebook.add(self.frameInformation,text="Info") self.notebook.pack(expand=YES, fill=BOTH, padx=5, pady=5 ,side=TOP) self.status = Label(self.rootWindow, width=40,height=3, relief=SUNKEN, bd=1,textvariable=self.statusText) self.status.grid(row=1,column=0,padx=2,pady=2,sticky='nswe') self.status.pack(side=TOP, fill=X, padx=1, pady=1, expand=NO) self.runPauseString = StringVar() self.runPauseString.set("Run") self.buttonRun = Button(self.frameRun,width=30,height=2,textvariable=self.runPauseString,command=self.runEvent) self.buttonRun.pack(side=TOP, padx=5, pady=5) self.showHelp(self.buttonRun,"Runs the simulation (or pauses the running simulation)") self.buttonStep = Button(self.frameRun,width=30,height=2,text='Step Once',command=self.stepOnce) self.buttonStep.pack(side=TOP, padx=5, pady=5) self.showHelp(self.buttonStep,"Steps the simulation only once") self.buttonReset = Button(self.frameRun,width=30,height=2,text='Reset',command=self.resetModel) self.buttonReset.pack(side=TOP, padx=5, pady=5) self.showHelp(self.buttonReset,"Resets the simulation") can = Canvas(self.frameSettings) lab = Label(can, width=25,height=1,text="Step size ", justify=LEFT, anchor=W,takefocus=0) lab.pack(side='left') self.stepScale = Scale(can,from_=1, to=50, resolution=1,command=self.changeStepSize,orient=HORIZONTAL, width=25,length=150) self.stepScale.set(self.stepSize) self.showHelp(self.stepScale,"Skips model redraw during every [n] simulation steps\nResults in a faster model run.") self.stepScale.pack(side='left') can.pack(side='top') can = Canvas(self.frameSettings) lab = Label(can, width=25,height=1,text="Step visualization delay in ms ", justify=LEFT, anchor=W,takefocus=0) lab.pack(side='left') self.stepDelay = Scale(can,from_=0, to=max(2000,self.timeInterval), resolution=10,command=self.changeStepDelay,orient=HORIZONTAL, width=25,length=150) self.stepDelay.set(self.timeInterval) self.showHelp(self.stepDelay,"The visualization of each step is delays by the given number of milliseconds.") self.stepDelay.pack(side='left') can.pack(side='top') scrollInfo = Scrollbar(self.frameInformation) self.textInformation = Text(self.frameInformation, width=45,height=13,bg='lightgray',wrap=WORD,font=("Courier",10)) scrollInfo.pack(side=RIGHT, fill=Y) self.textInformation.pack(side=LEFT,fill=BOTH,expand=YES) scrollInfo.config(command=self.textInformation.yview) self.textInformation.config(yscrollcommand=scrollInfo.set) for variableSetter in self.parameterSetters: can = Canvas(self.frameParameters) lab = Label(can, width=25,height=1,text=variableSetter.__name__+" ",anchor=W,takefocus=0) lab.pack(side='left') ent = Entry(can, width=11) ent.insert(0, str(variableSetter())) if variableSetter.__doc__ != None and len(variableSetter.__doc__) > 0: self.showHelp(ent,variableSetter.__doc__.strip()) ent.pack(side='left') can.pack(side='top') self.varEntries[variableSetter]=ent if len(self.parameterSetters) > 0: self.buttonSaveParameters = Button(self.frameParameters,width=50,height=1,command=self.saveParametersCmd,text="Save parameters to the running model",state=DISABLED) self.showHelp(self.buttonSaveParameters,"Saves the parameter values.\nNot all values may take effect on a running model\nA model reset might be required.") self.buttonSaveParameters.pack(side='top',padx=5,pady=5) self.buttonSaveParametersAndReset = Button(self.frameParameters,width=50,height=1,command=self.saveParametersAndResetCmd,text="Save parameters to the model and reset the model") self.showHelp(self.buttonSaveParametersAndReset,"Saves the given parameter values and resets the model") self.buttonSaveParametersAndReset.pack(side='top',padx=5,pady=5) def setStatusStr(self,newStatus): self.statusStr = newStatus self.statusText.set(self.statusStr) #model control functions def changeStepSize(self,val): self.stepSize = int(val) def changeStepDelay(self,val): self.timeInterval= int(val) def saveParametersCmd(self): for variableSetter in self.parameterSetters: variableSetter(float(self.varEntries[variableSetter].get())) self.setStatusStr("New parameter values have been set") def saveParametersAndResetCmd(self): self.saveParametersCmd() self.resetModel() def runEvent(self): self.running = not self.running if self.running: self.rootWindow.after(self.timeInterval,self.stepModel) self.runPauseString.set("Pause") self.buttonStep.configure(state=DISABLED) self.buttonReset.configure(state=DISABLED) if len(self.parameterSetters) > 0: self.buttonSaveParameters.configure(state=NORMAL) self.buttonSaveParametersAndReset.configure(state=DISABLED) else: self.runPauseString.set("Continue Run") self.buttonStep.configure(state=NORMAL) self.buttonReset.configure(state=NORMAL) if len(self.parameterSetters) > 0: self.buttonSaveParameters.configure(state=NORMAL) self.buttonSaveParametersAndReset.configure(state=NORMAL) def stepModel(self): if self.running: self.modelStepFunc() self.currentStep += 1 self.setStatusStr("Step "+str(self.currentStep)) self.status.configure(foreground='black') if (self.currentStep) % self.stepSize == 0: self.drawModel() self.rootWindow.after(int(self.timeInterval*1.0/self.stepSize),self.stepModel) def stepOnce(self): self.running = False self.runPauseString.set("Continue Run") self.modelStepFunc() self.currentStep += 1 self.setStatusStr("Step "+str(self.currentStep)) self.drawModel() if len(self.parameterSetters) > 0: self.buttonSaveParameters.configure(state=NORMAL) def resetModel(self): self.running = False self.runPauseString.set("Run") self.modelInitFunc() self.currentStep = 0; self.setStatusStr("Model has been reset") self.drawModel() def drawModel(self): if self.modelFigure == None or self.modelFigure.canvas.manager.window == None: self.modelFigure = PL.figure() PL.ion() self.modelDrawFunc() self.modelFigure.canvas.manager.window.update() def start(self,func=[]): if len(func)==3: self.modelInitFunc = func[0] self.modelDrawFunc = func[1] self.modelStepFunc = func[2] if (self.modelStepFunc.__doc__ != None and len(self.modelStepFunc.__doc__)>0): self.showHelp(self.buttonStep,self.modelStepFunc.__doc__.strip()) if (self.modelInitFunc.__doc__ != None and len(self.modelInitFunc.__doc__)>0): self.textInformation.config(state=NORMAL) self.textInformation.delete(1.0, END) self.textInformation.insert(END, self.modelInitFunc.__doc__.strip()) self.textInformation.config(state=DISABLED) self.modelInitFunc() self.drawModel() self.rootWindow.mainloop() def quitGUI(self): PL.close('all') self.rootWindow.quit() self.rootWindow.destroy() def showHelp(self, widget,text): def setText(self): self.statusText.set(text) self.status.configure(foreground='blue') def showHelpLeave(self): self.statusText.set(self.statusStr) self.status.configure(foreground='black') widget.bind("<Enter>", lambda e : setText(self)) widget.bind("<Leave>", lambda e : showHelpLeave(self))
class Application(Frame): def __init__(self, master): Frame.__init__(self, master) self.FileObjects = [] self.FileObjectNames = [] self.intSettings = {'Group': IntVar(value=1), 'DataObject': IntVar(value=1), 'FieldVariables': IntVar(value=1)} self.FieldVariables = OrderedDict() self.notebook = Notebook(self) self.tab1 = Frame(self.notebook) self.tab2 = Frame(self.notebook) self.notebook.add(self.tab1, text="Data Interaction") self.notebook.add(self.tab2, text="Mach-1 Image Grid") self.notebook.grid(row=0, column=0, sticky=NW) ##### BEGIN TAB 1 ##### self.frameDataFiles = Frame(self.tab1) self.frameDataFiles.grid(row=0, column=0, sticky=N+W+E) self.buttonLoadFile = Button(self.frameDataFiles, text="Load Data File", command=self.loadFile) self.buttonLoadFile.grid(row=0, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonRemoveFile = Button(self.frameDataFiles, text="Remove Selected File", command=self.removeDataObject) self.buttonRemoveFile.grid(row=1, column=0, padx=1, pady=1, sticky=N+W+E) self.frameDataObjects = LabelFrame(self.tab1, text="Data Files") self.frameDataObjects.grid(row=0, column=1, padx=1, pady=1, sticky=N+W+E) self.frameGroups = LabelFrame(self.tab1, text="Group Selection") self.frameGroups.grid(row=1, column=0, padx=1, pady=1, sticky=N+W+E ) Label(self.frameGroups, text="").grid(row=0, column=0, sticky=N+W+E) self.frameChannels = LabelFrame(self.tab1, text="Channel Selection") self.frameChannels.grid(row=1, column=1, padx=1, pady=1, sticky=N+W+E) Label(self.frameChannels, text="").grid(row=0, column=0, sticky=N+W+E) self.frameTab1BottomLeft = Frame(self.tab1) self.frameTab1BottomLeft.grid(row=2, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonSaveFile = Button(self.frameTab1BottomLeft, text="Save Selected to Pickle", command=self.saveFile) self.buttonSaveFile.grid(row=0, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonSaveCSV = Button(self.frameTab1BottomLeft, text="Save Selected to CSV", command=self.saveCSV) self.buttonSaveCSV.grid(row=1, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonGetThickness = Button(self.frameTab1BottomLeft, text="Get Mach-1 Thicknesses", command=self.findThicknesses) self.buttonGetThickness.grid(row=2, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonPlot = Button(self.frameTab1BottomLeft, text="Plot Selected Channels", command=self.plotChannels) self.buttonPlot.grid(row=3, column=0, padx=1, pady=1, sticky=N+W+E) self.frameTab1BottomRight = Frame(self.tab1) self.frameTab1BottomRight.grid(row=2, column=1, padx=1, pady=1, sticky=N+W+E) self.buttonMovingAvg = Button(self.frameTab1BottomRight, text="Apply Moving Average", command=self.applyMovingAvg) self.buttonMovingAvg.grid(row=0, column=0, padx=1, pady=1, columnspan=2, sticky=N+W+E) self.windowSize = IntVar(value=10) Label(self.frameTab1BottomRight, text="Window Size").grid(row=1, column=0, padx=1, pady=1, sticky=N+W) Entry(self.frameTab1BottomRight, textvariable=self.windowSize, width=4).grid(row=1, column=1, padx=1, pady=1, sticky=N+W) ##### END TAB 1 ##### ##### BEGIN TAB 2 ##### self.frameImageButtons = Frame(self.tab2) self.frameImageButtons.grid(row=0, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonLoadImage = Button(self.frameImageButtons, text="Load Image", command=self.loadImage) self.buttonLoadImage.grid(row=0, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonLoadMapFile = Button(self.frameImageButtons, text="Load Mach-1 Site Locations", command=self.loadMachMap) self.buttonLoadMapFile.grid(row=1, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonDefineMask = Button(self.frameImageButtons, text="Define Mask", command=self.cropImage) self.buttonDefineMask.grid(row=2, column=0, padx=1, pady=1, sticky=N+W+E) self.buttonClearMask = Button(self.frameImageButtons, text="Clear Mask", command=self.clearMask) self.buttonClearMask.grid(row=3, column=0, padx=1, pady=1, sticky=N+W+E) self.frameFieldVariables = LabelFrame(self.tab2, text="Field Variables") self.frameFieldVariables.grid(row=1, column=0, padx=1, pady=1, sticky=N+W+E) ##### END TAB 2 ##### self.grid() def loadFile(self): self.filename = tkFileDialog.askopenfilename( parent=root, initialdir=os.getcwd(), title="Select a Data File.") if self.filename: self.FileObjects.append(Data(self.filename)) self.FileObjectNames.append(os.path.basename(self.filename)) for child in self.frameGroups.grid_slaves(): child.grid_remove() del child self.intSettings["Group"].set(1) row = 0 column = 0 for i, g in enumerate(self.FileObjects[-1].groups): if i % 12 == 0: row = 0 column += 1 Radiobutton(self.frameGroups, text=g, indicatoron=0, width=5, variable=self.intSettings["Group"], command=self.populateChannelList, value=i+1).grid(row=row, column=column, sticky=NW) row += 1 g = self.FileObjects[-1].groups[self.intSettings["Group"].get() - 1] for child in self.frameChannels.grid_slaves(): child.grid_remove() del child row = 0 column = 0 self.channelSelections = {} for c in self.FileObjects[-1].time[g].keys(): if i % 12 == 0: row = 0 column += 1 self.channelSelections[c] = IntVar(value=0) Checkbutton(self.frameChannels, text=c, variable=self.channelSelections[c]).grid(row=row, column=column, sticky=NW) row += 1 counter = len(self.frameDataObjects.grid_slaves()) + 1 Radiobutton(self.frameDataObjects, text=self.FileObjectNames[-1], indicatoron=0, variable=self.intSettings["DataObject"], command=self.selectDataObject, value=counter).grid(row=counter, column=0, sticky=N+E+W) def selectDataObject(self): for child in self.frameGroups.grid_slaves(): child.grid_remove() del child self.intSettings["Group"].set(1) row = 0 column = 0 for i, g in enumerate(self.FileObjects[self.intSettings["DataObject"].get()-1].groups): if i % 12 == 0: row = 0 column += 1 Radiobutton(self.frameGroups, text=g, indicatoron=0, width=5, variable=self.intSettings["Group"], command=self.populateChannelList, value=i+1).grid(row=row, column=column, sticky=NW) row += 1 g = self.FileObjects[self.intSettings["DataObject"].get()-1].groups[self.intSettings["Group"].get() - 1] for child in self.frameChannels.grid_slaves(): child.grid_remove() del child row = 0 column = 0 self.channelSelections = {} for c in self.FileObjects[self.intSettings["DataObject"].get()-1].time[g].keys(): if i % 12 == 0: row = 0 column += 1 self.channelSelections[c] = IntVar(value=0) Checkbutton(self.frameChannels, text=c, variable=self.channelSelections[c]).grid(row=row, column=column, sticky=NW) row += 1 def removeDataObject(self): if tkMessageBox.askyesno(message="Really remove the selected data?"): del self.FileObjects[self.intSettings["DataObject"].get()-1] del self.FileObjectNames[self.intSettings["DataObject"].get()-1] for child in self.frameDataObjects.grid_slaves(): child.grid_remove() del child for i, o in enumerate(self.FileObjects): Radiobutton(self.frameDataObjects, text=self.FileObjectNames[i], indicatoron=0, variable=self.intSettings["DataObject"], command=self.selectDataObject, value=i+1).grid(row=i, column=0, sticky=N+E+W) if len(self.FileObjects) > 0: self.intSettings["DataObject"].set(1) else: for child in self.frameGroups.grid_slaves(): child.grid_remove() del child for child in self.frameChannels.grid_slaves(): child.grid_remove() del child def makePlot(self, group, keys): f = Figure() self.axes = [] if type(keys) is list: n = len(keys) for i, k in enumerate(keys): if i == 0: self.axes.append(f.add_subplot(n, 1, i + 1)) else: self.axes.append(f.add_subplot(n, 1, i + 1, sharex=self.axes[0])) self.axes[i].plot(self.FileObjects[self.intSettings["DataObject"].get()-1].time[group][k], self.FileObjects[self.intSettings["DataObject"].get()-1].data[group][k]) if self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses and k == "Fz, N": try: self.axes[i].axvline(x=self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses[group][1][0], color='r') self.axes[i].axvline(x=self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses[group][1][1], color='g') except: pass self.axes[i].set_ylabel(k) else: self.axes.append(f.add_subplot(1,1,1)) self.axes[0].plot(self.FileObjects[self.intSettings["DataObject"].get()-1].time[group][keys], self.FileObjects[self.intSettings["DataObject"].get()-1].data[group][keys]) if self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses and k == "Fz, N": self.axes[i].axvline(l=self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses[group][1][0], color='r') self.axes[i].axvline(l=self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses[group][1][1], color='g') self.axes[0].set_ylabel(keys) self.axes[-1].set_xlabel("Time (s)") canvas_frame = Frame(self.tab1) canvas_frame.grid(row=0, column=2, rowspan=4, sticky=N+W+E+S) canvas = FigureCanvasTkAgg(f, master=canvas_frame) canvas.draw() canvas.get_tk_widget().grid(row=0, column=0, padx=1, pady=1, sticky=N+W+E+S) toolbar_frame = Frame(self.tab1) toolbar_frame.grid(row=4, column=2, sticky=NW) toolbar = NavigationToolbar2TkAgg(canvas, toolbar_frame) toolbar.update() Button(self.tab1, text="Crop", command=self.cropData).grid( row=4, column=2, sticky=NE) def findThicknesses(self): self.FieldVariables["Thicknesses"] = [] for i, g in enumerate(self.FileObjects[self.intSettings["DataObject"].get()-1].groups): self.FileObjects[self.intSettings["DataObject"].get()-1].getThicknessMach1(g) self.FieldVariables["Thicknesses"].append(self.FileObjects[self.intSettings["DataObject"].get()-1].thicknesses[g][0]) self.populateFieldVariableList() def cropData(self): group = self.FileObjects[self.intSettings["DataObject"].get()-1].groups[self.intSettings["Group"].get() - 1] (start, end) = self.axes[0].xaxis.get_view_interval() for c in self.channelSelections.keys(): if self.channelSelections[c].get(): self.FileObjects[self.intSettings["DataObject"].get()-1].windowData(group, c, start, end) self.populateChannelList() def populateChannelList(self): g = self.FileObjects[self.intSettings["DataObject"].get()-1].groups[self.intSettings["Group"].get() - 1] self.channelSelections = {} for child in self.frameChannels.grid_slaves(): child.grid_remove() del child row = 0 column = 0 for i, c in enumerate(self.FileObjects[self.intSettings["DataObject"].get()-1].time[g].keys()): if i % 12 == 0: row = 0 column += 1 self.channelSelections[c] = IntVar(value=0) Checkbutton(self.frameChannels, text=c, variable=self.channelSelections[c]).grid(row=row, column=column, sticky=NW) row += 1 def plotChannels(self): keys = [] for c in self.channelSelections.keys(): if self.channelSelections[c].get(): keys.append(c) self.makePlot( self.FileObjects[self.intSettings["DataObject"].get()-1].groups[self.intSettings["Group"].get() - 1], keys) def applyMovingAvg(self): group = self.FileObjects[self.intSettings["DataObject"].get()-1].groups[ self.intSettings["Group"].get() - 1] for c in self.channelSelections.keys(): if self.channelSelections[c].get(): self.FileObjects[self.intSettings["DataObject"].get()-1].movingAverage( group, c, win=self.windowSize.get()) self.populateChannelList() def saveFile(self): group = self.FileObjects[self.intSettings["DataObject"].get()-1].groups[self.intSettings["Group"].get() - 1] for c in self.channelSelections.keys(): if self.channelSelections[c].get(): fid = open(os.path.abspath(string.replace( self.filename, ".tdms", "_{:s}_{:s}.pkl".format(group, c))), "wb") pickle.dump((self.FileObjects[self.intSettings["DataObject"].get()-1].time[group][c], self.FileObjects[self.intSettings["DataObject"].get()-1].data[group][c]), fid, 2) fid.close() def saveCSV(self): group = self.FileObjects[self.intSettings["DataObject"].get()-1].groups[self.intSettings["Group"].get() - 1] for c in self.channelSelections.keys(): if self.channelSelections[c].get(): if self.filename.lower().endswith(".tdms"): oname = string.replace(self.filename, ".tdms", "_{:s}_{:s}.csv".format(group, c)) oname = string.replace(oname, " ", "_") fid = open(os.path.abspath(oname), "wt") elif self.filename.lower().endswith(".txt"): oname = string.replace(self.filename, ".txt", "_{:s}_{:s}.csv".format(group, c)) oname = string.replace(oname, " ", "_") fid = open(os.path.abspath(oname), "wt") fid.write("Time, {:s}\n".format(c)) for (t, v) in zip( self.FileObjects[self.intSettings["DataObject"].get()-1].time[group][c], self.FileObjects[self.intSettings["DataObject"].get()-1].data[group][c]): fid.write("{:12.6f}, {:12.6f}\n".format(t, v)) fid.close() def loadImage(self): self.imagefile = tkFileDialog.askopenfilename( parent=root, initialdir=os.getcwd(), filetypes=[('image files', '.jpg .jpeg .png .tif .tiff')], title="Select a Image.") if not self.imagefile: print("A file was not selected") return self.image = imread(self.imagefile) self.cropimage=False self.plotImage() def loadMachMap(self): self.mapfile = tkFileDialog.askopenfilename( parent=root, initialdir=os.getcwd(), filetypes=[('Mach-1 map files', '.map')], title="Select the Mach-1 map file") if not self.mapfile: print("A file was not selected") return self.FileObjects[self.intSettings["DataObject"].get()-1].readMach1PositionMap(self.mapfile) self.maskFromMap() self.getTestLocations() def maskFromMap(self): ind = self.intSettings["DataObject"].get()-1 self.polygons = [] for p in self.FileObjects[ind].MachPositions["SubSurfaceID"].unique(): points = self.FileObjects[ind].MachPositions.query('(SubSurfaceID == "{:s}") & (PointType == 1)'.format(p))[["PixelX", "PixelY"]] points = np.array(points) points = np.vstack((points, points[0,:])) self.polygons.append(points) self.UpdateMask() def getTestLocations(self): ind = self.intSettings["DataObject"].get()-1 self.TestLocations = np.array(self.FileObjects[ind].MachPositions.query("(PointType == 0)")[["PixelX", "PixelY"]], dtype=float) def cropImage(self): self.points = [] self.polygons = [] self.image_canvas.get_tk_widget().bind("<Button-1>", self.XY_handler) self.image_canvas.get_tk_widget().bind("<Button-3>", self.nextPolygon) self.image_canvas.get_tk_widget().bind("<Return>", self.UpdateMask) #self.image_canvas.get_tk_widget().grid(row=0, column=0, padx=1, pady=1, sticky=N+E+W+S) self.image_canvas.draw() def XY_handler(self, aHandledEVENT): self.points.append((aHandledEVENT.x*self.screen2index, aHandledEVENT.y*self.screen2index)) if len(self.points) > 1: self.addLine() def addLine(self): codes = [Path.MOVETO] + [Path.LINETO] * (len(self.points) - 1) path = Path(tuple(self.points), codes) patch = patches.PathPatch(path, lw=2) self.image_ax.add_patch(patch) self.image_canvas.draw() def nextPolygon(self, aHandledEVENT): tmp = np.copy(self.points) tmp = np.vstack((tmp, tmp[0,:])) self.polygons.append(tmp) self.points = [] def UpdateMask(self, aHandledEVENT=None): img = Image.new('L', (self.image.shape[1], self.image.shape[0]), 1) drw = ImageDraw.Draw(img, 'L') for p in self.polygons: p = p.ravel() drw.polygon(tuple(p), outline=1, fill=0) self.maskimage = np.array(img, dtype=bool) self.cropimage = True if aHandledEVENT is None: self.image_canvas.get_tk_widget().unbind("<Button-1>") self.image_canvas.get_tk_widget().unbind("<Button-3>") self.image_canvas.get_tk_widget().unbind("<Return>") self.plotImage() def clearMask(self): self.cropimage = False self.plotImage() def populateFieldVariableList(self): for child in self.frameFieldVariables.grid_slaves(): child.grid_remove() del child for i, (k, v) in enumerate(self.FieldVariables.items()): Radiobutton(self.frameFieldVariables, text=k, indicatoron=0, variable=self.intSettings["FieldVariables"], value=i+1).grid(row=i, column=0, sticky=N+E+W) try: self.buttonPlotOverlay except: self.buttonPlotOverlay = Button(self.frameImageButtons, text="Plot Selected", command=self.overlayData) self.buttonPlotOverlay.grid(row=4, column=0, sticky=N+W+E) def plotImage(self, data=None): try: self.image except: return self.imageFrame = Frame(self.tab2) self.image_width_inches = 6.0 self.imageFrame.grid(row=0, column=1, padx=1, pady=1, sticky=N+E+W+S) self.image_aspect = float(self.image.shape[1])/float(self.image.shape[0]) self.image_dpi = 96 self.screen2index = self.image.shape[1] / (self.image_width_inches * self.image_dpi) self.image_fig = Figure((self.image_width_inches, self.image_width_inches/self.image_aspect), dpi=self.image_dpi, frameon=False) self.image_ax = self.image_fig.add_axes([0.0, 0.0, 1.0, 1.0,]) self.image_ax.imshow(self.image) self.image_ax.get_xaxis().set_visible(False) self.image_ax.get_yaxis().set_visible(False) self.image_ax.grid(False) self.image_canvas = FigureCanvasTkAgg(self.image_fig, master=self.imageFrame) self.image_canvas.get_tk_widget().grid(row=0, column=0, padx=1, pady=1, sticky=N+E+W+S) self.image_canvas.get_tk_widget().config(width=self.image_width_inches*self.image_dpi, height=self.image_width_inches*self.image_dpi/self.image_aspect) self.image_toolbar_frame = Frame(self.tab2) self.image_toolbar_frame.grid(row=1, column=1, sticky=NW) self.image_toolbar = NavigationToolbar2TkAgg(self.image_canvas, self.image_toolbar_frame) self.image_toolbar.update() self.image_canvas.draw() def overlayData(self): self.image_ax.hold(True) grid_size = self.image.shape[0:2] gridx, gridy = np.mgrid[0:grid_size[0], 0:grid_size[1]] key = self.FieldVariables.keys()[self.intSettings["FieldVariables"].get() - 1] data = np.array(self.FieldVariables[key][-self.TestLocations.shape[0]:]) m, se = np.mean(data), sem(data) h = se * t.ppf(0.975, data.size - 1) #rbf = Rbf(self.TestLocations[:,0], self.TestLocations[:,1], data, epsilon=2) #gridz = rbf(gridx, gridy) gridz = griddata(self.TestLocations[:, [1, 0]], data, (gridx, gridy), 'nearest') if self.cropimage: gridz = ma.masked_where(self.maskimage, gridz, copy=False) #gridz = ma.masked_where(np.abs((gridz - med))/mdev > 7.0, gridz, copy=False) cmap = sns.cubehelix_palette(light=1, as_cmap=True) im = self.image_ax.imshow(gridz, cmap=cmap, alpha=0.75, norm=colors.Normalize(vmin=data.min(), vmax=m+h, clip=False)) self.image_fig.colorbar(im, shrink=0.75) self.image_ax.scatter(self.TestLocations[:,0], self.TestLocations[:,1]) text = [str(i+1) for i in xrange(self.TestLocations.shape[0])] for i, tt in enumerate(text): self.image_ax.text(self.TestLocations[i,0] + 10, self.TestLocations[i,1] - 10, tt, color="orange", size=8) self.image_canvas.draw()
class MainApplication(Tk): def __init__(self, network_discoverer): Tk.__init__(self) self.winfo_toplevel().title("fHTTP") self.title_font = tkfont.Font(family='Helvetica', size=14, weight='bold', slant='italic') self.h2_font = tkfont.Font(family='Helvetica', size=12, weight='bold') self.h3_font = tkfont.Font(family='Helvetica', size=11, weight='bold') self.network_discoverer = network_discoverer self.own_mac_address = network_discoverer.get_own_mac_address() self.own_ip_address = network_discoverer.get_own_ip_address() self.ip_to_mac = None self.ip_to_mac_record = None self.configure(background='darkgrey') self.is_spoofing = self.is_extracting = self.is_filtering = False self.verbose_mode = False # verbose mode on/off for output frame self.victims = None self.target = None width = int(self.winfo_screenwidth() * 0.5) height = int(self.winfo_screenheight() * 0.8) x_start = int(self.winfo_screenwidth() * 0.25) y_start = int(self.winfo_screenheight() * 0.1) self.geometry('%dx%d+%d+%d' % (width, height, x_start, y_start)) self.resizable(0, 0) # do not feel like dealing with resizable frames self.conf_menu_bar() # configure menu-bar img_icon = PhotoImage(file=media_dir + os.path.sep + 'fhttp_logo.ico') self.tk.call('wm', 'iconphoto', self._w, img_icon) for row in range(0, 100): self.rowconfigure(row, weight=1) self.columnconfigure(row, weight=1) # notebook configuration (tabs) style = Style() style.theme_settings( "default", { "TNotebook": { "configure": { "tabmargins": [0, 0, 0, 0] } }, "TNotebook.Tab": { "configure": { "padding": [8, 1, 8, 1] } } }) self.notebook = Notebook(self) self.notebook.grid(row=1, column=0, columnspan=100, rowspan=10, sticky='nesw', padx=5) # output frame configuration self.output = OutputFrame(parent=self) self.output.grid(row=13, column=0, columnspan=100, rowspan=85, sticky='nesw', padx=5) # notebook frames self.tabs = {} self.tab_mapping = OrderedDict([ (StartFrame, 'Start'), (LocalNetworkScanFrame, 'Local Network Scan'), (ARPSpoofFrame, 'ARP Spoofing'), (InjectorExtractorFrame, 'Injection and Extraction') ]) for tab in self.tab_mapping.keys(): tab_frame_name = self.tab_mapping[tab] frame = tab(parent=self.notebook, controller=self) self.notebook.add(frame, text=tab_frame_name) self.tabs[tab.__name__] = frame self.notebook.tab(self.notebook.index( self.tabs['InjectorExtractorFrame']), state=DISABLED) self.notebook.tab(self.notebook.index(self.tabs['ARPSpoofFrame']), state=DISABLED) tkMessageBox.showinfo( "fHTTP", "\n\n\nWelcome to fhttp\n\n" "We inherently trust no one, including each other\n\n\n".ljust( 500)) def conf_menu_bar(self): menu_bar = Menu(self) # help menu help_menu = Menu(menu_bar, tearoff=0) help_menu.add_command(label='About', command=self.display_about) help_menu.add_command(label='Support and Documentation', command=self.display_support_doc) # help_menu.add_separator() menu_bar.add_cascade(label='Help', menu=help_menu) menu_bar.add_command(label='Exit', command=self.quit) self.config(menu=menu_bar) def clean_output_and_attack_frame(self): self.output = OutputFrame(parent=self) self.output.grid(row=13, column=0, columnspan=100, rowspan=85, sticky='nesw', padx=5) @staticmethod def display_about(): tkMessageBox.showinfo( "About", "fhttp is an application which is capable of exploiting vulnerabilities " "such as ARP cache poisoning. The (man-in-the-middle) positions that are acquired " "through the exploitation of these vulnerabilities are then used for things such as " "packet-sniffing, the `theft' of (insecure) cookies and img-tag-injection\n\n" "Abdel K. Bokharouss and Adriaan Knapen \n") @staticmethod def display_support_doc(): webbrowser.open('https://github.com/akbokha/fhttp') def show_frame(self, page_name, select=True, update=False): frame = self.tabs[page_name] if update: try: frame.update() except AttributeError: pass if select: self.notebook.select(self.notebook.index(frame)) def scan_and_update(self): self.ip_to_mac_record = self.network_discoverer.get_ip_to_mac_mapping( update=True) self.ip_to_mac = self.ip_to_mac_record.get_all()
class DataExploreGUI(Frame): def __init__(self, master): Frame.__init__(self, master) self.nb = Notebook(self) self.tab1 = Frame(self.nb) self.tab2 = Frame(self.nb) self.tab3 = Frame(self.nb) self.nb.add(self.tab1, text='Raw Data') self.nb.add(self.tab2, text='Quality metrics') self.nb.add(self.tab3, text='Friction tests') self.nb.grid(row=0, column=0, sticky=NW) self.intSettings = {'Group': IntVar(value=0)} self.intSettings2 = {'Group': IntVar(value=0)} self.intSettings3 = {'Group': IntVar(value=0)} self.intSettings4 = {'Group': IntVar(value=0)} # Tab1 buttons self.buttonLoadFile = Button(self.tab1, text="Load Data File", command=self.loadFile) self.buttonLoadFile.grid(row=0, column=0, padx=5, pady=5, sticky=W + E) self.buttonSavePlot = Button(self.tab1, text="Save Plot as SVG", command=self.savePlotFrame1) self.buttonSavePlot.grid(row=0, column=1, padx=5, pady=5, sticky=W + E) self.frameGroups = LabelFrame(self.tab1, text="Group Selection") self.frameGroups.grid(row=1, column=0, padx=5, pady=5, sticky=N + E + W + S) Label(self.frameGroups, text="").pack(anchor=W) self.frameChannels = LabelFrame(self.tab1, text="Channel Selection") self.frameChannels.grid(row=1, column=1, padx=5, pady=5, sticky=N + E + W + S) Label(self.frameChannels, text="").pack(anchor=W) self.buttonPlot = Button(self.tab1, text="Plot Selected Channels", command=self.plotChannels) self.buttonPlot.grid(row=2, column=0, padx=5, pady=5, sticky=W + E) self.grid() self.fg_sz = (12, 6) self.fig = plt.Figure(figsize=self.fg_sz) self.canvas = FigureCanvasTkAgg(self.fig, master=self.tab1) self.canvas.get_tk_widget().grid(column=2, row=1) # Tab2 button self.frameGroups3 = LabelFrame(self.tab2, text="Stress Relaxation") self.frameGroups3.grid(row=1, column=0, padx=5, pady=5, sticky=N + E + W + S) Label(self.frameGroups3, text="").pack(anchor=W) self.frameGroups4 = LabelFrame(self.tab2, text="X-Y alignment") self.frameGroups4.grid(row=1, column=1, padx=5, pady=5, sticky=N + E + W + S) Label(self.frameGroups4, text="").pack(anchor=W) self.fig2 = plt.Figure(figsize=self.fg_sz) self.canvas2 = FigureCanvasTkAgg(self.fig2, master=self.tab2) self.canvas2.get_tk_widget().grid(column=2, row=1) self.buttonSavePlot2 = Button(self.tab2, text="Save Plot as SVG", command=self.savePlotFrame2) self.buttonSavePlot2.grid(row=0, column=0, padx=5, pady=5, sticky=W + E) # Tab3 button self.buttonAnalyze = Button(self.tab3, text="Plot friction line", command=self.plotMu) self.buttonAnalyze.grid(row=0, column=0, padx=5, pady=5, sticky=W + E) self.frameGroups2 = LabelFrame(self.tab3, text="Friction Run") self.frameGroups2.grid(row=1, column=0, padx=5, pady=5, sticky=N + E + W + S) Label(self.frameGroups2, text="").pack(anchor=W) def loadFile(self): # read file into data object self.filename = get_filename() file_info, repaired = decompose_file_name(self.filename) if repaired: self.data = cPickle.load(open(self.filename, "rb")) else: self.data = parse_file(self.filename) self.data_obj = FrictionData(self.data, file_info) if self.filename: for child in self.frameGroups.pack_slaves(): child.destroy() count = 1 count2 = 1 self.blockmap = {} self.blockmap2 = {} for i, g in enumerate(self.data.keys()): tag = self.data[g]['tag'][0] Radiobutton(self.frameGroups, text='blk' + g[-1] + ': ' + tag[1:-1], indicatoron=0, width=20, variable=self.intSettings["Group"], command=self.populateChannelList, value=i).pack(anchor=W) if tag == '<Scripts>': # raw data curves Radiobutton(self.frameGroups2, text='run' + str(count), indicatoron=0, width=20, variable=self.intSettings2["Group"], command=self.plotCurves, value=i).pack(anchor=W) self.blockmap[g] = count - 1 # x-y alignment Radiobutton(self.frameGroups4, text='run' + str(count), indicatoron=0, width=20, variable=self.intSettings4["Group"], command=self.plotAlignment, value=i).pack(anchor=W) self.blockmap[g] = count - 1 count += 1 elif tag == '<Stress Relaxation>': Radiobutton(self.frameGroups3, text='Stress Relax' + str(count), indicatoron=0, width=20, variable=self.intSettings3["Group"], command=self.plotProny, value=i).pack(anchor=W) self.blockmap2[g] = count2 - 1 count2 += 1 self.channelSelections = {} for c in self.data['block0']['data'].keys(): if c == 'time': continue self.channelSelections[c] = IntVar(value=0) Checkbutton(self.frameChannels, text=c, variable=self.channelSelections[c]).pack(anchor=W) def populateChannelList(self): g = self.data.keys()[self.intSettings['Group'].get()] self.channelSelections = {} for child in self.frameChannels.pack_slaves(): child.destroy() for c in self.data[g]['data'].keys(): if c == 'time': continue self.channelSelections[c] = IntVar(value=0) Checkbutton(self.frameChannels, text=c, variable=self.channelSelections[c]).pack(anchor=W) def plotChannels(self): self.fig = plt.Figure(figsize=self.fg_sz) self.canvas = FigureCanvasTkAgg(self.fig, master=self.tab1) self.canvas.get_tk_widget().grid(column=2, row=1) keys = [] for c in self.channelSelections.keys(): if self.channelSelections[c].get(): keys.append(c) block = 'block' + str(self.intSettings["Group"].get()) for i, k in enumerate(keys): self.ax = self.fig.add_subplot(len(keys), 1, i+1, ylabel=k) t = self.data[block]['data']['time'] x = self.data[block]['data'][k][:, 0] y = self.data[block]['data'][k][:, 1] z = self.data[block]['data'][k][:, 2] self.ax.hold(True) self.ax.plot(t, x, label='x') self.ax.plot(t, y, label='y') self.ax.plot(t, z, label='z') legend = self.ax.legend(loc='upper right', prop={'size': 3}, shadow=True) for label in legend.get_texts(): label.set_fontsize('small') plt.show() def savePlotFrame1(self): pltsavename = tkFileDialog.asksaveasfilename( parent=root, initialdir=os.getcwd(), title="Save As" ) # check input for errors pltsavename = '' for i in xrange(len(pltsavenamein)): if pltsavenamein[i] == '.': pltsavename = pltsavename + '_' else: pltsavename = pltsavename + pltsavenamein[i] pltsavename = pltsavename + '.svg' if pltsavename: self.fig.savefig(pltsavename, format='svg', transparent=True) def savePlotFrame2(self): pltsavename = tkFileDialog.asksaveasfilename( parent=root, initialdir=os.getcwd(), title="Save As" ) # check input for errors pltsavename = '' for i in xrange(len(pltsavenamein)): if pltsavenamein[i] == '.': pltsavename = pltsavename + '_' else: pltsavename = pltsavename + pltsavenamein[i] pltsavename = pltsavename + '.svg' if pltsavename: self.fig2.savefig(pltsavename, format='svg', transparent=True) def plotMu(self): self.data_obj.show_friction_line() def plotAlignment(self): self.fig2 = plt.Figure(figsize=self.fg_sz) self.canvas2 = FigureCanvasTkAgg(self.fig2, master=self.tab2) self.canvas2.get_tk_widget().grid(column=2, row=1) g = 'block' + str(self.intSettings4["Group"].get()) r = float(self.blockmap[g]) df = self.data_obj.test_summary_frame() x = df[df['load_index'] == r]['alig_x'].values y = df[df['load_index'] == r]['alig_y'].values for i in xrange(2): self.ax2 = self.fig2.add_subplot(1, 2, i+1, ylabel='y position (mm)', xlabel='x position (mm)') self.ax2.plot(x[i], y[i], "or") plt.show() def plotProny(self): self.fig2 = plt.Figure(figsize=self.fg_sz) self.canvas2 = FigureCanvasTkAgg(self.fig2, master=self.tab2) self.canvas2.get_tk_widget().grid(column=2, row=1) g = 'block' + str(self.intSettings3["Group"].get()) r = int(self.blockmap2[g]) df = self.data_obj.test_summary_frame() F = self.data_obj.Fz_all[r] E = df.loc[r]['E'] p = df.loc[r]['p'] tau = df.loc[r]['tau'] e1 = self.data_obj.e1_all[r] t1 = self.data_obj.t1_all[r] t = self.data_obj.t_all[r] y = prony_hold(t, E, p, tau, e1, t1) self.ax3 = self.fig2.add_subplot(1, 1, 1, xlabel='time (s)', ylabel='Fz (N)') self.ax3.hold(True) self.ax3.plot(t, F, 'o') self.ax3.plot(t, y) plt.show() def plotCurves(self): g = 'block' + str(self.intSettings2["Group"].get()) r = float(self.blockmap[g]) self.data_obj.show_friction_curve(run=r)
class GoalTrak(Tk): def __init__(self,parent): Tk.__init__(self,parent) self.parent = parent self.initialize() def initialize(self): self.grid() self.entryVariable = StringVar() #Student entry box self.entry = Entry(self,textvariable=self.entryVariable) self.entry.grid(column=0,row=1,sticky='EW') self.entry.bind("<Return>", self.onPressEnter) self.entryVariable.set(u"Enter new student here") #Simple buttons# self.quitButton = Button(self,text=u"Quit", command=self.onQuitClick) #Quit button self.quitButton.grid(row = 14, sticky='SE') self.removeButton = Button(self, text=u"Remove student", command=self.onRemoveClick) #Remove student button self.removeButton.grid(column=0,row=6, sticky = 'W') self.optionMenu = Button(self, text=u"About", command=self.onAboutClick) #About button self.optionMenu.grid(row = 13, sticky='SE') self.infoUpdate = Button(self, text=u"Update Student Info", command=self.onInfoUpdateClick) #Info updater self.infoUpdate.grid(column=0, row=4, sticky = 'W') self.showInformation = Button(self, text = u"Show Information", command=self.onShowInformationClick) self.showInformation.grid(column=0, row=5, sticky = 'W') self.labelVariable = StringVar() #Banner self.labelVariable.set(u"Welcome to GoalTrak") label = Label(self,textvariable=self.labelVariable, \ anchor="w",fg="white",bg="navy") label.grid(column=0,row=0,sticky='EW') self.StudentListDisplay = Listbox(self) #Student List self.StudentListDisplay.grid(row=2,column=0,columnspan=2,sticky='W') for student in student_list: self.StudentListDisplay.insert(END, student) self.tab = Notebook(width=200, height=200) #Notebook self.tab.pressed_index = None ###Notebook### self.studentInfoDisplayFrame = Frame(self.tab) ####Info display tab### self.studentNameLabelVar = StringVar() #Student name label self.studentNameLabelVar.set('Click "show information"') studentNameLabel = Label(self.studentInfoDisplayFrame, textvariable=self.studentNameLabelVar, fg='black', bg='white') studentNameLabel.grid(column=0,row=0,sticky='NW') self.studentClassLabelVar = StringVar() #Student class label self.studentClassLabelVar.set('') studentClassLabel = Label(self.studentInfoDisplayFrame, textvariable=self.studentClassLabelVar, fg='black', bg='white') studentClassLabel.grid(column=0,row=1,sticky='W') self.studentGoal1LabelVar = StringVar() #Student goal1 label self.studentGoal1LabelVar.set('') studentGoal1Label = Label(self.studentInfoDisplayFrame, textvariable=self.studentGoal1LabelVar, fg='black', bg='white') studentGoal1Label.grid(column=0,row=2,sticky='W') otherWidget = Canvas(self.tab, width=300, height=300) #Empty widget for fun! self.tab.add(self.studentInfoDisplayFrame, text='Student Info') #Labels tabs self.tab.add(otherWidget, text='Other Widget') self.tab.grid(column = 0, row = 7, rowspan = 5, sticky = 'EW') self.grid_columnconfigure(0,weight=1) #This makes it so the window is resizable self.resizable(True,True) self.update() self.geometry(self.geometry()) self.entry.focus_set() self.entry.selection_range(0, END) def onAboutClick(self): #About message tkMessageBox.showinfo(title=u'About', message=u'GoalTrak v. Alpha V by Eli Dinkelspiel') def student_list_updater(self, studentlist): self.StudentListDisplay.delete(0, END) for student in studentlist: self.StudentListDisplay.insert(END, student)#Refreshes student listbox def onQuitClick(self): result = tkMessageBox.askokcancel(title='GoalTrak', message='Are you sure you want to quit GoalTrak?') if result == True: GoalTrak.destroy(self) #Quit button def onRemoveClick(self): index = self.StudentListDisplay.curselection() index = int(index[0]) result = tkMessageBox.askokcancel(title='Are you sure?', \ message='Are you sure you want to remove %s? This cannot be undone and will remove all associated data.' \ % (student_list[index])) if result == True: del student_list[index] self.student_list_updater(student_list) file_saver(student_list, 'GoalTrak/StudentList')#Remove student button def onPressEnter(self, event): #Enters students into save file hold = self.entryVariable.get() hold = str(hold) with open('GoalTrak/StudentList', 'rb') as file: #This appends students to the already existing document of students if (hold) not in student_list: student_list.append(hold) file_saver(student_list, 'GoalTrak/StudentList') self.labelVariable.set(self.entryVariable.get() + " added" ) self.student_list_updater(student_list) else: #If student is already in list, aborts self.labelVariable.set( self.entryVariable.get() + " is already in list" ) file.close() self.entry.focus_set() self.entry.selection_range(0, END)#Add student with <enter> def onShowInformationClick(self): #Refreshes student information display studentNameVar = student_list[int(self.StudentListDisplay.curselection()[0])] self.studentNameLabelVar.set(studentNameVar) current_student = file_loader('GoalTrak/StudentInformation' + studentNameVar) #Each one of these try/except pairs makes the various User() attributes visible, if they exist. DO NOT BUNDLE AS ONE try: self.studentClassLabelVar.set(current_student.usrClass) except (AttributeError): self.studentClassLabelVar.set(u'No set class') try: self.studentGoal1LabelVar.set(current_student.goals['goal1']) except (AttributeError): self.studentGoal1LabelVar.set(u'Goal 1 not set') def onInfoUpdateClick(self): #User Information Updater index = self.StudentListDisplay.curselection() index = int(index[0]) student_name = student_list[index] def onSaveQuitClick(): #Stores the data classHold = str(self.UserInformationUpdater.classEntry.get()) goal1Hold = str(self.UserInformationUpdater.goal1Entry.get()) current_student = file_loader('GoalTrak/StudentInformation' + student_name) for student in student_information: #I probably want to get rid of this for loop but I'm afraid to tinker with my code :( if student == student_name: try: current_student.usrClass = classHold current_student.goals['goal1'] = goal1Hold file_saver(current_student, 'GoalTrak/StudentInformation' + student_name) except (AttributeError): print 'New file being created' file_saver(User(student_name, classHold, {'goal1':goal1Hold}), 'GoalTrak/StudentInformation' + student_name) current_student = file_loader('GoalTrak/StudentInformation' + student_name) self.UserInformationUpdater.destroy() try: #Gives new students a file object current_student = file_loader('GoalTrak/StudentInformation' + student_name) except (IOError): file_saver('GoalTrak/StudentInformation' + student_name) self.UserInformationUpdater = Toplevel() self.UserInformationUpdater.grid() self.UserInformationUpdater.title("Update Information - %s" % (student_name)) self.UserInformationUpdater.infolabel = Label(self.UserInformationUpdater, \ text = (u"User Information - %s" % (student_name)), anchor="w", fg="white", bg="navy") self.UserInformationUpdater.infolabel.grid(column=0,row=0,columnspan=2,sticky='EW') #Visual stuff for the updater self.UserInformationUpdater.classVar = StringVar() self.UserInformationUpdater.classEntry = Entry(self.UserInformationUpdater, textvariable=self.UserInformationUpdater.classVar) self.UserInformationUpdater.classEntry.grid(column=0,row=1,sticky='EW') try: self.UserInformationUpdater.classVar.set(str(current_student.usrClass)) except (AttributeError): self.UserInformationUpdater.classVar.set(u"Enter student's class here") self.UserInformationUpdater.goal1Var = StringVar() self.UserInformationUpdater.goal1Entry = Entry(self.UserInformationUpdater, textvariable=self.UserInformationUpdater.goal1Var) self.UserInformationUpdater.goal1Entry.grid(column=0,row=2,sticky='EW') try: self.UserInformationUpdater.goal1Var.set(str(current_student.goals['goal1'])) except (AttributeError): self.UserInformationUpdater.goal1Var.set(u"Enter goal 1 here:") self.UIU_quitButton = Button(self.UserInformationUpdater, text=u"Save and Quit", command=onSaveQuitClick) #Save & Quit button self.UIU_quitButton.grid(column=1, row=2) self.UserInformationUpdater.grid_columnconfigure(0,weight=1) #This makes it so the window is resizable self.UserInformationUpdater.resizable(True,True) self.UserInformationUpdater.update() self.UserInformationUpdater.geometry(self.UserInformationUpdater.geometry())
class GUI(tk.Tk): """ Start graphical interface for client. Args: client_queue_cmd: queue to send commands client_queue_log: queue to get logging info client_queue_telem: queue to get telemetry data beam_gap_queue: queue to retrieve beam gap data (any queue will do, this is handled via the gui, through the telemetry queue) @depricated server_ip: server IP address for rtp stream access """ def __init__(self, client_queue_cmd, client_queue_log, client_queue_telem, beam_gap_queue, destroyEvent, server_ip, **kwargs): tk.Tk.__init__(self, **kwargs) self.client_queue_cmd = client_queue_cmd self.client_queue_log = client_queue_log self.client_queue_telem = client_queue_telem self.beam_gap_queue = beam_gap_queue self.server_ip = server_ip self.destroyEvent = destroyEvent def init_ui(self): #make resizable self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.notebook = Notebook(self) # define mainapp instance -- also manages above telemetry thread self.mainApplication = MainApplication(self, self.client_queue_cmd, self.client_queue_log, self.client_queue_telem, self.beam_gap_queue, self.destroyEvent, self.server_ip) self.notebook.add(self.mainApplication, text = "Main") # define telemetry widgets self.monitor = Monitor(self, VisualConstants.MARS_PRIMARY(1)) self.notebook.add(self.monitor, text = 'Monitor') self.notebook.grid(column = 0, row = 0, sticky = 'nsew') # menu -outside of notebook self.menu_ = TopMenu(self, '../gui/operations.json', self.client_queue_cmd, 'Commands') ### Add custom commands here self.menu_.add_menu_item('Reconnect to Cameras', self.mainApplication.start_streams, "View") self.menu_.add_menu_item('Left', self.mainApplication.focus_left, 'View/Camera Focus') self.menu_.add_menu_item('Center', self.mainApplication.focus_center, 'View/Camera Focus') self.menu_.add_menu_item('Right', self.mainApplication.focus_right, 'View/Camera Focus') self.menu_.add_menu_item('IBeam Display', self.beamGapGraph, 'View/Windows') self.menu_.add_menu_item('Toggle FOD Enabled', self.mainApplication.toggle_fod, 'View/Object Detection') self.menu_.add_menu_item('Set Ideal Images', self.mainApplication.define_ideal_images, 'View/Object Detection') ### self.menu_.finalize_menu_items() self.config(menu=self.menu_) # start all operations here so we don't cause a hissyfit between tkinter and threads self.mainApplication.start_streams() #define telemetryThread self.tthread = TelemetryThread([self.mainApplication.telemetry_w, self.monitor], self.client_queue_telem, self.beam_gap_queue) self.tthread.start() # title and icon self.wm_title('Hyperloop Imaging Team') #this is garbage, i hate tkinter #self.img = ImageTk.PhotoImage(file='rit_imaging_team.xbm') #self.tk.call('wm', 'iconphoto', self._w, self.img) #self.iconbitmap('@rit_imaging_team.xbm') #call destroyCallback on clicking X self.protocol('WM_DELETE_WINDOW', self.destroyCallback) #assign dimensions and locatin on screen width = 900 height = 500 x = (self.winfo_screenwidth() // 2) - (width // 2) y = (self.winfo_screenheight() // 2) - (height // 2) self.geometry('{}x{}+{}+{}'.format(width, height, x, y)) self.update() def killMars(self): ''' Sends the kill command to Mars ''' logger.debug('GUI Killing Mars...') self.client_queue_cmd.put('exit') def displayMarsDisconnected(self): tkMessageBox.showerror('Lost connection to Mars', 'The client has lossed connection to mars, closing application.') self.destroyClient() def destroyClient(self): logger.debug('GUI Killing Main App...') self.menu_.destroy() self.mainApplication.close_() logger.debug('GUI Killing Monitor app...') self.monitor.destroy() self.notebook.destroy() logger.debug('GUI Killing Self...') self.killTelemThread() logger.debug('GUI Dead') self.quit() self.destroy() def killTelemThread(self): """ Customized quit function to allow for safe closure of processes. """ logger.debug('GUI Killing Telemetry...') self.tthread.stop() if self.tthread.is_alive(): self.tthread.join() def destroyCallback(self): ''' Function called when the window handle Destory is clicked (the x) Opens up a small prompt asking if you wanna kill mars ''' logger.debug('GUI entering destroy callback...') result = tkMessageBox.askyesno('Leaving GUI, Should Mars be Disabled?', 'Leaving GUI, should Mars be Disabled?') if result: self.killMars() self.destroyClient() def beamGapGraph(self): ''' Function that launches the Beam Gap Widget that displays the current beam distances in readalbe form. ''' if getattr(self, 'top', False) == False: self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") else: if self.top['state'] != 'normal': self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") def start(self): ''' Starts the root window ''' self.init_ui() try: self.mainloop() except KeyboardInterrupt: self.destroyClient()
class GUI(tk.Tk): """ Start graphical interface for client. Args: client_queue_cmd: queue to send commands client_queue_log: queue to get logging info client_queue_telem: queue to get telemetry data beam_gap_queue: queue to retrieve beam gap data (any queue will do, this is handled via the gui, through the telemetry queue) @depricated server_ip: server IP address for rtp stream access """ def __init__(self, client_queue_cmd, client_queue_log, client_queue_telem, beam_gap_queue, destroyEvent, server_ip, **kwargs): tk.Tk.__init__(self, **kwargs) self.client_queue_cmd = client_queue_cmd self.client_queue_log = client_queue_log self.client_queue_telem = client_queue_telem self.beam_gap_queue = beam_gap_queue self.server_ip = server_ip self.destroyEvent = destroyEvent def init_ui(self): #make resizable self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.notebook = Notebook(self) # define mainapp instance -- also manages above telemetry thread self.mainApplication = MainApplication(self, self.client_queue_cmd, self.client_queue_log, self.client_queue_telem, self.beam_gap_queue, self.destroyEvent, self.server_ip) self.notebook.add(self.mainApplication, text="Main") # define telemetry widgets self.monitor = Monitor(self, VisualConstants.MARS_PRIMARY(1)) self.notebook.add(self.monitor, text='Monitor') self.notebook.grid(column=0, row=0, sticky='nsew') # menu -outside of notebook self.menu_ = TopMenu(self, '../gui/operations.json', self.client_queue_cmd, 'Commands') ### Add custom commands here self.menu_.add_menu_item('Reconnect to Cameras', self.mainApplication.start_streams, "View") self.menu_.add_menu_item('Left', self.mainApplication.focus_left, 'View/Camera Focus') self.menu_.add_menu_item('Center', self.mainApplication.focus_center, 'View/Camera Focus') self.menu_.add_menu_item('Right', self.mainApplication.focus_right, 'View/Camera Focus') self.menu_.add_menu_item('IBeam Display', self.beamGapGraph, 'View/Windows') self.menu_.add_menu_item('Toggle FOD Enabled', self.mainApplication.toggle_fod, 'View/Object Detection') self.menu_.add_menu_item('Set Ideal Images', self.mainApplication.define_ideal_images, 'View/Object Detection') ### self.menu_.finalize_menu_items() self.config(menu=self.menu_) # start all operations here so we don't cause a hissyfit between tkinter and threads self.mainApplication.start_streams() #define telemetryThread self.tthread = TelemetryThread( [self.mainApplication.telemetry_w, self.monitor], self.client_queue_telem, self.beam_gap_queue) self.tthread.start() # title and icon self.wm_title('Hyperloop Imaging Team') #this is garbage, i hate tkinter #self.img = ImageTk.PhotoImage(file='rit_imaging_team.xbm') #self.tk.call('wm', 'iconphoto', self._w, self.img) #self.iconbitmap('@rit_imaging_team.xbm') #call destroyCallback on clicking X self.protocol('WM_DELETE_WINDOW', self.destroyCallback) #assign dimensions and locatin on screen width = 900 height = 500 x = (self.winfo_screenwidth() // 2) - (width // 2) y = (self.winfo_screenheight() // 2) - (height // 2) self.geometry('{}x{}+{}+{}'.format(width, height, x, y)) self.update() def killMars(self): ''' Sends the kill command to Mars ''' logger.debug('GUI Killing Mars...') self.client_queue_cmd.put('exit') def displayMarsDisconnected(self): tkMessageBox.showerror( 'Lost connection to Mars', 'The client has lossed connection to mars, closing application.') self.destroyClient() def destroyClient(self): logger.debug('GUI Killing Main App...') self.menu_.destroy() self.mainApplication.close_() logger.debug('GUI Killing Monitor app...') self.monitor.destroy() self.notebook.destroy() logger.debug('GUI Killing Self...') self.killTelemThread() logger.debug('GUI Dead') self.quit() self.destroy() def killTelemThread(self): """ Customized quit function to allow for safe closure of processes. """ logger.debug('GUI Killing Telemetry...') self.tthread.stop() if self.tthread.is_alive(): self.tthread.join() def destroyCallback(self): ''' Function called when the window handle Destory is clicked (the x) Opens up a small prompt asking if you wanna kill mars ''' logger.debug('GUI entering destroy callback...') result = tkMessageBox.askyesno( 'Leaving GUI, Should Mars be Disabled?', 'Leaving GUI, should Mars be Disabled?') if result: self.killMars() self.destroyClient() def beamGapGraph(self): ''' Function that launches the Beam Gap Widget that displays the current beam distances in readalbe form. ''' if getattr(self, 'top', False) == False: self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") else: if self.top['state'] != 'normal': self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") def start(self): ''' Starts the root window ''' self.init_ui() try: self.mainloop() except KeyboardInterrupt: self.destroyClient()
def initialize(self): popup=self buttons_with_status=[] dim=self.dim self.opened_tabs=[] #popup.configure(background=bg) bg=popup.cget("background") panel=Frame(popup, padx=5, pady=5, height=2, bd=1, relief=SUNKEN) panel.grid(column=1,row=1,sticky=N+S) display_factor=grp_config.getfloat("Live", "LiveGobanRatio") screen_width = self.parent.winfo_screenwidth() screen_height = self.parent.winfo_screenheight() width=int(display_factor*screen_width) height=int(display_factor*screen_height) self.goban_size=min(width,height) notebook=Notebook(popup) self.notebook=notebook notebook.grid(column=2,row=1,rowspan=2,sticky=N+S+E+W) live_tab=Frame(notebook) live_tab.bind("<Visibility>",lambda event: self.refocus(live_tab)) toolbar=Frame(live_tab) toolbar.pack(fill=X) goban = Goban(dim,self.goban_size,master=live_tab,bg=bg,bd=0, borderwidth=0) goban.space=self.goban_size/(dim+1+1+1) goban.pack(fill=BOTH, expand=1) notebook.add(live_tab, text=_("Live game")) goban.bind("<Enter>",lambda e: self.set_status(_("<Ctrl+Q> to save the goban as an image."))) buttons_with_status.append(goban) plus_tab=Frame(notebook) notebook.add(plus_tab, text="+") plus_tab.bind("<Visibility>",self.new_goban) popup.grid_rowconfigure(1, weight=1) popup.grid_columnconfigure(2, weight=1) grid=[[0 for r in range(dim)] for c in range(dim)] markup=[["" for r in range(dim)] for c in range(dim)] self.goban=goban self.grid=grid self.markup=markup self.history=[] self.g = sgf.Sgf_game(size=self.dim) node_set(self.g.get_root(),"KM", self.komi) self.g_lock=Lock() self.g.lock=self.g_lock #self.analyser=self.analyser[0](self.g,self.filename) self.analyser=self.analyser["liveanalysis"](self.g,self.rsgf_filename,self.analyser) first_comment=_("Analysis by GoReviewPartner") first_comment+="\n"+("Bot: %s/%s"%(self.analyser.bot.bot_name,self.analyser.bot.bot_version)) first_comment+="\n"+("Komi: %0.1f"%self.komi) if grp_config.getboolean('Analysis', 'SaveCommandLine'): first_comment+="\n"+("Command line: %s"%self.analyser.bot.command_line) node_set(self.g.get_root(),"RSGF",first_comment+"\n") node_set(self.g.get_root(),"BOT",self.analyser.bot.bot_name) node_set(self.g.get_root(),"BOTV",self.analyser.bot.bot_version) self.cpu_lock=Lock() if not self.overlap_thinking: self.analyser.cpu_lock=self.cpu_lock #analyser and bot share the same cpu lock self.analyser.start() if type(self.black)!=type("abc"): #black is neither human nor analyser #so it's a bot log("Starting bot for black") #self.black=bot_starting_procedure(self.black[2],self.black[3],self.black[1],self.g,profil="fast") self.black=self.black["starting"](self.g,profile=self.black) log("Black bot started") if type(self.white)!=type("abc"): #white is neither human nor analyser not black #so it's a bot log("Starting bot for white") #self.white=bot_starting_procedure(self.white[2],self.white[3],self.white[1],self.g,profil="fast") self.white=self.white["starting"](self.g,profile=self.white) log("White bot started") row=1 Label(panel,text=_("Game"), font="-weight bold").grid(column=1,row=row,sticky=W) row+=1 if self.black=="human": player_black=_("Human player") elif self.black=="analyser": player_black=self.analyser.bot.bot_name else: player_black=self.black.bot_name self.game_label=Label(panel,text=_("Black")+": "+player_black) self.game_label.grid(column=1,row=row,sticky=W) node_set(self.g.get_root(),"PB",player_black) row+=1 if self.white=="human": player_white=_("Human player") elif self.white=="analyser": player_white=self.analyser.bot.bot_name elif self.white=="black": player_white=player_black else: player_white=self.white.bot_name self.game_label=Label(panel,text=_("White")+": "+player_white) self.game_label.grid(column=1,row=row,sticky=W) node_set(self.g.get_root(),"PW",player_white) row+=1 self.game_label=Label(panel,text=_("Komi")+": "+str(self.komi)) self.game_label.grid(column=1,row=row,sticky=W) row+=1 self.game_label=Label(panel,text=_("Currently at move %i")%1) self.game_label.grid(column=1,row=row,sticky=W) row+=1 self.pass_button=Button(toolbar,text=_("Pass"),state="disabled",command=self.player_pass) self.pass_button.bind("<Enter>",lambda e: self.set_status(_("Pass for this move"))) buttons_with_status.append(self.pass_button) self.undo_button=Button(toolbar,text=_("Undo"),state="disabled") self.undo_button.bind("<Enter>",lambda e: self.set_status(_("Undo to previous move"))) buttons_with_status.append(self.undo_button) if (self.black=="human") or (self.white=="human"): self.pass_button.pack(side=LEFT) self.undo_button.pack(side=LEFT) row+=1 if (self.black!="human") and (self.white!="human"): row+=1 self.pause_button=Button(toolbar,text=_("Pause"),command=self.pause) self.pause_button.pack(side=LEFT) self.pause_button.bind("<Enter>",lambda e: self.set_status(_("Pause the game"))) buttons_with_status.append(self.pause_button) self.pause_lock=Lock() Label(toolbar,text=" ", height=2).pack(side=LEFT) row+=1 Label(panel,text="").grid(column=1,row=row,sticky=W) row+=1 Label(panel,text=_("Analysis"), font="-weight bold").grid(column=1,row=row,sticky=W) row+=1 Label(panel,text=_("Analysis by %s")%self.analyser.bot.bot_name).grid(column=1,row=row,sticky=W) row+=1 Label(panel,text=_("Status:")).grid(column=1,row=row,sticky=W) row+=1 self.analysis_label=Label(panel,text=_("Ready to start")) self.analysis_label.grid(column=1,row=row,sticky=W) row+=1 Label(panel,fg=bg,text=_("Currently at move %i")%1000).grid(column=1,row=row,sticky=W) #yes, this is a ugly hack :) row+=1 Label(panel,fg=bg,text=_("Waiting for next move")).grid(column=1,row=row,sticky=W) #yes, this is a ugly hack :) row+=1 Label(panel,text="").grid(column=1,row=row,sticky=W) row+=1 self.review_bouton_wrapper=Frame(panel) self.review_bouton_wrapper.grid(column=1,row=row,sticky=W+E) self.status_bar=Label(self,text='',background=bg) self.status_bar.grid(column=1,row=3,sticky=W,columnspan=2) for button in buttons_with_status: button.bind("<Leave>",lambda e: self.clear_status()) self.protocol("WM_DELETE_WINDOW", self.close) self.parent.after(500,self.follow_analysis) self.bind('<Control-q>', self.save_as_png) #self.update_idletasks() #goban.reset() #goban.display(grid,markup) #self.goban.create_goban() #self.goban.grid=grid #self.goban.markup=markup self.goban.bind("<Configure>",self.redraw) popup.focus() self.locked=False self.goban.bind("<Button-3>",self.shine) #self.starting() self.after(500, self.starting)
class channel_plot: ''' ''' def __init__(self, interface, toplevel=False, start_t=False, stop_t=False): ''' ''' self.abort = False if not start_t: start_t = datetime.utcnow() - timedelta(hours=2) if not stop_t: stop_t = datetime.utcnow() self.update_pending = False self.pype = interface self.plot_dicts = {} if isinstance(start_t, datetime): self.start_t = StringVar(value=start_t.strftime(time_format)) elif isinstance(start_t, str): self.start_t = StringVar(value=start_t) else: raise TypeError('start_t must be string or datetime') if isinstance(stop_t, datetime): self.stop_t = StringVar(value=stop_t.strftime(time_format)) elif isinstance(stop_t, str): self.stop_t = StringVar(value=stop_t) else: raise TypeError('stop_t must be string or datetime') self.time_interval = [self.start_t.get(), self.stop_t.get()] self.ymin = DoubleVar() self.ymax = DoubleVar() if toplevel: self.toplevel = toplevel else: self.toplevel = Tk.Tk() self.status_var = StringVar(value='initializing') self._SetupCanvas() self._BuildGui() if not toplevel: Tk.mainloop() def _BuildGui(self): ''' ''' self.removei = IntVar(value=0) self.relative_start_time = BooleanVar(value=False) self.relative_stop_time = BooleanVar(value=False) self.continuous_updates = BooleanVar(value=False) self.ManualLimits = BooleanVar(value=False) self.LogYScale = BooleanVar(value=False) self.ShowGrid = BooleanVar(value=False) self.ConnectedPts = BooleanVar(value=True) Button(self.toplevel, text="Add Line", command=self._AddSubplot ).grid(row=0, column=1) self._AddSubplot() Button(self.toplevel, text="Gas Line Temps", command=self._PlotGasLines ).grid(row=0, column=2) Button(self.toplevel, text="Amps+Cell Temps", command=self._PlotCell ).grid(row=0, column=3) Label(self.toplevel, text='Start Time').grid(row=4, column=1) start_entry = Entry(self.toplevel, textvariable=self.start_t) start_entry.bind('<Return>', self.Update) start_entry.bind('<KP_Enter>', self.Update, '+') start_entry.grid(row=4, column=2, columnspan=2) Checkbutton(self.toplevel, text='Hours ago', variable=self.relative_start_time).grid(row=4, column=4, sticky='W') Label(self.toplevel, text='Stop Time').grid(row=5, column=1) stop_entry = Entry(self.toplevel, textvariable=self.stop_t) stop_entry.bind('<Return>', self.Update) stop_entry.bind('<KP_Enter>', self.Update, '+') stop_entry.grid(row=5, column=2, columnspan=2) Checkbutton(self.toplevel, text='Now', variable=self.relative_stop_time).grid(row=5, column=4, sticky='W') Label(self.toplevel, text='Y limits (min-max)').grid(row=7, column=1) ymin = Entry(self.toplevel, textvariable=self.ymin) ymin.grid(row=7, column=2) ymin.bind('<Return>', self.Update) ymin.bind('<KP_Enter>', self.Update, '+') ymax = Entry(self.toplevel, textvariable=self.ymax) ymax.grid(row=7, column=3) ymax.bind('<Return>', self.Update) ymax.bind('<KP_Enter>', self.Update, '+') Checkbutton(self.toplevel, text='Manual Y-limits', variable=self.ManualLimits ).grid(row=8, column=1) Checkbutton(self.toplevel, text='Log Y-scale', variable=self.LogYScale ).grid(row=8, column=2) Checkbutton(self.toplevel, text='Show Grid', variable=self.ShowGrid ).grid(row=9, column=1) Checkbutton(self.toplevel, text='Connected Points', variable=self.ConnectedPts ).grid(row=9, column=2) Button(self.toplevel, text="Update All", command=self.Update ).grid(row=10, column=1) Button(self.toplevel, text="Save Plot", command=self.SaveFigure ).grid(row=10, column=2) Button(self.toplevel, text="Save Json", command=self.SaveJson ).grid(row=10, column=3) Checkbutton(self.toplevel, text='Continuous (Button above to start)', variable=self.continuous_updates ).grid(row=11, column=1, columnspan=2) self.status_var.set('done') Label(self.toplevel, textvariable=self.status_var).grid(row=20, column=1, columnspan=2) def _SetupCanvas(self): ''' ''' self.figure = Figure() self.figure.subplots_adjust(left=0.15, bottom=0.2) self.subfigure = self.figure.add_subplot(1,1,1) self.notebook = Notebook(self.toplevel) self.notebook.grid(row=1, column=1, rowspan=3, columnspan=3, sticky='nsew') self.canvas = FigureCanvasTkAgg(self.figure, master=self.toplevel) self.canvas.show() self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=10) def _AddSubplot(self): ''' ''' plotnum = len(self.notebook.tabs()) self.plot_dicts[plotnum] = {} frame = Frame(self.notebook) frame.pack(side='top', fill='both', expand='y') self.plot_dicts[plotnum]['xname'] = StringVar(value='None') self.plot_dicts['xunit'] = False self.plot_dicts[plotnum]['yname'] = StringVar(value='None') self.plot_dicts['yunit'] = False Label(frame, text='X Channel').grid(row=0, column=0) Label(frame, text='Y Channel').grid(row=1, column=0) OptionMenu(frame, self.plot_dicts[plotnum]['xname'], "None", "time", "dpph_field", *self.pype.EligibleLoggers() ).grid(row=0, column=1, sticky='ew') OptionMenu(frame, self.plot_dicts[plotnum]['yname'], "None", "dpph_field", *self.pype.EligibleLoggers() ).grid(row=1, column=1, sticky='ew') self.notebook.add(frame, text='line:'+str(plotnum)) def _SetStartStop(self, event=None): ''' ''' try: if self.relative_stop_time.get(): stop_time = datetime.utcnow() else: stop_time = datetime.strptime(self.stop_t.get(), time_format) if self.relative_start_time.get(): hours = float(self.start_t.get()) start = datetime.utcnow() - timedelta(hours=hours) else: start = datetime.strptime(self.start_t.get(), time_format) assert (start < stop_time) self.time_interval[0] = start.strftime(time_format) self.time_interval[1] = stop_time.strftime(time_format) except ValueError: showwarning('Warning', 'invalid time format, must match yyyy-mm-ddThh:mm:ssZ') raise TimeFormatError("invalid start or stop time format") except AssertionError: showwarning('Warning', 'time order error, stop time must be after start time') raise TimeOrderError("stop time must be after start time") def Update(self, event=None, tab='All', unpend=False): ''' Call whatever sequence is needed to update local data and redraw the plot ''' if self.abort: self.abort = False return if unpend: self.update_pending = False self.status_var.set('updating!') if tab == 'All': tab = range(len(self.notebook.tabs())) elif isinstance(tab, int): tab = [tab] else: raise ValueError('tab should be "All" or an int') try: self._SetStartStop(event=None) except: print('SetStartStop problems') self.abort = True self.subfigure.clear() for tabi in tab: if tabi > len(self.subfigure.get_lines()): print('wtf') elif tabi == len(self.subfigure.get_lines()): self._UpdateData(tab=tabi) self._MakePlot(tab=tabi) else: self._UpdateExisting(tab=tabi) self.figure.legends = [] self.figure.legend(*self.subfigure.get_legend_handles_labels()) self.figure.legends[0].draggable(True) self.canvas.draw() self.status_var.set('updated at: ' + datetime.utcnow().strftime(time_format)) if (self.continuous_updates.get() and self.relative_stop_time.get() and not self.update_pending): self.update_pending = True self.toplevel.after(10000, lambda: self.Update(unpend=True)) def _UpdateData(self, tab=0): ''' ''' try: yname = self.plot_dicts[tab]['yname'].get() ychdat = self.pype.GetTimeSeries(yname, self.time_interval[0], self.time_interval[1]) if self.plot_dicts[tab]['xname'].get() == 'time': xchdat = (ychdat[0], ychdat[0], 'time' * len(ychdat[0])) else: xname = self.plot_dicts[tab]['xname'].get() xchdat = self.pype.GetTimeSeries(xname, self.time_interval[0], self.time_interval[1]) if tab > 0 and ychdat[0]: assert xchdat[2][0] == self.plot_dicts['xunit'], 'x units' assert ychdat[2][0] == self.plot_dicts['yunit'], 'y units' self.xdata = [] self.ydata = [] if ychdat[0]: for tx, x in zip(xchdat[0], xchdat[1]): xtmp = False ytmp = False dt = timedelta(seconds=60) for ty, y in zip(ychdat[0], ychdat[1]): if abs(ty - tx) < dt: dt = abs(ty - tx) xtmp = x ytmp = y if xtmp and ytmp: self.xdata.append(xtmp) self.ydata.append(ytmp) [self.xdata, self.ydata] = zip(*sorted(zip(self.xdata, self.ydata))) self.plot_dicts['xunit'] = xchdat[2][0] self.plot_dicts['yunit'] = ychdat[2][0] except AssertionError as e: print('*'*60, '\n the', e[0], 'do not match the 0th line', '*'*60) def _UpdateExisting(self, tab=0): ''' ''' try: yname = self.plot_dicts[tab]['yname'].get() ychdat = self.pype.GetTimeSeries(yname, self.time_interval[0], self.time_interval[1]) if self.plot_dicts[tab]['xname'].get() == 'time': xchdat = (ychdat[0], ychdat[0], 'time' * len(ychdat[0])) else: xname = self.plot_dicts[tab]['xname'].get() xchdat = self.pype.GetTimeSeries(xname, self.time_interval[0], self.time_interval[1]) if tab > 0 and ychdat[0]: assert xchdat[2][0] == self.plot_dicts['xunit'], 'x units' assert ychdat[2][0] == self.plot_dicts['yunit'], 'y units' self.xdata = [] self.ydata = [] if ychdat[0]: for tx, x in zip(xchdat[0], xchdat[1]): xtmp = False ytmp = False dt = timedelta(seconds=60) for ty, y in zip(ychdat[0], ychdat[1]): if abs(ty - tx) < dt: dt = abs(ty - tx) xtmp = x ytmp = y if xtmp and ytmp: self.xdata.append(xtmp) self.ydata.append(ytmp) [self.xdata, self.ydata] = zip(*sorted(zip(self.xdata, self.ydata))) self.plot_dicts['xunit'] = xchdat[2][0] self.plot_dicts['yunit'] = ychdat[2][0] this_line = self.subfigure.get_lines()[tab] this_line.set_xdata(array(self.xdata)) this_line.set_ydata(array(self.ydata)) except AssertionError as e: print('*'*60, '\n the', e[0], 'do not match the 0th line', '*'*60) def _MakePlot(self, tab=0): ''' ''' if self.ConnectedPts.get(): plotformat='o-' else: plotformat='o' if self.plot_dicts[tab]['xname'].get() == 'time': self.subfigure.plot_date(self.xdata, self.ydata, plotformat, label=self.plot_dicts[tab]['yname'].get()) self.subfigure.set_xticklabels(self.subfigure.get_xticklabels(), rotation=-45) self.subfigure.xaxis.set_major_formatter(dates.DateFormatter( "%m/%d %H:%M")) self.subfigure.yaxis.set_major_formatter(ticker.ScalarFormatter( useOffset=False)) else: self.subfigure.plot(self.xdata, self.ydata, plotformat, label=self.plot_dicts[tab]['yname'].get()) self.subfigure.set_title(self.plot_dicts[tab]['yname'].get() + ' vs ' + self.plot_dicts[tab]['xname'].get() + '\n from ' + self.time_interval[0] + ' to ' + self.time_interval[1]) xname = self.plot_dicts[tab]['xname'].get().replace('_', ' ') xunit = '[' + str(self.plot_dicts['xunit']) + ']' self.subfigure.set_xlabel(xname + ' ' + xunit) yname = self.plot_dicts[tab]['yname'].get().replace('_', ' ') yunit = '[' + str(self.plot_dicts['yunit']) + ']' self.subfigure.set_ylabel(yname + ' ' + yunit) tickformat = ticker.ScalarFormatter(useOffset=False) if self.ManualLimits.get(): self.subfigure.set_ylim(bottom=self.ymin.get(), top=self.ymax.get()) if self.LogYScale.get(): self.subfigure.set_yscale('log') if self.ShowGrid.get(): self.subfigure.grid(b=True, which='major') self.subfigure.grid(b=True, which='minor') def _PlotGasLines(self): ''' ''' gas_lines = ['left_gas_line_lower_t', 'left_gas_line_upper_t', 'right_gas_line_lower_t', 'right_gas_line_upper_t'] self._PlotSet(gas_lines) def _PlotCell(self): ''' ''' sensors = ['kh2_temp', 'kh3_temp', 'waveguide_cell_body_temp', 'coldhead_temp'] self._PlotSet(sensors) def _PlotSet(self, channels): ''' Plots a set of channels on common axes ''' for plotn, channel in enumerate(channels): if (len(self.plot_dicts)-2) <= plotn: self._AddSubplot() self.plot_dicts[plotn]['xname'].set('time') self.plot_dicts[plotn]['yname'].set(channel) self.start_t.set('3') self.relative_start_time.set(True) self.relative_stop_time.set(True) self.continuous_updates.set(True) self.Update() def SaveFigure(self): ''' ''' file_extensions = [('vectorized', '.eps'), ('adobe', '.pdf'), ('image', '.png'), ('all', '.*')] outfile = asksaveasfilename(defaultextension='.pdf', filetypes=file_extensions) self.figure.savefig(outfile) def SaveJson(self): ''' ''' outfile = asksaveasfile(defaultextension='.json') outdict = {'xunit':self.plot_dicts['xunit'], 'yunit':self.plot_dicts['yunit'] } for tab in range(len(self.plot_dicts)-2): outdict[tab] = {} outdict[tab]['xname']=self.plot_dicts[tab]['xname'].get() outdict[tab]['yname']=self.plot_dicts[tab]['yname'].get() this_line = self.subfigure.get_lines()[tab] if outdict['xunit'] == 't': outdict[tab]['xdata'] = [str(t) for t in this_line.get_xdata()] else: outdict[tab]['xdata'] = list(this_line.get_xdata()) outdict[tab]['ydata'] = list(this_line.get_ydata()) dump(outdict, outfile, indent=4) outfile.close()
class GoalTrak(Tk): def __init__(self,parent): Tk.__init__(self,parent) self.parent = parent self.initialize() def initialize(self): self.grid() self.entryVariable = StringVar() #Student entry box self.entry = Entry(self,textvariable=self.entryVariable) self.entry.grid(column=0,row=1,sticky='EW') self.entry.bind("<Return>", self.onPressEnter) self.entryVariable.set(u"Enter new student here") #Simple buttons# self.quitButton = Button(self,text=u"Quit", command=self.onQuitClick) #Quit button self.quitButton.grid(row = 14, sticky='SE') self.removeButton = Button(self, text=u"Remove student", command=self.onRemoveClick) #Remove student button self.removeButton.grid(column=0,row=6, sticky = 'W') self.optionMenu = Button(self, text=u"About", command=self.onAboutClick) #About button self.optionMenu.grid(row = 13, sticky='SE') self.infoUpdate = Button(self, text=u"Update Student Info", command=self.onInfoUpdateClick) #Info updater self.infoUpdate.grid(column=0, row=4, sticky = 'W') self.showInformation = Button(self, text = u"Show Information", command=self.onShowInformationClick) self.showInformation.grid(column=0, row=5, sticky = 'W') self.labelVariable = StringVar() #Banner self.labelVariable.set(u"Welcome to GoalTrak") label = Label(self,textvariable=self.labelVariable, \ anchor="w",fg="white",bg="navy") label.grid(column=0,row=0,sticky='EW') self.StudentListDisplay = Listbox(self) #Student List self.StudentListDisplay.grid(row=2,column=0,columnspan=2,sticky='W') for student in student_list: self.StudentListDisplay.insert(END, student) self.tab = Notebook(width = 500, height = 300) #Notebook self.tab.pressed_index = None ###Notebook### self.studentInfoDisplayFrame = Frame(self.tab) ####Info display tab### self.studentNameLabelVar = StringVar() #Student name label self.studentNameLabelVar.set('Click "show information"') studentNameLabel = Label(self.studentInfoDisplayFrame, textvariable=self.studentNameLabelVar, fg='black', bg='white') studentNameLabel.grid(column=0,row=0,sticky='NW') self.studentClassLabelVar = StringVar() #Student class label self.studentClassLabelVar.set('') studentClassLabel = Label(self.studentInfoDisplayFrame, textvariable=self.studentClassLabelVar, fg='black', bg='white') studentClassLabel.grid(column=0,row=1,sticky='W') self.studentGoal1LabelVar = StringVar() #Student goal1 label self.studentGoal1LabelVar.set('') studentGoal1Label = Label(self.studentInfoDisplayFrame, textvariable=self.studentGoal1LabelVar, fg='black', bg='white') studentGoal1Label.grid(column=0,row=2,sticky='W') self.dataGenerationFrame = Frame(self.tab) ###Data entry frame### self.dataGenerationFrame.grid() self.listboxFrame = Frame(self.dataGenerationFrame) #LISTBOX self.listboxFrame.grid(column=0, row=0, columnspan=2, rowspan=2, padx=2, pady=2) self.goalSelection = Listbox(self.listboxFrame) self.goalSelection.pack() self.goalValEntryFrame = Frame(self.dataGenerationFrame) #SPINBOX self.goalValEntryFrame.grid(row= 0, column=4, padx=2, pady=2) self.goalValEntry = Spinbox(self.goalValEntryFrame, from_=0, to=10) self.goalValEntry.pack() self.noteEntryFrame = Frame(self.dataGenerationFrame) #TEXT self.noteEntryFrame.grid(column= 2, row=1, columnspan=3, rowspan=3, padx=2, pady=2) self.noteEntry = Text(self.noteEntryFrame, borderwidth=2, height = 15, width = 40, relief=SUNKEN) self.noteEntry.pack(anchor= 'w') self.buttonBox = Frame(self.dataGenerationFrame) self.buttonBox.grid(row= 4, column= 0, columnspan= 2, rowspan= 2, sticky= 'W') self.addDataButton = Button(self.buttonBox, text = 'Store Information', command=self.onStoreInformationClick) self.addDataButton.pack() self.tab.add(self.studentInfoDisplayFrame, text='Student Info') #Labels tabs self.tab.add(self.dataGenerationFrame, text='Enter Data') self.tab.grid(column = 0, row = 7, rowspan = 5, sticky = 'EW') self.grid_columnconfigure(0,weight=1) #This makes it so the window is resizable self.resizable(True,True) self.update() self.geometry(self.geometry()) self.entry.focus_set() self.entry.selection_range(0, END) def onAboutClick(self): #About message tkMessageBox.showinfo(title=u'About', message=u'GoalTrak v. Alpha VI by Eli Dinkelspiel') def student_list_updater(self, studentlist): self.StudentListDisplay.delete(0, END) for student in studentlist: self.StudentListDisplay.insert(END, student)#Refreshes student listbox def onQuitClick(self): result = tkMessageBox.askokcancel(title='GoalTrak', message='Are you sure you want to quit GoalTrak?') if result == True: GoalTrak.destroy(self) #Quit button def onRemoveClick(self): index = self.StudentListDisplay.curselection() index = int(index[0]) result = tkMessageBox.askokcancel(title='Are you sure?', \ message='Are you sure you want to remove %s? This cannot be undone and will remove all associated data.' \ % (student_list[index])) if result == True: try: remove('GoalTrak/StudentInformation' +student_list[index]) except (OSError): pass del student_list[index] self.student_list_updater(student_list) file_saver(student_list, 'GoalTrak/StudentList')#Remove student button def onPressEnter(self, event): #Enters students into save file hold = self.entryVariable.get() hold = str(hold) with open('GoalTrak/StudentList', 'rb') as file: #This appends students to the already existing document of students if (hold) not in student_list: student_list.append(hold) file_saver(student_list, 'GoalTrak/StudentList') self.labelVariable.set(self.entryVariable.get() + " added" ) self.student_list_updater(student_list) else: #If student is already in list, aborts self.labelVariable.set( self.entryVariable.get() + " is already in list" ) file.close() self.entry.focus_set() self.entry.selection_range(0, END)#Add student with <enter> def onStoreInformationClick(self): note_hold = self.noteEntry.get(1.0, END) val_hold = self.goalValEntry.get() validEntry = True try: entry_mode = current_student.goals['goal' + self.goalSelection.curselection()[0]] except(KeyError): entry_mode = 3 if entry_mode in ['goal1', 'goal2', 'goal3']: if self.goalSelection.get() in ['<goal1 not set>', '<goal2 not set>', '<goal3 not set>']: tkMessageBox.showerror('Goal not defined') validEntry = False else: if note_hold == '': note_hold = None elif entry_mode == 3: val_hold = None entry_mode = None if validEntry: current_student.dataHist.append(dataPointCompile(entry_mode, val_hold, note_hold)) file_saver(current_student, 'GoalTrak/StudentInformation' + current_student.name) self.labelVariable.set(u"Data safely stored") def onShowInformationClick(self): #Refreshes student information display studentNameVar = student_list[int(self.StudentListDisplay.curselection()[0])] self.studentNameLabelVar.set(studentNameVar) global current_student current_student = file_loader('GoalTrak/StudentInformation' + studentNameVar) ####Each one of these try/except pairs makes the various User() attributes visible, if they exist. DO NOT BUNDLE AS ONE### #infoFrame try: self.studentClassLabelVar.set(current_student.usrClass) except (AttributeError): self.studentClassLabelVar.set(u'No set class') try: self.studentGoal1LabelVar.set(current_student.goals['goal1']) except (AttributeError): self.studentGoal1LabelVar.set(u'Goal 1 not set') #dataGenFrame self.goalSelection.delete(0, END) try: self.goalSelection.insert(END, current_student.goals['goal1']) except (AttributeError): pass try: self.goalSelection.insert(END, current_student.goals['goal2']) except (AttributeError, KeyError): pass try: self.goalSelection.insert(END, current_student.goals['goal3']) except (AttributeError, KeyError): pass self.goalSelection.insert(END, 'Unattached Note') def onInfoUpdateClick(self): #User Information Updater index = self.StudentListDisplay.curselection() index = int(index[0]) student_name = student_list[index] try: #Gives new students a file object global current_student current_student = file_loader('GoalTrak/StudentInformation' + student_name) except (IOError): file_saver(User(student_name, None, None, None), 'GoalTrak/StudentInformation' + student_name) global current_student current_student = file_loader('GoalTrak/StudentInformation' + student_name) def onSaveQuitClick(): #Stores the data classHold = str(self.UserInformationUpdater.classEntry.get()) goal1Hold = str(self.UserInformationUpdater.goal1Entry.get()) global current_student try: current_student = file_loader('GoalTrak/StudentInformation' + student_name) except (IOError): print "New file being created for " + student_name current_student = User(student_name, None, None, None) for student in student_information: #I probably want to get rid of this for loop but I'm afraid to tinker with my code :( if student == student_name: try: global current_student current_student.usrClass = classHold current_student.goals['goal1'] = goal1Hold file_saver(current_student, 'GoalTrak/StudentInformation' + student_name) except (AttributeError): print 'New file being created' file_saver(User(student_name, classHold, {'goal1':goal1Hold}, []), 'GoalTrak/StudentInformation' + student_name, ) global current_student current_student = file_loader('GoalTrak/StudentInformation' + student_name) self.UserInformationUpdater.destroy() self.UserInformationUpdater = Toplevel() self.UserInformationUpdater.grid() self.UserInformationUpdater.title("Update Information - %s" % (student_name)) self.UserInformationUpdater.infolabel = Label(self.UserInformationUpdater, \ text = (u"User Information - %s" % (student_name)), anchor="w", fg="white", bg="navy") self.UserInformationUpdater.infolabel.grid(column=0,row=0,columnspan=2,sticky='EW') #Visual stuff for the updater self.UserInformationUpdater.classVar = StringVar() self.UserInformationUpdater.classEntry = Entry(self.UserInformationUpdater, textvariable=self.UserInformationUpdater.classVar) self.UserInformationUpdater.classEntry.grid(column=0,row=1,sticky='EW') try: if current_student.usrClass != None: self.UserInformationUpdater.classVar.set(str(current_student.usrClass)) else: self.UserInformationUpdater.classVar.set(u"Enter student's class here") except (AttributeError, TypeError): self.UserInformationUpdater.classVar.set(u"Enter student's class here") self.UserInformationUpdater.goal1Var = StringVar() self.UserInformationUpdater.goal1Entry = Entry(self.UserInformationUpdater, textvariable=self.UserInformationUpdater.goal1Var) self.UserInformationUpdater.goal1Entry.grid(column=0,row=2,sticky='EW') try: self.UserInformationUpdater.goal1Var.set(str(current_student.goals['goal1'])) except (AttributeError, TypeError): self.UserInformationUpdater.goal1Var.set(u"Enter goal 1 here") self.UIU_quitButton = Button(self.UserInformationUpdater, text=u"Save and Quit", command=onSaveQuitClick) #Save & Quit button self.UIU_quitButton.grid(column=1, row=2) self.UserInformationUpdater.grid_columnconfigure(0,weight=1) #This makes it so the window is resizable self.UserInformationUpdater.resizable(True,True) self.UserInformationUpdater.update() self.UserInformationUpdater.geometry(self.UserInformationUpdater.geometry()) def goalSelDispSet(self): result = [] global current_student try: result.append((current_student.goals['goal1'], '1')) except (KeyError, AttributeError): pass try: result.append((current_student.goals['goal2'], '2')) except (KeyError, AttributeError): pass try: result.append((current_student.goals['goal3'], '3')) except (KeyError, AttributeError): pass result.append(('Unattached Note', '4')) return result
class DicoGIS(Tk): def __init__(self): u""" Main window constructor Creates 1 frame and 2 labelled subframes """ # basics settings Tk.__init__(self) # constructor of parent graphic class self.title(u'DicoGIS {0}'.format(DGversion)) self.li_raster_formats = ['ecw', 'geotiff'] # notebook self.nb = Notebook(self) self.FrProg = Labelframe(self, name='progression', text='gui_prog') self.FrOutp = Labelframe(self, name='output', text='gui_fr4') # tabs self.tab_files = Frame(self.nb) # tab_id = 0 self.tab_sgbd = Frame(self.nb) # tab_id = 1 self.tab_webservices = Frame(self.nb) # tab_id = 2 self.tab_isogeo = Frame(self.nb) # tab_id = 3 self.tab_about = Frame(self.nb) # tab_id = 4 ## TAB 1: FILES self.nb.add(self.tab_files, text='gui_files', padding=3) # frame: path folder self.FrPath = Labelframe(self.tab_files, name='files', text='gui_fr1') self.labtarg = Label(self.FrPath, text='gui_path') self.target = Entry(master=self.FrPath, width=35) self.browsetarg = Button(self.FrPath, # browse button text='gui_choix', command=lambda: self.setpathtarg(), takefocus=True) self.browsetarg.focus_force() # force the focus on # widgets placement self.labtarg.grid(row=1, column=1, columnspan=1, sticky="NSWE", padx=2, pady=2) self.target.grid(row=1, column=2, columnspan=1, sticky="NSWE", padx=2, pady=2) self.browsetarg.grid(row=1, column=3, sticky="NSWE", padx=2, pady=2) # frame: filters self.FrFilters = Labelframe(self.tab_files, name='filters', text='filters') # formats options self.opt_shp = IntVar(self.FrFilters) # able/disable shapefiles self.opt_tab = IntVar(self.FrFilters) # able/disable MapInfo tables self.opt_kml = IntVar(self.FrFilters) # able/disable KML self.opt_gml = IntVar(self.FrFilters) # able/disable GML self.opt_geoj = IntVar(self.FrFilters) # able/disable GeoJSON self.opt_gxt = IntVar(self.FrFilters) # able/disable GXT self.opt_egdb = IntVar(self.FrFilters) # able/disable Esri FileGDB self.opt_spadb = IntVar(self.FrFilters) # able/disable Spatalite DB self.opt_rast = IntVar(self.FrFilters) # able/disable rasters self.opt_cdao = IntVar(self.FrFilters) # able/disable CAO/DAO files self.opt_pdf = IntVar(self.FrFilters) # able/disable Geospatial PDF self.opt_lyr = IntVar(self.FrFilters) # able/disable Geospatial Lyr self.opt_mxd = IntVar(self.FrFilters) # able/disable Geospatial MXD self.opt_qgs = IntVar(self.FrFilters) # able/disable Geospatial QGS # format choosen: check buttons caz_shp = Checkbutton(self.FrFilters, text=u'.shp', variable=self.opt_shp) caz_tab = Checkbutton(self.FrFilters, text=u'.tab', variable=self.opt_tab) caz_kml = Checkbutton(self.FrFilters, text=u'.kml', variable=self.opt_kml) caz_gml = Checkbutton(self.FrFilters, text=u'.gml', variable=self.opt_gml) caz_geoj = Checkbutton(self.FrFilters, text=u'.geojson', variable=self.opt_geoj) caz_gxt = Checkbutton(self.FrFilters, text=u'.gxt', variable=self.opt_gxt) caz_egdb = Checkbutton(self.FrFilters, text=u'Esri FileGDB', variable=self.opt_egdb) caz_spadb = Checkbutton(self.FrFilters, text=u'Spatialite', variable=self.opt_spadb) caz_rast = Checkbutton(self.FrFilters, text=u'rasters ({0})'.format(', '.join(self.li_raster_formats)), variable=self.opt_rast) caz_cdao = Checkbutton(self.FrFilters, text=u'CAO/DAO', variable=self.opt_cdao) caz_pdf = Checkbutton(self.FrFilters, text=u'Geospatial PDF', variable=self.opt_pdf) caz_lyr = Checkbutton(self.FrFilters, text=u'.lyr', variable=self.opt_lyr) caz_mxd = Checkbutton(self.FrFilters, text=u'.mxd', variable=self.opt_mxd) caz_qgs = Checkbutton(self.FrFilters, text=u'.qgs', variable=self.opt_qgs) # widgets placement caz_shp.grid(row=1, column=0, sticky="NSWE", padx=2, pady=2) caz_tab.grid(row=1, column=1, sticky="NSWE", padx=2, pady=2) caz_kml.grid(row=1, column=2, sticky="NSWE", padx=2, pady=2) caz_gml.grid(row=1, column=3, sticky="NSWE", padx=2, pady=2) caz_geoj.grid(row=1, column=4, sticky="NSWE", padx=2, pady=2) caz_gxt.grid(row=1, column=7, sticky="NSWE", padx=2, pady=2) caz_pdf.grid(row=1, column=5, columnspan=2, sticky="NSWE", padx=2, pady=2) caz_rast.grid(row=2, column=0, columnspan=2, sticky="NSWE", padx=2, pady=2) caz_egdb.grid(row=2, column=2, columnspan=2, sticky="NSWE", padx=2, pady=2) caz_cdao.grid(row=2, column=4, columnspan=1, sticky="NSWE", padx=2, pady=2) caz_spadb.grid(row=2, column=5, columnspan=2, sticky="NSWE", padx=2, pady=2) caz_lyr.grid(row=3, column=0, columnspan=2, sticky="NSWE", padx=2, pady=2) caz_mxd.grid(row=3, column=1, columnspan=2, sticky="NSWE", padx=2, pady=2) caz_qgs.grid(row=3, column=2, columnspan=2, sticky="NSWE", padx=2, pady=2) # frames placement self.FrPath.grid(row=3, column=1, padx=2, pady=2, sticky="NSWE") self.FrFilters.grid(row=4, column=1, padx=2, pady=2, sticky="NSWE") # tab 2: database self.nb.add(self.tab_sgbd, text='gui_database', padding=3) # tab 3: webservices self.nb.add(self.tab_webservices, text='gui_webservices', padding=3) ## TAB 4: ISOGEO self.nb.add(self.tab_isogeo, text='gui_Isogeo', padding=3) ## TAB 5: ABOUT self.nb.add(self.tab_about, text='gui_about', padding=3) ## MAIN FRAME # Welcome message self.welcome = Label(self, text='hola test', foreground="red2") # Progression bar self.status = StringVar(self.FrProg, '') # widgets self.prog_layers = Progressbar(self.FrProg, orient="horizontal") Label(master=self.FrProg, textvariable=self.status, foreground='DodgerBlue').pack() # widgets placement self.prog_layers.pack(expand=1, fill='both') # Output configuration # widgets self.nameoutput = Label(self.FrOutp, text='gui_fic') self.output = Entry(self.FrOutp, width=35) # widgets placement self.nameoutput.grid(row=0, column=1, sticky="NSWE", padx=2, pady=2) self.output.grid(row=0, column=2, columnspan=2, sticky="NSWE", padx=2, pady=2) # Image self.icone = PhotoImage(file=r'../data/img/DicoGIS_logo.gif') Label(self, borderwidth=2, image=self.icone).grid(row=1, rowspan=4, column=0, padx=2, pady=2, sticky=W) # credits s = Style(self) s.configure('Kim.TButton', foreground='DodgerBlue', borderwidth=0) Button(self, text='by @GeoJulien\nGPL3 - 2015', style='Kim.TButton', command=lambda: open_new('https://github.com/Guts/DicoGIS')).grid(row=4, padx=2, pady=2, sticky="WE") # language switcher self.ddl_lang = Combobox(self, values=['fr', 'en'], width=5) # grid placement self.val = Button(self, text='gui_go', state=ACTIVE, command=lambda: self.process()) self.can = Button(self, text='gui_quit', command=lambda: self.destroy()) self.welcome.grid(row=1, column=1, columnspan=1, sticky="NS", padx=2, pady=2) self.ddl_lang.grid(row=1, column=1, sticky="NSE", padx=2, pady=2) self.nb.grid(row=2, column=1) self.FrProg.grid(row=3, column=1, sticky="NSWE", padx=2, pady=2) self.FrOutp.grid(row=4, column=1, sticky="NSWE", padx=2, pady=2) self.val.grid(row=5, column=1, columnspan=2, sticky="NSWE", padx=2, pady=2) self.can.grid(row=5, column=0, sticky="NSWE", padx=2, pady=2)
class Metadator(Tk): def __init__(self): u""" Main window constructor Creates 1 frame and 2 labeled subframes """ # first: the log # see: http://sametmax.com/ecrire-des-logs-en-python/ self.logger = logging.getLogger() self.logger.setLevel(logging.DEBUG) # all errors will be get log_form = logging.Formatter('%(asctime)s || %(levelname)s || %(message)s') logfile = RotatingFileHandler('Metadator_LOG.log', 'a', 5000000, 1) logfile.setLevel(logging.DEBUG) logfile.setFormatter(log_form) self.logger.addHandler(logfile) self.logger.info('\n\t ======== Metadator ========') # first messages self.logger.info('Starting the UI') # checking the path to GDAL in the path if "GDAL_DATA" not in env.keys(): try: gdal.SetConfigOption(str('GDAL_DATA'), str(path.abspath(r'data/gdal'))) except: print("Oups! Something has gone wrong...\ see: https://github.com/Guts/Metadator/issues/21") else: pass # basics settings Tk.__init__(self) # constructor of parent graphic class self.title(u'Metadator {0}'.format(MetadatorVersion)) self.style = Style() # more friendly windows style if opersys == 'win32': self.logger.info('Op. system: {0}'.format(platform.platform())) self.iconbitmap('Metadator.ico') # windows icon self.uzer = env.get(u'USERNAME') elif opersys == 'linux2': self.logger.info('Op. system: {0}'.format(platform.platform())) self.uzer = env.get(u'USER') icon = Image("photo", file=r'data/img/metadator.gif') self.call('wm', 'iconphoto', self._w, icon) self.minsize(580, 100) self.style.theme_use('clam') elif opersys == 'darwin': self.logger.info('Op. system: {0}'.format(platform.platform())) self.uzer = env.get(u'USER') else: self.logger.warning('Operating system not tested') self.logger.info('Op. system: {0}'.format(platform.platform())) self.resizable(width=False, height=False) self.focus_force() self.logger.info('GDAL version: {}'.format(gdal.__version__)) # variables self.def_rep = "" # folder to search for self.def_lang = 'FR' # language to start self.def_doc = IntVar() # to export into Word self.def_xls = IntVar() # to export into Excel 2003 self.def_xml = IntVar() # to export into ISO 19139 self.def_cat = IntVar() # to merge all output Word files self.def_odt = IntVar() # to export into OpenDocumentText self.def_dict = IntVar() # to make a dictionnary of data self.def_kass = IntVar() # to handle field name case sensitive self.def_stat = IntVar() # to active/disable stats fields self.li_pro = [] # list for profiles in language selected self.li_shp = [] # list for shapefiles path self.li_tab = [] # list for MapInfo tables path self.num_folders = 0 # number of folders explored self.today = strftime("%Y-%m-%d") # date of the day self.dico_layer = OD() # dictionary about layer properties self.dico_profil = OD() # dictionary from profile selected self.dico_fields = OD() # dictionary for fields information self.dico_rekur = OD() # dictionary of recurring attributes self.dico_err = OD() # errors list self.dico_help = OD() # dictionary of help texts li_lang = [lg for lg in listdir(r'locale')] # available languages self.blabla = OD() # texts dictionary # GUI fonts ft_tit = tkFont.Font(family="Times", size=10, weight=tkFont.BOLD) # fillfulling self.load_settings() self.load_texts(self.def_lang) self.li_profiles(self.def_lang) self.li_rekurs(self.def_lang) self.recup_help(self.def_lang) # Tabs self.nb = Notebook(self) self.tab_globals = Frame(self.nb) # tab_id = 0 self.tab_options = Frame(self.nb) # tab_id = 1 self.tab_attribs = Frame(self.nb) # tab_id = 2 self.nb.add(self.tab_globals, text=self.blabla.get('gui_tab1'), padding=3) self.nb.add(self.tab_options, text=self.blabla.get('gui_tab2'), padding=3) self.nb.add(self.tab_attribs, text=self.blabla.get('gui_tab3'), padding=3) self.logger.info('UI created') ### Tab 1: global # Frames self.FrPath = Labelframe(self.tab_globals, name='main', text=self.blabla.get('tab1_fr1')) self.FrProg = Labelframe(self.tab_globals, name='progression', text=self.blabla.get('tab1_frprog')) ## Frame 1 # target folder self.labtarg = Label(self.FrPath, text=self.blabla.get('tab1_path')) self.target = Entry(self.FrPath, width=25) self.browsetarg = Button(self.FrPath, # browse button text=self.blabla.get('tab1_browse'), command=lambda: self.setpathtarg(), takefocus=True) self.browsetarg.focus_force() # force the focus on self.profil = Label(self.FrPath, text=self.blabla.get('tab1_prof')) # profiles switcher self.ddl_profil = Combobox(self.FrPath, values=self.li_pro, width=5) self.ddl_profil.current(0) self.ddl_profil.bind("<<ComboboxSelected>>", self.select_profil) # widgets placement self.labtarg.grid(row=1, column=1, columnspan=1, sticky=N + S + W + E, padx=2, pady=8) self.target.grid(row=1, column=2, columnspan=1, sticky=N + S + W + E, padx=2, pady=8) self.browsetarg.grid(row=1, column=3, sticky=N + S + W + E, padx=2, pady=8) self.profil.grid(row=2, column=1, sticky=N + S + W + E, padx=2, pady=8) self.ddl_profil.grid(row=2, column=2, sticky=W + E + N + S, columnspan=2, padx=2, pady=8) # tooltips InfoBulle(self.target, message=self.dico_help.get(30)[1]) InfoBulle(self.browsetarg, message=self.dico_help.get(30)[1]) InfoBulle(self.ddl_profil, message=self.dico_help.get(31)[1]) ## Frame 2 # variables self.status = StringVar(self.FrProg, '') # widgets self.prog_layers = Progressbar(self.FrProg, orient="horizontal") self.prog_fields = Progressbar(self.FrProg, orient="horizontal") # widgets placement Label(self.FrProg, textvariable=self.status, foreground='DodgerBlue').pack(expand=1) self.prog_layers.pack(expand=1, fill=X) # Frames placement self.FrPath.pack(expand=1, fill='both') self.FrProg.pack(expand=1, fill='both') ### Tab 2: options # Export options caz_doc = Checkbutton(self.tab_options, text=u'HTML / Word (.doc/.docx)', variable=self.def_doc, command=lambda: self.catalog_dependance()) caz_xls = Checkbutton(self.tab_options, text=u'Excel 2003 (.xls)', variable=self.def_xls) caz_xml = Checkbutton(self.tab_options, text=u'XML (ISO 19139)', variable=self.def_xml) self.caz_cat = Checkbutton(self.tab_options, text=self.blabla.get('tab2_merge'), variable=self.def_cat) caz_odt = Checkbutton(self.tab_options, text=u'Open Document Text (.odt)', variable=self.def_odt) # widgets placement caz_doc.grid(row=1, column=0, sticky=N + S + W + E, padx=2, pady=2) self.caz_cat.grid(row=2, column=0, sticky=N + S + W + E, padx=2, pady=2) caz_xls.grid(row=1, column=1, sticky=N + S + W + E, padx=2, pady=2) caz_xml.grid(row=2, column=1, sticky=N + S + W + E, padx=2, pady=2) caz_odt.grid(row=3, column=1, sticky=N + S + W + E, padx=2, pady=2) # disabling the widgets which work only on Windows OS if opersys != 'win32': self.logger.info('Disabling Windows reserved functions.') self.def_doc.set(0) self.def_cat.set(0) caz_doc.configure(state='disabled') self.caz_cat.configure(state='disabled') else: pass # make the catalog option depending on the Word option self.catalog_dependance() # tooltips InfoBulle(caz_doc, message=self.dico_help.get(33)[1], image=self.dico_help.get(33)[2]) InfoBulle(caz_xls, message=self.dico_help.get(34)[1], image=self.dico_help.get(34)[2]) InfoBulle(caz_xml, message=self.dico_help.get(35)[1], image=self.dico_help.get(35)[2]) InfoBulle(caz_odt, message=self.dico_help.get(36)[1], image=self.dico_help.get(36)[2]) InfoBulle(self.caz_cat, message=self.dico_help.get(37)[1], image=self.dico_help.get(37)[2]) ### Tab 3: recurring attributes # Attribute selector self.lab_chps = Label(self.tab_attribs, text=self.blabla.get('tab3_sele')) self.ddl_attr = Combobox(self.tab_attribs, values=self.dico_rekur.keys()) self.ddl_attr.bind("<<ComboboxSelected>>", self.edit_rekur) self.supr = Button(self.tab_attribs, text=self.blabla.get('tab3_supp'), command=self.del_rekur) # frame self.FrRekur = Labelframe(self.tab_attribs, name='attributes', text=self.blabla.get('tab3_tit')) # attribute settings self.tab3_LBnom = Label(self.FrRekur, text=self.blabla.get('tab3_nom'), state=DISABLED) self.tab3_ENnom = Entry(self.FrRekur, state=DISABLED) self.tab3_LBdesc = Label(self.FrRekur, text=self.blabla.get('tab3_desc'), state=DISABLED) self.tab3_TXdesc = Text(self.FrRekur, height=5, width=30, wrap=WORD, state=DISABLED) self.tab3_CBcass = Checkbutton(self.FrRekur, text=self.blabla.get('tab3_cass'), variable=self.def_kass, state=DISABLED) self.tab3_CBstat = Checkbutton(self.FrRekur, text=self.blabla.get('tab3_stat'), variable=self.def_stat, state=DISABLED) # Validation button self.save = Button(self.FrRekur, text=self.blabla.get('tab3_save'), command=self.save_rekur, state='disabled') # widgets placement self.lab_chps.grid(row=1, column=1, sticky=N + S + W, padx=2, pady=2) self.ddl_attr.grid(row=1, column=2, sticky=N + S + W + E, padx=2, pady=2) self.supr.grid(row=1, column=3, sticky=N + S + W + E, padx=2, pady=2) self.tab3_LBnom.grid(row=1, column=0, columnspan=1, sticky=N + S + W, padx=2, pady=2) self.tab3_ENnom.grid(row=1, column=1, columnspan=1, sticky=N + S + W + E, padx=2, pady=2) self.tab3_LBdesc.grid(row=2, column=0, columnspan=1, sticky=N + S + W + E, padx=2, pady=2) self.tab3_TXdesc.grid(row=2, column=1, columnspan=2, sticky=N + S + W + E, padx=2, pady=2) self.tab3_CBcass.grid(row=3, column=0, columnspan=1, sticky=N + S + W + E, padx=2, pady=2) self.tab3_CBstat.grid(row=3, column=1, columnspan=1, sticky=N + S + W + E, padx=2, pady=2) self.save.grid(row=5, column=0, columnspan=4, sticky=N + S + W + E, padx=2, pady=2) # Frame placement self.FrRekur.grid(row=2, column=1, columnspan=3, sticky=N + S + W + E, padx=2, pady=2) # tooltips InfoBulle(self.lab_chps, message=self.dico_help.get(38)[1]) InfoBulle(self.ddl_attr, message=self.dico_help.get(39)[1]) InfoBulle(self.supr, message=self.dico_help.get(40)[1]) InfoBulle(self.tab3_CBcass, message=self.dico_help.get(41)[1]) InfoBulle(self.tab3_CBstat, message=self.dico_help.get(42)[1]) ## Main frame # Hola self.welcome = Label(self, text=self.blabla.get('hi') + self.uzer, font=ft_tit, foreground="red2") # Image self.icone = PhotoImage(master=self, file=r'data/img/metadator.gif') Label(self, image=self.icone).grid(row=2, column=0, padx=2, pady=2, sticky=N + S + W + E) # credits s = Style(self) s.configure('Kim.TButton', foreground='DodgerBlue', borderwidth=0, relief="flat") Button(self, text='by Julien M. (2015)', style='Kim.TButton', command=lambda: open_new('https://github.com/Guts')).grid(row=3, padx=2, pady=2, sticky=W+E) # language switcher self.ddl_lang = Combobox(self, values=li_lang, width=5) self.ddl_lang.current(li_lang.index(self.def_lang)) self.ddl_lang.bind("<<ComboboxSelected>>", self.change_lang) # Go go go button self.val = Button(self, text=self.blabla.get('tab1_go'), state='active', command=lambda: self.process()) # Cancel button self.can = Button(self, text=self.blabla.get('gui_quit'), command=self.destroy) # widgets placement self.welcome.grid(row=0, column=0, columnspan=1, sticky=N + S + W + E, padx=2, pady=2) self.ddl_lang.grid(row=1, column=0, sticky=N, padx=2, pady=0) self.can.grid(row=4, column=0, sticky=N + S + W + E, padx=2, pady=2) self.val.grid(row=4, column=1, sticky=N + S + W + E, padx=2, pady=2) # tooltips InfoBulle(self.ddl_lang, message=self.dico_help.get(32)[1]) ### Notebook placement self.nb.grid(row=0, rowspan=4, column=1, sticky=N + S + W + E) # keep updated list of profiles self.maj() def maj(self): """ update the profiles dropdown list every second """ try: self.li_profiles(self.ddl_lang.get()) self.ddl_profil['values'] = self.li_pro self.after(1000, self.maj) except WindowsError: # avoid an error occuring with browse button self.after(1000, self.maj) pass def alter_state(self, parent, new_state): """ just a function to change easily the state of all children widgets of a parent class parent=Tkinter class with children (Frame, Labelframe, Tk, etc.) new_state=Tkinter keyword for widget state (ACTIVE, NORMAL, DISABLED) """ for child in parent.winfo_children(): child.configure(state=new_state) # end of function return parent, new_state def catalog_dependance(self): """ unselect the catalog option if the word option is unselected """ if self.def_doc.get() == 0: self.def_cat.set(0) self.caz_cat.config(state='disabled') elif self.def_doc.get() == 1: self.caz_cat.config(state='normal') # end of function return def load_settings(self): u""" load settings from last execution """ confile = 'options.ini' config = ConfigParser.RawConfigParser() config.read(confile) # basics self.def_lang = config.get('basics', 'def_codelang') self.def_rep = config.get('basics', 'def_rep') # export preferences self.def_doc.set(config.get('export_preferences', 'def_word')) self.def_cat.set(config.get('export_preferences', 'def_cat')) self.def_xls.set(config.get('export_preferences', 'def_xls')) self.def_xml.set(config.get('export_preferences', 'def_xml')) self.def_dict.set(config.get('export_preferences', 'def_dict')) self.def_odt.set(config.get('export_preferences', 'def_odt')) # log self.logger.info('Last options loaded') # End of function return config, self.def_rep, self.def_lang, self.def_doc def save_settings(self): u""" save options in order to make the next execution easier """ confile = 'options.ini' config = ConfigParser.RawConfigParser() # add sections config.add_section('basics') config.add_section('export_preferences') # basics config.set('basics', 'def_codelang', self.ddl_lang.get()) config.set('basics', 'def_rep', self.target.get()) # export preferences config.set('export_preferences', 'def_word', self.def_doc.get()) config.set('export_preferences', 'def_cat', self.def_cat.get()) config.set('export_preferences', 'def_xls', self.def_xls.get()) config.set('export_preferences', 'def_xml', self.def_xml.get()) config.set('export_preferences', 'def_dict', self.def_dict.get()) config.set('export_preferences', 'def_odt', self.def_odt.get()) # Writing the configuration file with open(confile, 'wb') as configfile: config.write(configfile) # End of function return config def change_lang(self, event): u""" update the texts dictionary with the language selected """ new_lang = event.widget.get() # change to the new language selected self.load_texts(new_lang) self.li_profiles(new_lang) self.li_rekurs(new_lang) self.ddl_profil.delete(0, END) self.ddl_profil.config(values=self.li_pro) self.ddl_profil.update() self.ddl_attr.config(values=self.dico_rekur.keys()) self.recup_help(new_lang) # update widgets text # tab1 self.nb.tab(0, text=self.blabla.get('gui_tab1')) self.welcome.config(text=self.blabla.get('hi') + self.uzer) self.can.config(text=self.blabla.get('gui_quit')) self.FrPath.config(text=self.blabla.get('tab1_fr1')) self.FrProg.config(text=self.blabla.get('tab1_frprog')) self.labtarg.config(text=self.blabla.get('tab1_path')) self.browsetarg.config(text=self.blabla.get('tab1_browse')) self.val.config(text=self.blabla.get('tab1_go')) self.profil.config(text=self.blabla.get('tab1_prof')) # tab2 self.nb.tab(1, text=self.blabla.get('gui_tab2')) self.caz_cat.config(text=self.blabla.get('tab2_merge')) # tab3 self.nb.tab(2, text=self.blabla.get('gui_tab3')) self.lab_chps.config(text=self.blabla.get('tab3_sele')) self.supr.config(text=self.blabla.get('tab3_supp')) self.FrRekur.config(text=self.blabla.get('tab3_tit')) self.tab3_LBnom.config(text=self.blabla.get('tab3_nom')) self.tab3_LBdesc.config(text=self.blabla.get('tab3_desc')) self.tab3_CBcass.config(text=self.blabla.get('tab3_cass')) self.tab3_CBstat.config(text=self.blabla.get('tab3_stat')) self.save.config(text=self.blabla.get('tab3_save')) # End of function return self.blabla def load_texts(self, lang='FR'): u""" Load texts according to the selected language """ # clearing the text dictionary self.blabla.clear() # open xml cursor xml = ET.parse('locale/{0}/lang_{0}.xml'.format(lang)) # Looping and gathering texts from the xml file for elem in xml.getroot().getiterator(): self.blabla[elem.tag] = elem.text # updating the GUI self.update() # en of function return self.blabla def setpathtarg(self): """ ...browse and insert the path of target folder """ foldername = askdirectory(parent=self, initialdir=self.def_rep, mustexist=True, title=self.blabla.get('gui_cible')) # check if a folder has been choosen if foldername: try: self.target.delete(0, END) self.target.insert(0, foldername) except: info(title=self.blabla.get('nofolder'), message=self.blabla.get('nofolder')) return # count shapefiles and MapInfo files in a separated thread proc = threading.Thread(target=self.li_geofiles, args=(foldername, )) proc.daemon = True proc.start() # end of function return foldername def li_geofiles(self, foldertarget): u""" List shapefiles and MapInfo files (.tab, not .mid/mif) contained in the folders structure """ # reseting global variables self.li_shp = [] self.li_tab = [] self.browsetarg.config(state=DISABLED) # Looping in folders structure self.status.set(self.blabla.get('tab1_prog1')) self.prog_layers.start() for root, dirs, files in walk(unicode(foldertarget)): self.num_folders = self.num_folders + len(dirs) for f in files: """ looking for files with geographic data """ try: unicode(path.join(root, f)) full_path = path.join(root, f) except UnicodeDecodeError: full_path = path.join(root, f.decode('latin1')) # Looping on files contained if path.splitext(full_path.lower())[1].lower() == '.shp'\ and (path.isfile('{0}.dbf'.format(full_path[:-4])) or path.isfile('{0}.DBF'.format(full_path[:-4])))\ and (path.isfile('{0}.shx'.format(full_path[:-4])) or path.isfile('{0}.SHX'.format(full_path[:-4]))): """ listing compatible shapefiles """ # add complete path of shapefile self.li_shp.append(full_path) elif path.splitext(full_path.lower())[1] == '.tab'\ and (path.isfile(full_path[:-4] + '.dat') or path.isfile(full_path[:-4] + '.DAT'))\ and (path.isfile(full_path[:-4] + '.map') or path.isfile(full_path[:-4] + '.MAP'))\ and (path.isfile(full_path[:-4] + '.id') or path.isfile(full_path[:-4] + '.ID')): """ listing MapInfo tables """ # add complete path of MapInfo file self.li_tab.append(full_path) # stopping the progress bar self.prog_layers.stop() # Lists ordering and tupling self.li_shp.sort() self.li_shp = tuple(self.li_shp) self.li_tab.sort() self.li_tab = tuple(self.li_tab) # setting the label text and activing the buttons self.status.set(unicode(len(self.li_shp)) + u' shapefiles - ' + unicode(len(self.li_tab)) + u' tables (MapInfo) - ' + unicode(self.num_folders) + self.blabla.get('log_numfold')) self.browsetarg.config(state=ACTIVE) self.val.config(state=ACTIVE) # End of function return foldertarget, self.li_shp, self.li_tab def li_profiles(self, lang): u""" list profiles already existing """ # reseting global variable self.li_pro = [] # Looping in folders structure folder_profiles = path.join('locale/', lang + '/profiles/') self.li_pro = [lg[:-4] for lg in listdir(folder_profiles)] self.li_pro.append(self.blabla.get('tab1_new')) # End of function return folder_profiles, self.li_pro def li_rekurs(self, lang): u""" List recurring attributes that already exist in the selected language """ # clearing the text dictionary self.dico_rekur.clear() champis = path.abspath(r'locale/{0}/champignons_{0}.xml'.format(lang)) xml = ET.parse(champis) # Looping and gathering texts from the xml file for elem in xml.findall('champ'): rek_name = elem.find('intitule').text rek_desc = elem.find('description').text rek_kass = elem.find('case').text rek_stat = elem.find('stats').text self.dico_rekur[rek_name] = rek_desc, rek_kass, rek_stat self.dico_rekur[self.blabla.get('tab3_new')] = '', 0, 0 # updating the GUI self.update() # End of function return self.dico_rekur def edit_rekur(self, event): u""" preparing the form to edit a recurring attribute """ rekur = event.widget.get() # deactivate the selector self.ddl_attr.config(state=DISABLED) # activate the form self.alter_state(self.FrRekur, NORMAL) # change to the new language selected self.tab3_ENnom.insert(0, rekur) self.tab3_TXdesc.insert(1.0, self.dico_rekur.get(rekur)[0]) self.def_kass.set(self.dico_rekur.get(rekur)[1]) self.def_stat.set(self.dico_rekur.get(rekur)[2]) # End of function return self.dico_rekur def save_rekur(self): u""" save the recurring attribute edited """ # check if the attribute already exists if self.tab3_ENnom.get() in self.dico_rekur: if not askyesno(title=self.blabla.get('tab3_alert_exist1'), message=self.blabla.get('tab3_alert_exist2')): return else: pass else: pass # save self.dico_rekur[self.tab3_ENnom.get()] = self.tab3_TXdesc.get(1.0, END).rstrip(),\ self.def_kass.get(),\ self.def_stat.get() # reset the form self.tab3_ENnom.delete(0, END) self.tab3_TXdesc.delete(1.0, END) self.def_kass.set(0) self.def_stat.set(0) # deactivate the form self.alter_state(self.FrRekur, DISABLED) # updating the dropdown list self.ddl_attr.config(state=NORMAL) self.ddl_attr.delete(0, END) self.ddl_attr['values'] = self.dico_rekur.keys() # End of function return self.dico_rekur def del_rekur(self): u""" delete the selected recurring attribute """ # reactivate the selector self.ddl_attr.config(state=ACTIVE) self.dico_rekur.pop(self.ddl_attr.get()) self.ddl_attr.delete(0, END) self.ddl_attr['values'] = self.dico_rekur.keys() # reset the form self.tab3_ENnom.delete(0, END) self.tab3_TXdesc.delete(1.0, END) self.def_kass.set(0) self.def_stat.set(0) # deactivate the form self.alter_state(self.FrRekur, DISABLED) # End of function return self.dico_rekur def saveas_rekurs(self, lang): u""" save the recurring fields into the file dedicated """ rekur = ET.Element(u'champs') xml_path = r'locale/{0}/champignons_{0}.xml'.format(lang) self.dico_rekur.pop(self.blabla.get('tab3_new')) with open(xml_path, 'w') as champis: for elem in self.dico_rekur.keys(): rek = ET.SubElement(rekur, u'champ') # name of recurring attribute rek_name = ET.SubElement(rek, u'intitule') rek_name.text = elem # description of recurring attribute rek_desc = ET.SubElement(rek, u'description') rek_desc.text = self.dico_rekur.get(elem)[0] # stats option of recurring attribute rek_stats = ET.SubElement(rek, u'stats') rek_stats.text = unicode(self.dico_rekur.get(elem)[1]) # case sensitive option of recurring attribute rek_case = ET.SubElement(rek, u'case') rek_case.text = unicode(self.dico_rekur.get(elem)[2]) # creating the xml tree out_rekurs = ET.ElementTree(rekur) # saving it out_rekurs.write(xml_path, encoding='utf-8', xml_declaration='version="1.0"', method='xml') # End of function return self.dico_rekur def select_profil(self, event): """ when a profile is selected... """ profsel = event.widget.get() # if user wants to use an existing profile or create a new one if profsel == self.blabla.get('tab1_new'): self.val.config(text=self.blabla.get('tab1_crprofil')) else: self.val.config(text=self.blabla.get('tab1_go')) # end of function return self.val def recup_profil(self, lang): """ get the information from the profile selected """ # clearing the profile dictionary self.dico_profil.clear() # specific path to profile file path_profile = path.join('locale/{0}/profiles/{1}.xml'.format(lang, self.ddl_profil.get())) with open(path_profile, 'r') as profile: # open xml parser xml = ET.parse(profile) # basic informations self.dico_profil['description'] = xml.find('description').text self.dico_profil['sources'] = xml.find('sources').text self.dico_profil['url'] = xml.find('url').text self.dico_profil['url_label'] = xml.find('url_label').text self.dico_profil[u'diffusion'] = xml.find('diffusion').text # data language lang_data = xml.find(u'lang_data') self.dico_profil[u"lang_data"] = lang_data.find(u'name').text # metadata language lang_metad = xml.find(u'lang_metad') self.dico_profil[u"lang_md"] = lang_metad.find(u'name').text # diffusion constraints diff = xml.find(u'diffusion') self.dico_profil['diffusion'] = diff.find(u'name').text # update rythm rythm = xml.find(u'rythm') self.dico_profil['rythm'] = rythm.find(u'name').text # INSPIRE themes themes = xml.find('themesinspire') li_themesinspire = [theme.find('name').text for theme in themes.findall('theme')] self.dico_profil['themesinspire'] = li_themesinspire # custom keywords keywords = xml.find('keywords') li_keywords = [keyword.find('name').text for keyword in keywords.findall('keyword')] self.dico_profil['keywords'] = li_keywords # places keywords geokeywords = xml.find('geokeywords') li_geokeywords = [geokeyword.find('name').text for geokeyword in geokeywords.findall('geokeyword')] self.dico_profil['geokeywords'] = li_geokeywords # contacts contacts = xml.find(u'contacts') # point of contact cont = contacts.find(u'pointdecontact') self.dico_profil[u'cont_name'] = cont.find(u'name').text self.dico_profil[u'cont_orga'] = cont.find(u'org').text self.dico_profil[u'cont_mail'] = cont.find(u'mail').text self.dico_profil[u'cont_role'] = cont.find(u'role').text self.dico_profil[u'cont_func'] = cont.find(u'func')[0].text self.dico_profil[u'cont_street'] = cont.find(u'street').text self.dico_profil[u'cont_city'] = cont.find(u'city').text self.dico_profil[u'cont_cp'] = cont.find(u'cp').text self.dico_profil[u'cont_country'] = cont.find(u'country').text self.dico_profil[u'cont_phone'] = cont.find(u'tel').text # second contact (responsable, etc.) resp = contacts.find(u'second_contact') self.dico_profil[u'resp_name'] = resp.find(u'name').text self.dico_profil[u'resp_orga'] = resp.find(u'org').text self.dico_profil[u'resp_mail'] = resp.find(u'mail').text self.dico_profil[u'resp_role'] = resp.find(u'role').text self.dico_profil[u'resp_func'] = resp.find(u'func')[0].text self.dico_profil[u'resp_street'] = resp.find(u'street').text self.dico_profil[u'resp_city'] = resp.find(u'city').text self.dico_profil[u'resp_cp'] = resp.find(u'cp').text self.dico_profil[u'resp_country'] = resp.find(u'country').text self.dico_profil[u'resp_phone'] = resp.find(u'tel').text # End of function return self.dico_profil def recup_help(self, lang): """ get the help texts """ # specific path to xml file path_help = 'locale/%s/help_%s.xml' % (lang, lang) # reading and parsing the xml with open(path_help, 'r') as source: xml = ET.parse(source) # xml cursor for tooltip in xml.findall('tooltip'): idu = tooltip.find('id').text ref = tooltip.find('ref').text txt = tooltip.find('txt').text img = tooltip.find('image').text doc = tooltip.find('doc').text # fillfulling the INSPIRE dictionary self.dico_help[int(idu)] = ref, txt, img, doc # End of function return self.dico_help def process(self): u""" launch the different processes """ # display the main tab self.nb.select(0) # check option selected: process or create a new profile if self.ddl_profil.get() == self.blabla.get('tab1_new'): # launching the profile form self.logger.info('Creation of a new profile') tr_profile = threading.Thread(target=NewProfile, args=(self.blabla, self.ddl_lang.get(), self.dico_help, self.li_pro)) tr_profile.daemon = True tr_profile.run() # NewProfile(self.blabla, self.ddl_lang.get(), self.li_pro) self.li_profiles(self.ddl_lang.get()) # updating the dropdow list self.ddl_profil['values'] = self.li_pro return # check if the target folder has been selected if self.target.get() == "": info(title=self.blabla.get('info_blanktarget1'), message=self.blabla.get('info_blanktarget2')) return # check if a profile has been selected if self.ddl_profil.get() == "": info(title=self.blabla.get('info_blankprofile1'), message=self.blabla.get('info_blankprofile2')) return # disabling others GUI parts self.tab_globals.focus_force() self.alter_state(self.FrPath, DISABLED) # check if there are some layers into the folder structure if len(self.li_shp) + len(self.li_tab) == 0: self.logger.warning("No geofiles found in the folder structure") self.status.set(self.blabla.get('log_nodata')) return # specific variables dest = path.join(self.target.get(), 'metadator') if not path.isdir(dest): # test if folder already exists mkdir(dest, 0777) # if not, we create it # getting profile informations self.recup_profil(self.ddl_lang.get()) # saving options in a separated thread tr_options = threading.Thread(target=self.save_settings) tr_options.daemon = True tr_options.start() self.logger.info('Current options saved') # saving recurring fiels in a separated thread tr_rekurs = threading.Thread(target=self.saveas_rekurs, args=(self.ddl_lang.get(), )) tr_rekurs.daemon = True tr_rekurs.start() # configuring the progression bar self.prog_layers["maximum"] = len(self.li_shp) + len(self.li_tab) self.prog_layers["value"] # Processing the shapefiles self.logger.info('\tStart processing the files') for shp in self.li_shp: """ looping on shapefiles list """ self.logger.info('Processing: %s' % path.basename(shp)) self.status.set(path.basename(shp)) # reset recipient data self.dico_layer.clear() self.dico_fields.clear() # getting separated process threads Read_SHP(shp, self.dico_layer, self.dico_fields, 'shape', self.blabla) # checking layer error if self.dico_layer.get('error'): # increment the progress bar self.prog_layers["value"] = self.prog_layers["value"] + 1 self.update() self.logger.warning('This shape has an issue: %s' % shp) continue # getting fields statistics only if needed if self.def_doc.get() == 1 or self.def_xls.get() == 1 or self.def_odt.get() == 1: StatsFields(shp, self.dico_fields, self.dico_rekur, self.blabla) # export according to options selected if self.def_doc.get() == 1: ExportToHTML(dest, self.dico_layer, self.dico_fields, self.dico_profil, self.dico_rekur, self.blabla) html_path = path.join(dest, "{0}_MD.html".format(self.dico_layer['name'][:-4])) ExportToDocX(html_path, dest) if self.def_xls.get() == 1: ExportToXLS(dest, self.dico_layer, self.dico_fields, self.dico_profil, self.dico_rekur, self.blabla) if self.def_xml.get() == 1: ExportToXML(dest, self.dico_layer, self.dico_profil, '', self.blabla, 1, 0) if self.def_odt.get() == 1: ExportToODT(dest, self.dico_layer, self.dico_fields, self.dico_profil, self.dico_rekur, self.blabla) # increment the progress bar self.prog_layers["value"] = self.prog_layers["value"] + 1 self.update() # Processing the MapInfo tables for tab in self.li_tab: """ looping on MapInfo tables list """ self.logger.info('Processing: %s' % path.basename(tab)) self.status.set(path.basename(tab)) # reset recipient data self.dico_layer.clear() self.dico_fields.clear() # getting the informations Read_TAB(tab, self.dico_layer, self.dico_fields, 'table', self.blabla) # checking layer error if self.dico_layer.get('error'): self.logger.warning('This MapInfo table has an issue: %s' % tab) # increment the progress bar self.prog_layers["value"] = self.prog_layers["value"] +1 self.update() continue # getting fields statistics only if needed if self.def_doc.get() == 1 \ or self.def_xls.get() == 1 \ or self.def_odt.get() == 1: StatsFields(tab, self.dico_fields, self.dico_rekur, self.blabla) # export according to options selected if self.def_doc.get() == 1: ExportToHTML(dest, self.dico_layer, self.dico_fields, self.dico_profil, self.dico_rekur, self.blabla) html_path = path.join(dest, "{0}_MD.html".format(self.dico_layer['name'][:-4])) ExportToDocX(html_path, dest) if self.def_xls.get() == 1: ExportToXLS(dest, self.dico_layer, self.dico_fields, self.dico_profil, self.dico_rekur, self.blabla) if self.def_xml.get() == 1: ExportToXML(dest, self.dico_layer, self.dico_profil, '', self.blabla, 1, 0) if self.def_odt.get() == 1: ExportToODT(dest, self.dico_layer, self.dico_fields, self.dico_profil, self.dico_rekur, self.blabla) # increment the progress bar self.prog_layers["value"] = self.prog_layers["value"] + 1 self.update() # Word catalog export if self.def_doc.get() == 1 and self.def_cat.get() == 1: self.status.set(self.blabla.get('info_cat')) self.update() DocxMerger(dest, '00_Metadator_Catalog', 'metadator_') else: pass # final message # msg = self.blabla.get('info_end2') + self.blabla.get('info_end3') # info(title=self.blabla.get('info_end'), message=msg) # opening the destination folder self.open_dir_file(dest) # cleaning up logging.info('Hurray! It worked! All seem to have been fine!') self.destroy() # end of function return def open_dir_file(self, target): """ Open a file or a directory in the explorer of the operating system http://sametmax.com/ouvrir-un-fichier-avec-le-bon-programme-en-python """ # check if the file or the directory exists if not path.exists(target): raise IOError('No such file: {0}'.format(target)) # check the read permission if not access(target, R_OK): raise IOError('Cannot access file: {0}'.format(target)) # open the directory or the file according to the os if opersys == 'win32': # Windows proc = startfile(target) elif opersys.startswith('linux'): # Linux: proc = subprocess.Popen(['xdg-open', target], stdout=subprocess.PIPE, stderr=subprocess.PIPE) elif opersys == 'darwin': # Mac: proc = subprocess.Popen(['open', '--', target], stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: raise NotImplementedError( "Your `%s` isn't a supported operating system`." % opersys) # end of function return proc