class Screen(Observer): def __init__(self, parent, bg="white"): self.menu_bar = MenuBar(parent) self.canvas = Canvas(parent, bg=bg, name="screen") self.frameControl = Frame(parent) self.frameLabelSignals = LabelFrame(self.frameControl, text="Signaux", padx=20, pady=20) self.frameLabelMode = LabelFrame(self.frameControl, text="Mode", padx=20, pady=20) self.panelControl = ttk.Notebook(self.frameLabelSignals) self.checkbox_signalX = Checkbutton(self.frameLabelMode, text="Signal X") self.checkbox_signalY = Checkbutton(self.frameLabelMode, text="Signal Y") self.checkbox_XY = Checkbutton(self.frameLabelMode, text="XY") self.panel_control_page = [] # contient les références de mes curseurs for p in parent.get_models(): self.addPage(p.get_name()) def addPage(self, name): page = ttk.Frame(self.panelControl) self.panelControl.add(page, text='signal ' + name) visible_checkbox = Checkbutton(page, text="Afficher") magnitude = Scale(page, length=250, orient="horizontal", label="Amplitude", sliderlength=20, showvalue=0, from_=0, to=5, tickinterval=1, name="magnitudeScale") frequency = Scale(page, length=250, orient="horizontal", label="Frequency", sliderlength=20, showvalue=0, from_=0, to=25, tickinterval=5, name="frequencyScale") phase = Scale(page, length=250, orient="horizontal", label="Phase", sliderlength=20, showvalue=0, from_=0, to=20, tickinterval=5, name="phaseScale") visible_checkbox.pack(fill="x", pady=6) magnitude.pack(expand=1, fill="both", pady=6) frequency.pack(expand=1, fill="both", pady=6) phase.pack(expand=1, fill="both", pady=6) self.panel_control_page.append({ 'visible': visible_checkbox, 'magnitude': magnitude, 'frequency': frequency, 'phase': phase }) def update(self, model): if type(model) == list: for i, m in enumerate(model): signal = m.get_signal() #self.plot_signal(signal, m.get_color()) self.plot_signal(m) else: signal = model.get_signal() self.plot_signal(model) self.grid(6, 8) def get_panel_control_index(self): return self.panelControl.index('current') def get_canvas(self): return self.canvas def get_panel_control_page(self): return self.panel_control_page def get_magnitude(self, index): return self.panel_control_page[index]['magnitude'] def get_frequency(self, index): return self.panel_control_page[index]['frequency'] def get_phase(self, index): return self.panel_control_page[index]['phase'] def get_visible(self, index): return self.panel_control_page[index]['visible'] def get_checkbox_signalX(self): return self.checkbox_signalX def get_checkbox_signalY(self): return self.checkbox_signalY def get_checkbox_XY(self): return self.checkbox_XY def plot_signal(self, model): w, h = self.canvas.winfo_width(), self.canvas.winfo_height() width, height = int(w), int(h) signal = model.get_signal() name = model.get_name() color = model.get_color() if self.canvas.find_withtag("signal" + name): self.canvas.delete("signal" + name) if signal and len(signal) > 1 and model.is_visible(): plot = [(x * width, height / 2.0 * (y + 1)) for (x, y) in signal] self.canvas.create_line(plot, fill=color, smooth=1, width=3, tags="signal" + name) self.canvas.scale("signal" + name, width / 2, height / 2, 1.0, 0.25) def grid(self, row, col): w, h = self.canvas.winfo_width(), self.canvas.winfo_height() width, height = int(w), int(h) if self.canvas.find_withtag("grid"): self.canvas.delete("grid") # dessin des axes X et Y self.canvas.create_line(5, height / 2, width, height / 2, arrow="last", tags=('grid', 'axe-x')) self.canvas.create_line(width / 2, height - 5, width / 2, 5, arrow="last", tags=('grid', 'axe-y')) # dessin des lignes verticales for c in range(1, int(row / 2) + 1): stepW = width / row xd = width / 2 + c * stepW xg = width / 2 - c * stepW #Creation des lignes verticales self.canvas.create_line(xd, height - 5, xd, 5, dash=1, tags=('grid', 'vertical-line'), fill='grey') #cote droit self.canvas.create_line(xg, height - 5, xg, 5, dash=1, tags=('grid', 'vertical-line'), fill='grey') #cote gauche #Creation des tirets sur x self.canvas.create_line(xd, height / 2 - 4, xd, height / 2 + 4, tags=('grid', 'horizontal-line'), fill='grey') self.canvas.create_line(xg, height / 2 - 4, xg, height / 2 + 4, tags=('grid', 'horizontal-line'), fill='grey') # dessin des lignes horizontales for r in range(1, int(col / 2) + 1): stepH = height / col yB = height / 2 + r * stepH yH = height / 2 - r * stepH #Creation des lignes horizontales self.canvas.create_line(5, yB, width, yB, dash=1, tags=('grid', 'horizontal-line'), fill='grey') self.canvas.create_line(5, yH, width, yH, dash=1, tags=('grid', 'horizontal-line'), fill='grey') #Creation des tirets sur y self.canvas.create_line(width / 2 - 4, yB, width / 2 + 4, yB, tags=('grid', 'vertical-line'), fill='grey') self.canvas.create_line(width / 2 - 4, yH, width / 2 + 4, yH, tags=('grid', 'vertical-line'), fill='grey') def packing(self): self.menu_bar.pack(fill='x') self.canvas.pack(side=LEFT, expand=1, fill="both", padx=6, pady=6) self.panelControl.pack(side=RIGHT, expand=1, fill="both", pady=6) self.frameLabelSignals.pack(expand=1, fill="both") self.frameLabelMode.pack(expand=1, fill="both") self.checkbox_signalX.pack(side=LEFT) self.checkbox_signalY.pack(side=LEFT) self.checkbox_XY.pack(side=RIGHT) self.frameControl.pack(side=RIGHT, expand=1, fill="both", pady=6)
class Screen(Observer): def __init__(self, parent, bg="white"): self.canvas = Canvas(parent, bg=bg) self.canvas.bind("<Configure>", self.resize) self.width = int(self.canvas.cget("width")) self.height = int(self.canvas.cget("height")) print("parent", parent.cget("width"), parent.cget("height")) self.magnitude = Scale(parent, length=250, orient="horizontal", label="Magnitude", sliderlength=20, showvalue=0, from_=0, to=10, tickinterval=1, relief="sunken") self.frequency = Scale(parent, length=250, orient="horizontal", label="Frequency", sliderlength=20, showvalue=0, from_=0, to=10, tickinterval=1, relief="sunken") self.phase = Scale(parent, length=250, orient="horizontal", label="Phase", sliderlength=20, showvalue=0, from_=0, to=10, tickinterval=1, relief="sunken") def update(self, model): print("View update") signal = model.get_signal() self.plot_signal(signal) def get_magnitude(self): return self.magnitude def get_frequency(self): return self.frequency def get_phase(self): return self.phase def plot_signal(self, signal, color="red"): w, h = self.canvas.winfo_width(), self.canvas.winfo_height() width, height = int(w), int(h) print(self.canvas.find_withtag("signal")) if self.canvas.find_withtag("signal"): self.canvas.delete("signal") if signal and len(signal) > 1: plot = [(x * width, height / 2.0 * (y + 1)) for (x, y) in signal] signal_id = self.canvas.create_line(plot, fill=color, smooth=1, width=3, tags="signal") return def grid(self, steps): w, h = self.canvas.cget("width"), self.canvas.cget("height") width, height = int(w), int(h) # self.canvas.create_line(10,height/2,width,height/2,arrow="last") # self.canvas.create_line(10,height-5,10,5,arrow="last") step = (width - 10) / steps * 1. for t in range(1, steps + 2): x = t * step self.canvas.create_line(x, 0, x, height) self.canvas.create_line(0, x, width, x) def packing(self): self.canvas.pack() self.magnitude.pack() self.frequency.pack() self.phase.pack() self.canvas.pack(expand=1, fill="both", padx=6) self.magnitude.pack(expand=1, fill="x", padx=2) self.frequency.pack(expand=1, fill="x", padx=2) self.phase.pack(expand=1, fill="x", padx=2) def resize(self, event): wscale = float(event.width) / self.width hscale = float(event.height) / self.height self.width = event.width self.height = event.height print("resize", wscale, hscale) # resize the canvas #self.config(width=self.width, height=self.height) scale_xy = self.width * 1.0 / self.height # rescale all the objects tagged with the "all" tag self.canvas.scale("all", 0, 0, wscale, hscale)
class Viewer(Frame): def __init__(self, master,x=600,y=200, onLeft=None, onRight=None, **kwargs): self.root=master self.xsize=x self.ysize=y self.onLeft=onLeft self.onRight=onRight self.ratio=100. Frame.__init__(self, master,width=x,height=y, **kwargs) self.canvas = Canvas(self, width=x, height=y, background="white") self.xsb = Scrollbar(self, orient="horizontal", command=self.canvas.xview) self.ysb = Scrollbar(self, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.ysb.set, xscrollcommand=self.xsb.set) self.canvas.configure(scrollregion=(0,0,x,y)) self.xsb.grid(row=1, column=0, sticky="ew") self.ysb.grid(row=0, column=1, sticky="ns") self.canvas.grid(row=0, column=0, sticky="nsew") self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.canvas.bind("<Button-1>", self.clickL) self.canvas.bind("<Button-3>", self.clickR) # This is what enables using the mouse: self.canvas.bind("<ButtonPress-1>", self.move_start) self.canvas.bind("<B1-Motion>", self.move_move) #linux scroll self.canvas.bind("<Button-4>", self.zoomerP) self.canvas.bind("<Button-5>", self.zoomerM) self.canvas.bind_all("<Prior>", self.zoomerP) self.canvas.bind_all("<Next>", self.zoomerM) self.canvas.bind_all("E", self.zoomExtens) #windows scroll self.canvas.bind_all("<MouseWheel>",self.zoomer) def reset(self): pass def set_title(self, title): self.root.title( title) #move def move_start(self, event): self.canvas.scan_mark(event.x, event.y) return True def move_move(self, event): self.canvas.scan_dragto(event.x, event.y, gain=1) return True #windows zoom def zoomer(self,event): if (event.delta > 0): self.ratio *= 1.1 elif (event.delta < 0): self.ratio *= 0.9 self.redraw() def redraw(self): self.canvas.delete("all") self.canvas.configure(scrollregion = self.canvas.bbox("all")) def zoomExtens(self, *args): x0,y0,x1,y1 = self.canvas.bbox("all") xlen=x1-x0 ylen=y1-y0 height=self.canvas.winfo_height() width=self.canvas.winfo_width() unfit=min(width/float(xlen), height/float(ylen)) self.ratio*=unfit self.redraw() # """" if xlen and ylen: self ratio*= self.canvas.scale("all", xlen/2., ylen/2., float(self.xsize)/xlen, float(self.ysize)/ylen) self.canvas.configure(scrollregion = self.canvas.bbox("all")) """ #linux zoom def zoomerP(self,event): self.canvas.scale("all", event.x, event.y, 1.1, 1.1) self.canvas.configure(scrollregion = self.canvas.bbox("all")) def zoomerM(self,event): self.canvas.scale("all", event.x, event.y, 0.9, 0.9) self.canvas.configure(scrollregion = self.canvas.bbox("all")) def pose2p(self, pose): x,y=pose[:2] return int(x*self.ratio), -int(y*self.ratio) def line2p(self, line): if type(line[0]) in (float, int): line=zip(line[::2],line[1::2]) return map(self.pose2p, line) def p2m(self, x, y): return x/self.ratio, -y/self.ratio def create_line(self, coords, **kwargs): return self.canvas.create_line(self.line2p(coords), **kwargs) def create_polygon(self, coords, **kwargs): return self.canvas.create_polygon(self.line2p(coords), **kwargs) def delete(self, object): self.canvas.delete(object) def clickL(self, event): if self.onLeft: x,y=self.p2m(int(self.canvas.canvasx(event.x)), int(self.canvas.canvasy(event.y))) self.onLeft(x,y) return True def clickR(self, event): if self.onRight: x,y=self.p2m(int(self.canvas.canvasx(event.x)), int(self.canvas.canvasy(event.y))) self.onRight(x,y) return True