class Oscilloscope(Frame): """ Modele d'Oscilloscope time : valeur de la base de temps signal : liste de couples, (temps,elongation) ou (elongation X, elongation Y) de signaux view : visualisation de signaux control_X : controle d'un signal control_time : controle de la base de temps """ def __init__(self, parent=None, width=800, height=800): """ Initialisation parent : une application width,height : dimension de l'oscilloscpe """ Frame.__init__(self) self.master.title("Oscilloscope") # Barre de menu menuBar = MenuBar(parent=self) menuBar.pack(side="top") # Hauteur & largeur self.width = width self.height = height # Modele self.time = 0 self.signal = None # Vues self.view = Screen(parent=self) # Controleurs self.control_time = TimeBase(parent=self) self.control_X = Generator(parent=self) self.control_Y = Generator(parent=self, name="Y") self.control_L = Lissajou(parent=self) self.signalSelected = SignalSelected(parent=self) # Affichage Vues, Controleurs self.signalSelected.pack(side="left", fill="y") self.view.pack(fill="both", expand=1) self.control_time.pack(fill="both", expand=1) self.control_X.pack(side="left", fill="both", expand=1) self.control_L.pack(side="left") self.control_Y.pack(side="right", fill="both", expand=1) self.configure(width=width, height=height) def get_time(self): """ recuperer la valeur courante de la base de temps """ return self.control_time.get_time() def update_time(self, time): """ calcul de signal si modification de la base de temps time : nouvelle valeur de la base de temps """ if self.time != time: self.time = time self.control_X.update_signal(None) self.control_Y.update_signal(None) def update_view(self, name="X", signal=None): """ demande d'affichage de signal name : nom de la courbe (X,Y, X-Y) signal : liste des couples (temps,elongation) ou (elongation X, elongation Y) """ msdiv = self.get_time() if signal: signal = signal[0:(len(signal) / msdiv) + 1] signal = map(lambda (x, y): (x * msdiv, y), signal) self.view.plot_signal(name, signal) return signal
class Oscilloscope(Frame): def __init__(self, parent=None, width=800, height=800): """ Proprietes : - un ecran (classe Screen) - vibrations harmoniques (classe Vibration) - base de temps (classe TimeBase) Methodes : - get_time(self) : demander le temps de la base de temps - update_time(self, time) : calcul de vibration si mise a jour base de temps - draw_curve(self, name, curve) : demander affichage d'une courbe """ Frame.__init__(self) self.time = 0 self.master.title("Oscilloscope") self.screen = Screen(parent=self) self.time_base = TimeBase(parent=self) self.vib_X = Vibration(parent=self, color="blue") self.curveX = None self.menuBar = MenuBar(self) self.menuBar.pack() self.screen.pack() self.vib_X.pack() self.time_base.pack() self.configure(width=width, height=height) def get_time(self): """ Retour : valeur courante de la base de temps """ return self.time_base.get_time() def update_time(self, time): """ Si modification base de temps : calcul vibration """ if self.time != time: self.time = time self.curveX = self.vib_X.compute(a=self.vib_X.scale_A.get(), f=self.vib_X.scale_F.get(), p=self.vib_X.scale_P.get(), timeBase=self.get_time()) self.draw_curve("X", self.curveX) def draw_curve(self, name="X", curve=None): """ demande d'affichage de courbe """ self.screen.draw_curve(name, curve) ######### #event def exit(self): """ Quitte le programme en demandant si l'on veut sauvegarder son programme """ self.quit() def save(self): """ Sauvegarde la courbe dans un fichier """ data = cPickle.dump(self.curveX) print "sauvegarde du fichier" print data
class Oscilloscope(Frame): """ Oscilloscope time : valeur de la base de temps signaux : liste de couples, (temps,elongation) ou (elongation X, elongation Y) de signaux screen : ecran de visualisation de signaux time_control : controle de la base de temps signal_control : controle d'un signal """ def __init__(self, parent=None, width=800, height=800): """ initialisation parent : une application width,height : dimension de l'oscilloscpe """ Frame.__init__(self) self.master.title("Oscilloscope") # Modele self.time = 0 self.signal = None # Vues self.menuBar = MenuBar(parent=self) self.screen = Screen(parent=self) self.frame = Frame(master=self) # Controleurs self.time_control = TimeBase(parent=self) self.signal_controlX = Generator(parent=self, name="X", color="red") self.signal_controlY = Generator(parent=self, name="Y", color="blue") # Affichage Vues, Controleurs self.menuBar.pack() self.screen.pack() self.signal_controlX.pack(side="left") self.signal_controlY.pack(side="left") self.time_control.pack() self.configure(width=width, height=height) def get_time(self): """valeur courante de la base de temps.""" return self.time_control.get_time() def update_time(self, time): """demande de calcul de signal si modification de la base de temps""" if self.time != time: self.time = time self.signal_controlX.update_signal(None) self.signal_controlY.update_signal(None) def set_signal(self, name="X", signal=None): """ demande d'affichage de signal name : nom de la courbe (X,Y, X-Y) signal : liste des couples (temps,elongation) ou (elongation X, elongation Y) """ print("Base de Temps :", self.get_time()) msdiv = self.get_time() if signal : signal = signal[0:(len(signal)/msdiv) + 1] signal = map(lambda (x, y): (x*msdiv, y), signal) self.screen.plot_signal(name, signal) return signal
class Oscilloscope(Frame): """ Oscilloscope time : valeur de la base de temps signaux : liste de couples, (temps,elongation) ou (elongation X, elongation Y) de signaux screen : ecran de visualisation de signaux time_control : controle de la base de temps signal_control : controle d'un signal """ def __init__(self, parent=None, width=800, height=800): """ initialisation parent : une application width,height : dimension de l'oscilloscpe """ Frame.__init__(self) self.master.title("Oscilloscope") # Modelethreading.Thread(None, affiche, None, (200,), {'nom':'thread a'}) self.time = 0 self.signal = None # # Vues # self.menuBar = MenuBar(parent=self) # self.screen = Screen(parent=self) # self.frame = Frame(master=self) # # Controleurs # self.time_control = TimeBase(parent=self) # self.signal_controlX = Generator(parent=self, name="X", color="red") # self.signal_controlY = Generator(parent=self, name="Y", color="blue") # # Affichage Vues, Controleurs # self.menuBar.pack() # self.screen.pack() # self.signal_controlX.pack(side="left") # self.signal_controlY.pack(side="left") # self.time_control.pack() # Vues self.menuBar = MenuBar(parent=self) self.screenT = Screen(parent=self) self.screenXY = Screen(parent=self) # Controleurs self.signal_controlX = Generator(parent=self, name="X", color="red") self.signal_controlY = Generator(parent=self, name="Y", color="blue") self.signal_controlXY = Generator(parent=self, name="XY", color="blue") self.time_control = TimeBase(parent=self) self.varX = IntVar() self.varY = IntVar() self.varXY = IntVar() self.showX = Checkbutton(parent, text="X", variable=self.varX, command=lambda: self.update_show("X")) self.showY = Checkbutton(parent, text="Y", variable=self.varY, command=lambda: self.update_show("Y")) self.showXY = Checkbutton(parent, text="XY", variable=self.varXY, command=lambda: self.update_show("XY")) self.varX.set(1) self.varY.set(1) self.varXY.set(1) # Affichage Vues, Controleurs self.menuBar.grid(column=0, row=0) self.screenT.grid(column=0,row=1) self.screenXY.grid(column=1,row=1) self.signal_controlX.grid(column=0, row=2) self.signal_controlY.grid(column=0, row=3) self.time_control.grid(column=0, row=4) self.showX.grid(column=1, row=2) self.showY.grid(column=1, row=3) self.showXY.grid(column=1, row=4) self.configure(width=width, height=height) def get_time(self): """valeur courante de la base de temps.""" return self.time_control.get_time() def update_time(self, time): """demande de calcul de signal si modification de la base de temps""" if self.time != time: self.time = time self.signal_controlX.update_signal(None) self.signal_controlY.update_signal(None) def set_signal(self, name="X", signal=None , color =None): """ demande d'affichage de signal name : nom de la courbe (X,Y, X-Y) signal : liste des couples (temps,elongation) ou (elongation X, elongation Y) """ #print("Base de Temps :", self.get_time()) msdiv = self.get_time() if signal : signal = signal[0:(len(signal)/msdiv) + 1] signal = map(lambda (x, y): (x*msdiv, y), signal) #Search if the signal need to be shown self.screenT.change_signal(name, signal,color) listCurveScreenT = self.screenT.listCurve if len(listCurveScreenT) > 1: listCurveX = listCurveScreenT[0] listCurveY = listCurveScreenT[1] curveXY= [] for i in range(len(listCurveX)-1): #create a new curve using the elongation of X & Y curves curveXY.append((listCurveX[1][i][1]+0.05,listCurveY[1][i][1])) self.screenXY.change_signal("XY", curveXY, "green") return signal def update_show(self, name= None): """ Function permettant de changer l'état d'une courbe ( affichée ou non) en fonction des checkbox """ #print "EtatX", self.varX.get(), " EtatY" , self.varY.get(), " EtatY" , self.varXY.get() #print name if name == "X": self.screenT.show_curve(name, self.varX.get()) elif name =="Y": self.screenT.show_curve(name, self.varY.get()) elif name =="XY": self.screenXY.show_curve(name, self.varXY.get()) #self.signal_controlX.update_signal(None) #self.signal_controlY.update_signal(None) def exit(self): """ Prend en charge l'appui sur la croix pour quitter l'application, va stopper les threads """ if tkMessageBox.askokcancel("Quitter l'application?", "Etes vous sur de vouloir quitter l'application oscilloscope?"): self.screenT.stop_draw() self.screenXY.stop_draw() self.master.quit()
class Oscilloscope(Frame): """ Modele d'Oscilloscope time : valeur de la base de temps signal : liste de couples, (temps,elongation) ou (elongation X, elongation Y) de signaux view : visualisation de signaux control_X : controle d'un signal control_time : controle de la base de temps """ def __init__(self, parent=None, width=800, height=800): """ Initialisation parent : une application width,height : dimension de l'oscilloscpe """ Frame.__init__(self) self.master.title("Oscilloscope - Diquélou - Toscer") # doit-on afficher la courbe de lissajoux self.drawXY = IntVar() # Modele self.time = 0 # gestion des signaux X et Y self.signal_X = None self.signal_Y = None self.signal_XY = None # Vues self.view = Screen(parent=self) self.lissajoux = Screen(parent= self) # Controleurs self.control_time = TimeBase(parent=self) self.control_X = Generator(self,'X') self.control_Y = Generator(self, 'Y') # menu menuBar = MenuBar(self) menuBar.pack(fill="x"); # Affichage Vues, Controleurs self.view.pack(fill="both") self.control_time.pack(side="left", fill="y") self.control_X.pack(side="left",fill="y") self.lissajoux.pack(fill="both", side="left", expand=1) self.control_Y.pack(side="right", fill="both") self.configure(width=width, height=height) self.master.protocol("WM_DELETE_WINDOW", self.quitter) def get_time(self): """ recuperer la valeur courante de la base de temps """ return self.control_time.get_time() def update_time(self, time): """ calcul de signal si modification de la base de temps time : nouvelle valeur de la base de temps """ if self.time != time: self.time = time self.control_X.update_signal(None) self.control_Y.update_signal(None) def plot_all(self): """ affiche tous les signaux """ self.update_view('X',self.control_X.signal) self.update_view('Y',self.control_Y.signal) self.update_view('XY',self.control_X.signal) def update_view(self, name="X", signal=None): """ demande d'affichage de signal name : nom de la courbe (X,Y, X-Y) signal : liste des couples (temps,elongation) ou (elongation X, elongation Y) """ print("Base de Temps :", self.get_time()) msdiv = self.get_time() if signal : if name!='XY': signal = signal[0:(len(signal)/msdiv) + 1] signal = map(lambda (x, y): (x*msdiv, y), signal) self.view.plot_signal(name, signal) else: self.signal_XY = [] for i in range(0, len(self.control_X.signal)): self.signal_XY.append((self.control_X.signal[i][1],self.control_Y.signal[i][1])) self.lissajoux.plot_signal('XY',self.signal_XY) return signal def about(self): """ Affiche les infos des créateurs """ tkMessageBox.showinfo('Super oscilloscope', 'v0.1.5\n\n\tYoann Diquélou\n\tLeïla Toscer\n\n# Copyright (C) 2015 by ENIB-CAI') def save(self): """ Sauvegarde la courbe sauvegarde au format temps|amplitude|frequence|phase """ print "Oscilloscope.save()" saveTxt = {} saveTxt["timebase"] = self.time saveTxt["graphs"] = [] saveTxt["graphs"].append( self.getGraphInfos(self.control_X)) saveTxt["graphs"].append( self.getGraphInfos(self.control_Y)) filename = tkFileDialog.asksaveasfilename(title="Sauvegarder un graphe", filetypes=[('oscillographe file','.osc'),('all files', '.*')]) print json.dumps(saveTxt, indent=4) if filename: file = open(filename,'w') file.write(json.dumps(saveTxt, indent=4)) #file.write(str(self.time)+'|'+str(self.control_X.drawVar.get())+'|'+str(self.control_Y.drawVar.get())+'\n'+str(self.control_X.scale_A.get())+'|'+str(self.control_X.scale_F.get())+'|'+str(self.control_X.scale_P.get())+'|\n'+str(self.control_Y.scale_A.get())+'|'+str(self.control_Y.scale_F.get())+'|'+str(self.control_Y.scale_P.get())+'|\n') # fermeture du fichier file.close() def load(self): """ Charger la courbe """ print "Oscilloscope.load()" file = tkFileDialog.askopenfile(title="Ouvrir un graphe", filetypes=[('oscillographe file','.osc'),('all files', '.*')]) if file: #data = file.readline().rstrip('\r\n') # vérification que le texte est en accord avec le format # regex = re.compile('^[0-9]{1,2}\|[0-9]{1,2}\|[0-9]{1,2}\|[0-9]{1,2}$') # regex = re.compile('^([0-9]{1,2}\|){4}$') # if(regex.match(data)): # print "Format ok, loading\n" # a = re.split('\|+', data, flags = re.IGNORECASE) # self.control_time.scale_time.set(int(a[0])) # self.control_X.scale_A.set(int(a[1])) # self.control_X.scale_F.set(int(a[2])) # self.control_X.scale_P.set(int(a[3])) # else: # print "Fichier incorrect" # tkMessageBox.showerror('ERREUR', # 'Entrez un fichier valide, merci.') format = json.load(file) self.control_time.scale_time.set( format["timebase"]) for i in range(0 ,len(format["graphs"])): eval('self.control_'+format["graphs"][i]["name"]+'.scale_A.set('+str(format["graphs"][i]["amp"])+')') eval('self.control_'+format["graphs"][i]["name"]+'.scale_F.set('+str(format["graphs"][i]["freq"])+')') eval('self.control_'+format["graphs"][i]["name"]+'.scale_P.set('+str(format["graphs"][i]["phi"])+')') if format["graphs"][i]["active"]==1: eval('self.control_'+format["graphs"][i]["name"]+'.draw.select()') else: eval('self.control_'+format["graphs"][i]["name"]+'.draw.deselect()') # if format["graphs"][i]["name"] == 'X': # self.control_X.scale_A.set(format["graphs"][i]["amp"]) # self.control_X.scale_F.set(format["graphs"][i]["freq"]) # self.control_X.scale_P.set(format["graphs"][i]["phi"]) # if format["graphs"][i]["active"]==1: # self.control_X.draw.select() # else: # self.control_X.draw.deselect() # else: # self.control_Y.scale_A.set(format["graphs"][i]["amp"]) # self.control_Y.scale_F.set(format["graphs"][i]["freq"]) # self.control_Y.scale_P.set(format["graphs"][i]["phi"]) # if format["graphs"][i]["active"]==1: # self.control_Y.draw.select() # else: # self.control_Y.draw.deselect() file.close() def getGraphInfos(self, graph): graphique = {} graphique["name"] = graph.name graphique["active"] = graph.drawVar.get() graphique["amp"] = graph.scale_A.get() graphique["freq"] = graph.scale_F.get() graphique["phi"] = graph.scale_P.get() return graphique def quitter(self): """ Affiche une boite de dialogue pour que l'utilisateur confirme son souhait de quitter """ if tkMessageBox.askyesno('Quitter', 'voulez-vous quitter?'): print "Oscilloscope.quitter()" self.quit()
class Oscilloscope(Frame): """ Modele d'Oscilloscope time : valeur de la base de temps signal : liste de couples, (temps,elongation) ou (elongation X, elongation Y) de signaux view : visualisation de signaux control_X : controle d'un signal control_time : controle de la base de temps """ def __init__(self, parent=None, width=800, height=800): """ Initialisation parent : une application width,height : dimension de l'oscilloscpe """ Frame.__init__(self) self.master.title("Oscilloscope - Diquélou - Toscer") # doit-on afficher la courbe de lissajoux self.drawXY = IntVar() # Modele self.time = 0 # gestion des signaux X et Y self.signal_X = None self.signal_Y = None self.signal_XY = None # Vues self.view = Screen(parent=self) self.lissajoux = Screen(parent= self) # Controleurs self.control_time = TimeBase(parent=self) self.control_X = Generator(self,'X') self.control_Y = Generator(self, 'Y') # menu menuBar = MenuBar(self) menuBar.pack(fill="x"); # Affichage Vues, Controleurs self.view.pack(fill="both") self.control_time.pack(side="left", fill="y") self.control_X.pack(side="left",fill="y") self.lissajoux.pack(fill="both", side="left", expand=1) self.control_Y.pack(side="right", fill="both") self.configure(width=width, height=height) self.master.protocol("WM_DELETE_WINDOW", self.quitter) def get_time(self): """ recuperer la valeur courante de la base de temps """ return self.control_time.get_time() def update_time(self, time): """ calcul de signal si modification de la base de temps time : nouvelle valeur de la base de temps """ if self.time != time: self.time = time self.control_X.update_signal(None) self.control_Y.update_signal(None) def plot_all(self): """ affiche tous les signaux """ self.update_view('X',self.control_X.signal) self.update_view('Y',self.control_Y.signal) self.update_view('XY',self.control_X.signal) def update_view(self, name="X", signal=None): """ demande d'affichage de signal name : nom de la courbe (X,Y, X-Y) signal : liste des couples (temps,elongation) ou (elongation X, elongation Y) """ print("Base de Temps :", self.get_time()) msdiv = self.get_time() if signal : if name!='XY': signal = signal[0:(len(signal)/msdiv) + 1] signal = map(lambda (x, y): (x*msdiv, y), signal) self.view.plot_signal(name, signal) else: self.signal_XY = [] for i in range(0, len(self.control_X.signal)): self.signal_XY.append((self.control_X.signal[i][1],self.control_Y.signal[i][1])) self.lissajoux.plot_signal('XY',self.signal_XY) return signal def about(self): """ Affiche les infos des créateurs """ tkMessageBox.showinfo('Super oscilloscope', 'v0.1.5\n\n\tYoann Diquélou\n\tLeïla Toscer\n\n# Copyright (C) 2015 by ENIB-CAI') def save(self): """ Sauvegarde la courbe sauvegarde au format temps|amplitude|frequence|phase """ print "Oscilloscope.save()" saveTxt = {} saveTxt["timebase"] = self.time saveTxt["graphs"] = [] saveTxt["graphs"].append( self.getGraphInfos(self.control_X)) saveTxt["graphs"].append( self.getGraphInfos(self.control_Y)) filename = tkFileDialog.asksaveasfilename(title="Sauvegarder un graphe", filetypes=[('oscillographe file','.osc'),('all files', '.*')]) print json.dumps(saveTxt, indent=4) if filename: file = open(filename,'w') file.write(json.dumps(saveTxt, indent=4)) #file.write(str(self.time)+'|'+str(self.control_X.drawVar.get())+'|'+str(self.control_Y.drawVar.get())+'\n'+str(self.control_X.scale_A.get())+'|'+str(self.control_X.scale_F.get())+'|'+str(self.control_X.scale_P.get())+'|\n'+str(self.control_Y.scale_A.get())+'|'+str(self.control_Y.scale_F.get())+'|'+str(self.control_Y.scale_P.get())+'|\n') # fermeture du fichier file.close() def load(self): """ Charger la courbe """ print "Oscilloscope.load()" file = tkFileDialog.askopenfile(title="Ouvrir un graphe", filetypes=[('oscillographe file','.osc'),('all files', '.*')]) if file: #data = file.readline().rstrip('\r\n') # vérification que le texte est en accord avec le format # regex = re.compile('^[0-9]{1,2}\|[0-9]{1,2}\|[0-9]{1,2}\|[0-9]{1,2}$') # regex = re.compile('^([0-9]{1,2}\|){4}$') # if(regex.match(data)): # print "Format ok, loading\n" # a = re.split('\|+', data, flags = re.IGNORECASE) # self.control_time.scale_time.set(int(a[0])) # self.control_X.scale_A.set(int(a[1])) # self.control_X.scale_F.set(int(a[2])) # self.control_X.scale_P.set(int(a[3])) # else: # print "Fichier incorrect" # tkMessageBox.showerror('ERREUR', # 'Entrez un fichier valide, merci.') format = json.load(file) self.control_time.scale_time.set( format["timebase"]) for i in range(0 ,len(format["graphs"])): eval('self.control_'+format["graphs"][i]["name"]+'.scale_A.set('+str(format["graphs"][i]["amp"])+')') eval('self.control_'+format["graphs"][i]["name"]+'.scale_F.set('+str(format["graphs"][i]["freq"])+')') eval('self.control_'+format["graphs"][i]["name"]+'.scale_P.set('+str(format["graphs"][i]["phi"])+')') if format["graphs"][i]["active"]==1: eval('self.control_'+format["graphs"][i]["name"]+'.draw.select()') else: eval('self.control_'+format["graphs"][i]["name"]+'.draw.deselect()') # if format["graphs"][i]["name"] == 'X': # self.control_X.scale_A.set(format["graphs"][i]["amp"]) # self.control_X.scale_F.set(format["graphs"][i]["freq"]) # self.control_X.scale_P.set(format["graphs"][i]["phi"]) # if format["graphs"][i]["active"]==1: # self.control_X.draw.select() # else: # self.control_X.draw.deselect() # else: # self.control_Y.scale_A.set(format["graphs"][i]["amp"]) # self.control_Y.scale_F.set(format["graphs"][i]["freq"]) # self.control_Y.scale_P.set(format["graphs"][i]["phi"]) # if format["graphs"][i]["active"]==1: # self.control_Y.draw.select() # else: # self.control_Y.draw.deselect() file.close() def getGraphInfos(self, graph): graphique = {} graphique["name"] = graph.name graphique["active"] = graph.drawVar.get() graphique["amp"] = graph.scale_A.get() graphique["freq"] = graph.scale_F.get() graphique["phi"] = graph.scale_P.get() return graphique def quitter(self): """ Affiche une boite de dialogue pour que l'utilisateur confirme son souhait de quitter """ if tkMessageBox.askyesno('Quitter', 'voulez-vous quitter?'): print "Oscilloscope.quitter()" self.quit()