class filterswindow: ''' Interface graphique recapitulant les caracteristique du sismogramme presentant les options de filtrage et de calculs du noyau de sensibilite ''' def __init__(self,racine): self.canvas = Canvas(racine, borderwidth=1, background="#ffffff") self.frame = Frame(self.canvas, background="#ffffff") self.vsb = Scrollbar(racine, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.vsb.set) self.vsb.pack(side="right", fill="y") self.canvas.pack(side="left", fill="both", expand=True) self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame") self.frame.bind("<Configure>", self.OnFrameConfigure) self.data() def data(self): global filterVar filterVar = 1 global text6a text6a = "1" global text6c1 text6c1 = StringVar() global text6c2 text6c2 = StringVar() global text6c3 text6c3 = StringVar() Label(self.frame, text="Option Filter").grid(row=0) Label(self.frame, text="\n").grid(row=1) Label(self.frame, text="lowest frequency ?").grid(row=4) e1 = Entry(self.frame, textvariable=text6c1) e1.grid(row=5) Label(self.frame, text="highest frequency ?").grid(row=20) e2 = Entry(self.frame, textvariable=text6c2) e2.grid(row=21) Label(self.frame, text="number of poles ?").grid(row=22) e3 = Entry(self.frame, textvariable=text6c3) e3.grid(row=23) Button(self.frame, text="continue", command=self.quitter).grid(row=24) def quitter(self): global racine racine.destroy() afficheSismoFiltre(textPath.get(), float(text6c1.get()), float(text6c2.get()), float(text6c3.get())) def OnFrameConfigure(self, event): '''Reset the scroll region to encompass the inner frame''' self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def xGC_skew(seq, window=1000, zoom=100, r=300, px=100, py=100): """Calculates and plots normal and accumulated GC skew (GRAPHICS !!!).""" from Tkinter import Scrollbar, Canvas, BOTTOM, BOTH, ALL, \ VERTICAL, HORIZONTAL, RIGHT, LEFT, X, Y yscroll = Scrollbar(orient=VERTICAL) xscroll = Scrollbar(orient=HORIZONTAL) canvas = Canvas(yscrollcommand=yscroll.set, xscrollcommand=xscroll.set, background='white') win = canvas.winfo_toplevel() win.geometry('700x700') yscroll.config(command=canvas.yview) xscroll.config(command=canvas.xview) yscroll.pack(side=RIGHT, fill=Y) xscroll.pack(side=BOTTOM, fill=X) canvas.pack(fill=BOTH, side=LEFT, expand=1) canvas.update() X0, Y0 = r + px, r + py x1, x2, y1, y2 = X0 - r, X0 + r, Y0 - r, Y0 + r ty = Y0 canvas.create_text(X0, ty, text='%s...%s (%d nt)' % (seq[:7], seq[-7:], len(seq))) ty += 20 canvas.create_text(X0, ty, text='GC %3.2f%%' % (GC(seq))) ty += 20 canvas.create_text(X0, ty, text='GC Skew', fill='blue') ty += 20 canvas.create_text(X0, ty, text='Accumulated GC Skew', fill='magenta') ty += 20 canvas.create_oval(x1, y1, x2, y2) acc = 0 start = 0 for gc in GC_skew(seq, window): r1 = r acc += gc # GC skew alpha = pi - (2*pi*start)/len(seq) r2 = r1 - gc*zoom x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1, y1, x2, y2, fill='blue') # accumulated GC skew r1 = r - 50 r2 = r1 - acc x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1, y1, x2, y2, fill='magenta') canvas.update() start += window canvas.configure(scrollregion=canvas.bbox(ALL))
def xGC_skew(seq, window = 1000, zoom = 100, r = 300, px = 100, py = 100): """Calculates and plots normal and accumulated GC skew (GRAPHICS !!!).""" from Tkinter import Scrollbar, Canvas, BOTTOM, BOTH, ALL, \ VERTICAL, HORIZONTAL, RIGHT, LEFT, X, Y yscroll = Scrollbar(orient = VERTICAL) xscroll = Scrollbar(orient = HORIZONTAL) canvas = Canvas(yscrollcommand = yscroll.set, xscrollcommand = xscroll.set, background = 'white') win = canvas.winfo_toplevel() win.geometry('700x700') yscroll.config(command = canvas.yview) xscroll.config(command = canvas.xview) yscroll.pack(side = RIGHT, fill = Y) xscroll.pack(side = BOTTOM, fill = X) canvas.pack(fill=BOTH, side = LEFT, expand = 1) canvas.update() X0, Y0 = r + px, r + py x1, x2, y1, y2 = X0 - r, X0 + r, Y0 -r, Y0 + r ty = Y0 canvas.create_text(X0, ty, text = '%s...%s (%d nt)' % (seq[:7], seq[-7:], len(seq))) ty +=20 canvas.create_text(X0, ty, text = 'GC %3.2f%%' % (GC(seq))) ty +=20 canvas.create_text(X0, ty, text = 'GC Skew', fill = 'blue') ty +=20 canvas.create_text(X0, ty, text = 'Accumulated GC Skew', fill = 'magenta') ty +=20 canvas.create_oval(x1,y1, x2, y2) acc = 0 start = 0 for gc in GC_skew(seq, window): r1 = r acc+=gc # GC skew alpha = pi - (2*pi*start)/len(seq) r2 = r1 - gc*zoom x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1,y1,x2,y2, fill = 'blue') # accumulated GC skew r1 = r - 50 r2 = r1 - acc x1 = X0 + r1 * sin(alpha) y1 = Y0 + r1 * cos(alpha) x2 = X0 + r2 * sin(alpha) y2 = Y0 + r2 * cos(alpha) canvas.create_line(x1,y1,x2,y2, fill = 'magenta') canvas.update() start += window canvas.configure(scrollregion = canvas.bbox(ALL))
class RecapCalculs: ''' Interface graphique recapitulant les caracteristique du sismogramme presentant les options de filtrage et de calculs du noyau de sensibilite ''' def __init__(self,root): self.canvas = Canvas(root, borderwidth=1, background="#ffffff") self.frame = Frame(self.canvas, background="#ffffff") self.vsb = Scrollbar(root, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.vsb.set) self.vsb.pack(side="right", fill="y") self.canvas.pack(side="left", fill="both", expand=True) self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame") self.frame.bind("<Configure>", self.OnFrameConfigure) self.data() def data(self): self.message = Label(self.frame, text="Recapitulatif du sismogramme").grid(row=0) global X X=read(textPath.get()) self.recap = Listbox(self.frame, height = 15, width = 50) self.recap.insert(1, "network: {}\n".format(X[0].stats.network)) self.recap.insert(2, "station: {}\n".format(X[0].stats.station)) self.recap.insert(3, "location: {}\n".format(X[0].stats.location)) self.recap.insert(4, "channel: {}\n".format(X[0].stats.channel)) self.recap.insert(5, "start time: {}\n".format(X[0].stats.starttime)) self.recap.insert(6, "end time: {}\n".format(X[0].stats.endtime)) self.recap.insert(7, "sampling rate: {}\n".format(X[0].stats.sampling_rate)) self.recap.insert(8, "delta: {}\n".format(X[0].stats.delta)) self.recap.insert(9, "number points: {}\n".format(X[0].stats.npts)) self.recap.insert(10, "calibration: {}\n".format(X[0].stats.calib)) self.recap.insert(11, "event latitude: {}\n".format(X[0].stats.sac.evla)) self.recap.insert(12, "event longitude: {}\n".format(X[0].stats.sac.evlo)) self.recap.insert(13, "event depth: {}\n".format(X[0].stats.sac.evdp)) self.recap.insert(14, "station latitude: {}\n".format(X[0].stats.sac.stla)) self.recap.insert(15, "station longitude: {}\n".format(X[0].stats.sac.stlo)) self.recap.grid(row=0) #afficheGraphique() def OnFrameConfigure(self, event): '''Reset the scroll region to encompass the inner frame''' self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def run(): """ Esegue l'emulatore del pdp8 """ CD = pdp8() principale = Tk() principale.title("Pdp8 Emulator : Assembly Editor") emulatore = Toplevel() emulatore.title("Pdp8 Emulator") emulatore.geometry("1015x589") edit = Editor(principale, CD) scrollbar1 = AutoScrollbar(emulatore) scrollbar1.grid(row=0, column=1, sticky=N + S) scrollbar2 = AutoScrollbar(emulatore, orient=HORIZONTAL) scrollbar2.grid(row=1, column=0, sticky=E + W) finestra = Canvas(emulatore, yscrollcommand=scrollbar1.set, xscrollcommand=scrollbar2.set) finestra.grid(row=0, column=0, sticky=N + S + E + W) scrollbar1.config(command=finestra.yview) scrollbar2.config(command=finestra.xview) emulatore.grid_rowconfigure(0, weight=1) emulatore.grid_columnconfigure(0, weight=1) emul = Emulatore(finestra, edit, CD, emulatore) finestra.create_window(0, 0, anchor=NW, window=emul.master) emul.master.update_idletasks() finestra.config(scrollregion=finestra.bbox("all")) principale.protocol("WM_DELETE_WINDOW", edit.exit) emulatore.protocol("WM_DELETE_WINDOW", emul.exit) principale.mainloop() emulatore.mainloop()
def run(): """ Esegue l'emulatore del pdp8 """ CD = pdp8() principale = Tk() principale.title("Pdp8 Emulator : Assembly Editor") emulatore = Toplevel() emulatore.title("Pdp8 Emulator") emulatore.geometry("1015x589") edit = Editor(principale, CD) scrollbar1 = AutoScrollbar(emulatore) scrollbar1.grid(row=0, column=1, sticky=N + S) scrollbar2 = AutoScrollbar(emulatore, orient=HORIZONTAL) scrollbar2.grid(row=1, column=0, sticky=E + W) finestra = Canvas(emulatore, yscrollcommand=scrollbar1.set, xscrollcommand=scrollbar2.set) finestra.grid(row=0, column=0, sticky=N + S + E + W) scrollbar1.config(command=finestra.yview) scrollbar2.config(command=finestra.xview) emulatore.grid_rowconfigure(0, weight=1) emulatore.grid_columnconfigure(0, weight=1) emul = Emulatore(finestra, edit, CD, emulatore) finestra.create_window(0, 0, anchor=NW, window=emul.master) emul.master.update_idletasks() finestra.config(scrollregion=finestra.bbox("all")) principale.protocol("WM_DELETE_WINDOW", edit.exit) emulatore.protocol("WM_DELETE_WINDOW", emul.exit) principale.mainloop() emulatore.mainloop()
def on_show_frame(self): self.canvas_wrappers = [] self.canvases = [] self.page_num = 0 if len(self.controller.sr_results) == 0: self.controller.show_frame(SrNoFramesFoundScreen) else: pages = int(ceil(len(self.controller.sr_results) / 10.0)) for page in range(0, pages): canvas_wrapper = Frame(self.content_wrapper, borderwidth="1", relief="solid") canvas = Canvas(canvas_wrapper, width=int(WINDOW_WIDTH * 7 / 8), height=(WINDOW_HEIGHT * 2 / 3)) scroll_bar = Scrollbar(canvas_wrapper, orient=VERTICAL, command=canvas.yview) results_list_frame = Frame(canvas) canvas.configure(yscrollcommand=scroll_bar.set) canvas.create_window(0, 0, window=results_list_frame) canvas.bind_all("<Up>", self.on_up_key) canvas.bind_all("<Down>", self.on_down_key) canvas.bind_all("<Left>", self.on_left_key) canvas.bind_all("<Right>", self.on_right_key) canvas.grid(row=0, column=0, sticky="nsew") scroll_bar.grid(row=0, column=1, sticky="ns") canvas_wrapper.grid(row=2, column=0, columnspan=3, sticky="nsew") select_buttons_on_page = [] for row in range(0, RESULTS_PER_PAGE): result_num = page * RESULTS_PER_PAGE + row if result_num < len(self.controller.sr_results): frame_num = self.controller.sr_results[result_num][ FRAME_NUM_LABEL] result_entry = Frame(results_list_frame, borderwidth="1", relief="solid") description = PLabel( result_entry, text="Frame #" + str(int(frame_num)) + ", Time: " + str(datetime.timedelta(seconds=frame_num / 30))) preview_wrapper = Frame(result_entry) left_video_preview = Label( preview_wrapper, image=self.controller.sr_results[result_num][LEFT]) right_video_preview = Label( preview_wrapper, image=self.controller.sr_results[result_num] [RIGHT]) select_button = SrSelectButton( preview_wrapper, self.controller, self.controller.sr_results[result_num] [SR_MAP_LABEL], text="Select") select_buttons_on_page.append(select_button) description.pack() left_video_preview.grid(row=row, column=0) right_video_preview.grid(row=row, column=1) select_button.grid(row=row, column=2) preview_wrapper.pack() result_entry.pack() for i in range(0, len(select_buttons_on_page)): select_buttons_on_page[i].configure( command=select_buttons_on_page[i].use_sr_map) self.master.update_idletasks() canvas.config(scrollregion=canvas.bbox("all")) canvas.yview_moveto(0) self.canvas_wrappers.append(canvas_wrapper) self.canvases.append(canvas) self.prev_result_page = Button( self.content_wrapper, text="<", command=lambda: self.prev_page_command()) self.page_info_label = PLabel( self.content_wrapper, text=get_page_info_label_message(self.page_num, len(self.canvases), RESULTS_PER_PAGE)) self.next_result_page = Button( self.content_wrapper, text=">", command=lambda: self.next_page_command()) self.prev_result_page.grid(row=3, column=0) self.page_info_label.grid(row=3, column=1) self.next_result_page.grid(row=3, column=2) self.canvas_wrappers[self.page_num].tkraise()
class Breakout(Tk): def __init__(self): Tk.__init__(self) self.geometry('400x400') self.resizable(0,0) # game screen self.canvas = Canvas(self, bg='black', width=400, height=400) self.canvas.pack(expand=1, fill=BOTH) # ball self._initiate_new_ball() # paddle self.canvas.create_rectangle(175,375,225,385, fill='black', outline='white', tags='paddle') self.bind('<Key>', self._move_paddle) # bricks self.bricks = {} brick_coords = [5,5,35,15] for i in range(39): self.canvas.create_rectangle(*brick_coords, outline='white', fill=('#{}'.format(randint(100000,999999))), tags='brick' + str(i)) self.bricks['brick' + str(i)] = None brick_coords[0] += 30; brick_coords[2] += 30 if brick_coords[2] > 395: brick_coords[0] = 5; brick_coords[2] = 35 brick_coords[1] += 10; brick_coords[3] += 10 def _initiate_new_ball(self): if self.canvas.find_withtag('ball'): self.canvas.delete('ball') self.x = 60; self.y = 100 self.angle = 140; self.speed = 5 self.canvas.create_oval(self.x,self.y,self.x+10,self.y+10, fill='lawn green', outline='white', tags='ball') self.after(1000, self._move_ball) def _move_paddle(self, event): if event.keysym == 'Left': if self.canvas.coords('paddle')[0] > 0: self.canvas.move('paddle', -10, 0) elif event.keysym == 'Right': if self.canvas.coords('paddle')[2] < 400: self.canvas.move('paddle', +10, 0) def _move_ball(self): # variables to determine where ball is in relation to other objects ball = self.canvas.find_withtag('ball')[0] bounds = self.canvas.find_overlapping(0,0,400,400) paddle = self.canvas.find_overlapping(*self.canvas.coords('paddle')) for brick in self.bricks.iterkeys(): self.bricks[brick] = self.canvas.find_overlapping(*self.canvas.bbox(brick)) # calculate change in x,y values of ball angle = self.angle - 90 # correct for quadrant IV increment_x = cos(radians(angle)) * self.speed increment_y = sin(radians(angle)) * self.speed # finite state machine to set ball state if ball in bounds: self.ball_state = 'moving' for brick, hit in self.bricks.iteritems(): if ball in hit: self.ball_state = 'hit_brick' delete_brick = brick elif ball in paddle: self.ball_state = 'hit_wall' elif ball not in bounds: if self.canvas.coords('ball')[1] < 400: self.ball_state = 'hit_wall' else: self.ball_state = 'out_of_bounds' self._initiate_new_ball() # handler for ball state if self.ball_state is 'moving': self.canvas.move('ball', increment_x, increment_y) self.after(15, self._move_ball) elif self.ball_state is 'hit_brick' or self.ball_state is 'hit_wall': if self.ball_state == 'hit_brick': self.canvas.delete(delete_brick) del self.bricks[delete_brick] self.canvas.move('ball', -increment_x, -increment_y) self.angle += choice([119, 120, 121]) self._move_ball()
class Path: def __init__(self, root): self.canvas = Canvas(root, borderwidth=1, background="#ffffff") self.frame = Frame(self.canvas, background="#ffffff") self.vsb = Scrollbar(root, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.vsb.set) self.vsb.pack(side="right", fill="y") self.canvas.pack(side="left", fill="both", expand=True) self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame") self.frame.bind("<Configure>", self.OnFrameConfigure) self.data() def data(self): global textPath textPath = StringVar() global text0a text0a = StringVar() global text0b text0b = StringVar() global text2a text2a = StringVar() global text3 text3 = StringVar() global alphaVar alphaVar = IntVar() global betaVar betaVar = IntVar() global allVar allVar = IntVar() global text6a text6a = "0" global filterVar filterVar = IntVar() global text6b text6b = StringVar() global t1x t1x = "" global t2x t2x = "" global t3x t3x = "" global t4x t4x = "" global text8_0 text8_0 = StringVar() global text8_1 text8_1 = StringVar() Label(self.frame,text="Path ? ").grid(row=0, column=0) Entry(self.frame,textvariable=textPath).grid(row=1, column=0) Button(self.frame, text="Valider et afficher", command = affiche_recap).grid(row=1, column=1) Label(self.frame, text="Green function database information file\n (for a certain depth only for the instance) ?").grid(row=3) Entry(self.frame, textvariable=text0a).grid(row=4) Label(self.frame, text="Output directory (parentdir) ?").grid(row=5) Entry(self.frame, textvariable=text0b).grid(row=6) Label(self.frame, text="Phase name ?").grid(row=9) Entry(self.frame, textvariable=text3).grid(row=10) def afficheAlpha(): seismicPara["text"]="alpha" betaVar.set(0) allVar.set(0) def afficheBeta(): seismicPara["text"]="beta" alphaVar.set(0) allVar.set(0) def afficheAll(): seismicPara["text"]="all" alphaVar.set(0) betaVar.set(0) seismicPara = Menubutton(self.frame, text="Seismic Parameter", relief=RAISED) seismicPara.grid(row=0) seismicPara.menu = Menu(seismicPara, tearoff = 0) seismicPara["menu"] = seismicPara.menu seismicPara.menu.add_checkbutton(label="alpha", variable = alphaVar, command = afficheAlpha) seismicPara.menu.add_checkbutton(label="beta", variable = betaVar, command = afficheBeta) seismicPara.menu.add_checkbutton(label="all", variable = allVar, command = afficheAll) seismicPara.grid(row=11) Label(self.frame, text="Filter name ?").grid(row=12) Entry(self.frame, textvariable=text6b).grid(row=13) Label(self.frame, text="time window t1 ?").grid(row=14) Labelt1 = Label(self.frame, text="-->").grid(row=15) Button(self.frame, text="time 1", command=self.time1).grid(row=15, column=1) Label(self.frame, text="time window t2 ?").grid(row=16) Labelt1 = Label(self.frame, text="-->").grid(row=17) Button(self.frame, text="time 2", command=self.time2).grid(row=17, column=1) ''' Label(self.frame, text="time window t3 ?").grid(row=18) Labelt1 = Label(self.frame, text="-->").grid(row=19) Button(self.frame, text="time 3", command=self.time3).grid(row=19, column=1) Label(self.frame, text="time window t4 ?").grid(row=20) Labelt1 = Label(self.frame, text="-->").grid(row=21) Button(self.frame, text="time 4", command=self.time4).grid(row=21, column=1) ''' def affiche0(): convertPara["text"]="No conversion" text8_1.set(0) def affiche1(): convertPara["text"]="Conversion" text8_0.set(0) convertPara = Menubutton(self.frame, text="Geodetic latitude to geocentric latitude conversion", relief=RAISED) convertPara.grid(row=0) convertPara.menu = Menu(convertPara, tearoff = 0) convertPara["menu"] = convertPara.menu convertPara.menu.add_checkbutton(label="No conversion", variable = text8_0, command = affiche0) convertPara.menu.add_checkbutton(label="Conversion", variable = text8_1, command = affiche1) convertPara.grid(row=22) b = Checkbutton(self.frame, text = "apply filter", variable = filterVar) b.grid(row=23, column = 0) Button(self.frame, text="continue", command=self.quitter).grid(row=23, column=1) def time1(self): global t1x global t1y t1x, t1y = Pointage() print type(t1x) print t1y def time2(self): global t2x global t2y t2x, t2y = Pointage() print t2x print t2y def time3(self): t3x, t3y = Pointage() print t3x print t3y def time4(self): t4x, t4y = Pointage() print t4x print t4y def quitter(self): root.destroy() def OnFrameConfigure(self, event): '''Reset the scroll region to encompass the inner frame''' self.canvas.configure(scrollregion=self.canvas.bbox("all"))
class Breakout(Tk): def __init__(self): Tk.__init__(self) self.geometry('400x400') self.resizable(0, 0) # game screen self.canvas = Canvas(self, bg='black', width=400, height=400) self.canvas.pack(expand=1, fill=BOTH) # ball self._initiate_new_ball() # paddle self.canvas.create_rectangle(175, 375, 225, 385, fill='black', outline='white', tags='paddle') self.bind('<Key>', self._move_paddle) # bricks self.bricks = {} brick_coords = [5, 5, 35, 15] for i in range(39): self.canvas.create_rectangle(*brick_coords, outline='white', fill=('#{}'.format( randint(100000, 999999))), tags='brick' + str(i)) self.bricks['brick' + str(i)] = None brick_coords[0] += 30 brick_coords[2] += 30 if brick_coords[2] > 395: brick_coords[0] = 5 brick_coords[2] = 35 brick_coords[1] += 10 brick_coords[3] += 10 def _initiate_new_ball(self): if self.canvas.find_withtag('ball'): self.canvas.delete('ball') self.x = 60 self.y = 100 self.angle = 140 self.speed = 5 self.canvas.create_oval(self.x, self.y, self.x + 10, self.y + 10, fill='lawn green', outline='white', tags='ball') self.after(1000, self._move_ball) def _move_paddle(self, event): if event.keysym == 'Left': if self.canvas.coords('paddle')[0] > 0: self.canvas.move('paddle', -10, 0) elif event.keysym == 'Right': if self.canvas.coords('paddle')[2] < 400: self.canvas.move('paddle', +10, 0) def _move_ball(self): # variables to determine where ball is in relation to other objects ball = self.canvas.find_withtag('ball')[0] bounds = self.canvas.find_overlapping(0, 0, 400, 400) paddle = self.canvas.find_overlapping(*self.canvas.coords('paddle')) for brick in self.bricks.iterkeys(): self.bricks[brick] = self.canvas.find_overlapping( *self.canvas.bbox(brick)) # calculate change in x,y values of ball angle = self.angle - 90 # correct for quadrant IV increment_x = cos(radians(angle)) * self.speed increment_y = sin(radians(angle)) * self.speed # finite state machine to set ball state if ball in bounds: self.ball_state = 'moving' for brick, hit in self.bricks.iteritems(): if ball in hit: self.ball_state = 'hit_brick' delete_brick = brick elif ball in paddle: self.ball_state = 'hit_wall' elif ball not in bounds: if self.canvas.coords('ball')[1] < 400: self.ball_state = 'hit_wall' else: self.ball_state = 'out_of_bounds' self._initiate_new_ball() # handler for ball state if self.ball_state is 'moving': self.canvas.move('ball', increment_x, increment_y) self.after(15, self._move_ball) elif self.ball_state is 'hit_brick' or self.ball_state is 'hit_wall': if self.ball_state == 'hit_brick': self.canvas.delete(delete_brick) del self.bricks[delete_brick] self.canvas.move('ball', -increment_x, -increment_y) self.angle += choice([119, 120, 121]) self._move_ball()
class Path: def __init__(self, root): self.canvas = Canvas(root, borderwidth=1, background="#ffffff") self.frame = Frame(self.canvas, background="#ffffff") self.vsb = Scrollbar(root, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.vsb.set) self.vsb.pack(side="right", fill="y") self.canvas.pack(side="left", fill="both", expand=True) self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame") self.frame.bind("<Configure>", self.OnFrameConfigure) self.data() def data(self): global textPath textPath = StringVar() global text0a text0a = StringVar() global text0b text0b = StringVar() global text2a text2a = StringVar() global text3 text3 = StringVar() global alphaVar alphaVar = IntVar() global betaVar betaVar = IntVar() global allVar allVar = IntVar() global text6a0 text6a0 = IntVar() global text6a1 text6a1 = IntVar() global text6b text6b = StringVar() global text6c1 text6c1 = StringVar() global text6c2 text6c2 = StringVar() global text6c3 text6c3 = StringVar() global text7_1 text7_1 = StringVar() global text7_2 text7_2 = StringVar() global text7_3 text7_3 = StringVar() global text7_4 text7_4 = StringVar() global text8 text8 = StringVar() Label(self.frame,text="Path ? ").grid(row=0, column=0) Entry(self.frame,textvariable=textPath).grid(row=1, column=0) Button(self.frame, text="Valider et afficher", command = affiche_recap).grid(row=1, column=1) Label(self.frame, text="Green function database information file\n (for a certain depth only for the instance) ?").grid(row=3) Entry(self.frame, textvariable=text0a).grid(row=4) Label(self.frame, text="Output directory (parentdir) ?").grid(row=5) Entry(self.frame, textvariable=text0b).grid(row=6) Label(self.frame, text="Phase name ?").grid(row=9) Entry(self.frame, textvariable=text3).grid(row=10) def afficheAlpha(): seismicPara["text"]="alpha" betaVar.set(0) allVar.set(0) def afficheBeta(): seismicPara["text"]="beta" alphaVar.set(0) allVar.set(0) def afficheAll(): seismicPara["text"]="all" alphaVar.set(0) betaVar.set(0) seismicPara = Menubutton(self.frame, text="Seismic Parameter", relief=RAISED) seismicPara.grid(row=0) seismicPara.menu = Menu(seismicPara, tearoff = 0) seismicPara["menu"] = seismicPara.menu seismicPara.menu.add_checkbutton(label="alpha", variable = alphaVar, command = afficheAlpha) seismicPara.menu.add_checkbutton(label="beta", variable = betaVar, command = afficheBeta) seismicPara.menu.add_checkbutton(label="all", variable = allVar, command = afficheAll) seismicPara.grid(row=11) def affiche0(): filterPara["text"]="Filter Off" text6a1.set(0) def affiche1(): filterPara["text"]="Filter On" text6a0.set(0) filterPara = Menubutton(self.frame, text="Butterworth filter ", relief=RAISED) filterPara.grid(row=0) filterPara.menu = Menu(filterPara, tearoff = 0) filterPara["menu"] = filterPara.menu filterPara.menu.add_checkbutton(label="Filter Off", variable = text6a0, command = affiche0) filterPara.menu.add_checkbutton(label="Filter On", variable = text6a1, command = affiche1) filterPara.grid(row=12) Label(self.frame, text="Filter name ?").grid(row=15) Entry(self.frame, textvariable=text6b).grid(row=16) Label(self.frame, text="\nIf butterworth = 0; \n just comment out those 3 parameters").grid(row=17) Label(self.frame, text="lowest frequency ?").grid(row=18,column=1) Entry(self.frame, textvariable=text6c1).grid(row=19, column=1) Label(self.frame, text="highest frequency ?").grid(row=20, column=1) Entry(self.frame, textvariable=text6c2).grid(row=21, column=1) Label(self.frame, text="number of poles ?").grid(row=22, column=1) Entry(self.frame, textvariable=text6c3).grid(row=23, column =1) Label(self.frame, text="time window t1 ?").grid(row=24) Entry(self.frame, textvariable=text7_1).grid(row=25) Label(self.frame, text="time window t2 ?").grid(row=26) Entry(self.frame, textvariable=text7_2).grid(row=27) Label(self.frame, text="time window t3 ?").grid(row=28) Entry(self.frame, textvariable=text7_3).grid(row=29) Label(self.frame, text="time window t4 ?").grid(row=30) Entry(self.frame, textvariable=text7_4).grid(row=31) Label(self.frame, text="itranslat (1 if you convert geodetic latitude to geocentric latitude) ?").grid(row=32) Entry(self.frame, textvariable=text8).grid(row=33) Button(self.frame, text="continue", command=writingFile).grid(row=34) def OnFrameConfigure(self, event): '''Reset the scroll region to encompass the inner frame''' self.canvas.configure(scrollregion=self.canvas.bbox("all"))
class ImageViewer(Frame, object): class _Panner(object): def __init__(self): self.viewers = [] self._factor = 1 self._drags = [] self._cdrag = None def add(self, val): self.viewers.append(val) for mark, end in self._drags: val.canvas.scan_mark(*mark) val.canvas.scan_dragto(*end, gain=1) if self._cdrag: val.canvas.scan_mark(*self._cdrag[0]) val.canvas.scan_dragto(*self._cdrag[1], gain=1) def move_mark(self, x, y): if self._cdrag: self._drags.append(self._cdrag) self._cdrag = [(x, y), (x, y)] for viewer in self.viewers: viewer.canvas.scan_mark(x, y) def move_actual(self, x, y): self._cdrag[1] = (x, y) for viewer in self.viewers: viewer.canvas.scan_dragto(x, y, gain=1) def update(self): for viewer in self.viewers: viewer._update() def __init__(self, master, panner=None): super(ImageViewer, self).__init__(master) self._image = None self._view = None self._view_id = None self.canvas = Canvas(self, background="#000") self.canvas.pack(fill='both', expand=1) self.canvas.bind("<MouseWheel>", self.zoom) self.canvas.bind("<ButtonPress-1>", self.scroll_start) self.canvas.bind("<B1-Motion>", self.scroll_move) # self.canvas.bind("<Enter>", self.focus_widget) # self.canvas.bind("<Leave>", self.unfocus_widget) self.popup_menu = PopupMenu(self.canvas) for val in (10, 25, 50, 75, 100, 150, 200, 250, 300, 500): self.popup_menu.add_command( label="%d%%" % val, command=(lambda v: (lambda: self.set_factor(v / 100.)))(val)) self.popup_menu.attach() self._panner = panner if panner is None: self._panner = ImageViewer._Panner() self._panner.add(self) self._focus_prev = None def destroy(self): self._panner.viewers.remove(self) super(ImageViewer, self).destroy() @property def image(self): return self._image @image.setter def image(self, value): self._image = value self.after(1, self.show) @property def factor(self): return self._panner._factor @factor.setter def factor(self, value): self._panner._factor = value self.after(1, self.show) def set_factor(self, value): self.factor = value def zoom(self, event): if event.delta < 0: if self.factor == .1: return self.factor -= .1 elif event.delta > 0: if self.factor == 5: return self.factor += .1 self.show() def scroll_start(self, event): self._panner.move_mark(event.x, event.y) def scroll_move(self, event): self._panner.move_actual(event.x, event.y) def focus_widget(self, event): self._focus_prev = self.canvas.focus_get() self.focus_set() def unfocus_widget(self, event): self._focus_prev.focus_set() def show(self): self._panner.update() def _update(self): if self._image is None: return if self._view_id is not None: self.canvas.delete(self._view_id) x, y = self.image.size x, y = int(round(x * self.factor)), int(round(y * self.factor)) self._view = ImageTk.PhotoImage(self.image.resize((x, y))) self._view_id = self.canvas.create_image(0, 0, image=self._view, anchor="nw") self.canvas.configure(scrollregsion=self.canvas.bbox("ALL"))
def displayFrame(self, data): root = Tk() root.title('Book Bank') root.geometry("380x620") yscrollbar = Scrollbar(root) canvas = Canvas(root, background="cadetblue4", yscrollcommand=yscrollbar.set) # BG="#D2D2D2" yscrollbar.config(command=canvas.yview) yscrollbar.pack(side=RIGHT, fill=Y) # Create the frame which will hold the widgets canvas.pack(fill="both", expand=1) # im = PhotoImage(file='/Users/RaMD/PycharmProjects/Exchange_Borrowing_Books/wall2.gif') lf = LabelFrame( canvas, text=unicode("قائمة الكتب", "utf-8"), bg='cadetblue4', fg='gray99' ).grid(row=1, column=1, padx=80, pady=50) # pack(expand=1, padx=20, pady=30, ipadx=20, ipady=18) frame = Frame(lf) im = Image.open('wall3.jpg') img = ImageTk.PhotoImage(image=im) # canvas.create_image(0, 0, anchor=NE, image=img) Label(canvas, image=img).grid(row=0, column=0) Label(root, text=unicode("الكتب المتوفرة", "utf-8"), bg='black', fg="white", width=40).place(x=0, y=0) # method for book pic botton def take(id, tableName): root.destroy() from Frame4_randa import BOOK_PROGRAM BOOK_PROGRAM().show(id + 1, tableName) def insert(tableName, tableIndex): print('entered ') root.destroy() from insertFrame import database database().show(tableName, tableIndex) def back(): root.destroy() from FrameSpecialty import Framespecialty Framespecialty().frame1() im = list(range(len(data))) # this loop place book name image and price thaat gots from database for i in range(len(data)): #byteImgIO = io.BytesIO(data[i][1]) #byteImg = Image.open(byteImgIO) #file_like = BytesIO(data[i][1]) #img1 = PIL.Image.open(file_like, mode='r').convert('RGB') file_like = cStringIO.StringIO(data[i][1]) img1 = PIL.Image.open(file_like, mode='r').convert('RGB') im1 = img1.resize((150, 150), PIL.Image.ANTIALIAS) # to chage image size im[i] = ImageTk.PhotoImage(im1) Button(frame, text=unicode(" اسم الكتاب: ", "utf-8") + str(data[i][0]) + '\n' + unicode(" سعر الكتاب: ", "utf-8") + str(data[i][2]), compound='top', image=im[i], command=lambda i=i: take(i, self.tableName)).pack() # استعارة الكتاب # seller button Button(canvas, text=unicode(" اضافة كتاب: ", "utf-8"), command=lambda: insert(self.tableName, self.tableindex)).place( x=230, y=300) # .pack(side=BOTTOM,anchor=SE)#,padx=107,pady=5 Button(canvas, text=unicode(" عودة إلى قائمة التخصصات: ", "utf-8"), command=back).place( x=195, y=350) # .pack(side=BOTTOM,anchor=SW)#,padx=90,pady=5 root.update() canvas.create_window(0, 0, window=frame, anchor=E) canvas.config(scrollregion=canvas.bbox("all")) root.mainloop()
class histogramWidget: BACKGROUND = "#222222" EDGE_HISTOGRAM_COLOR = "#999999" NODE_HISTOGRAM_COLOR = "#555555" TOOLTIP_COLOR="#FFFF55" PADDING = 8 CENTER_WIDTH = 1 CENTER_COLOR = "#444444" ZERO_GAP = 1 UPDATE_WIDTH = 9 UPDATE_COLOR = "#FFFFFF" HANDLE_WIDTH = 5 HANDLE_COLOR = "#FFFFFF" HANDLE_LENGTH = (HEIGHT-2*PADDING) TICK_COLOR = "#FFFFFF" TICK_WIDTH = 10 TICK_FACTOR = 2 LOG_BASE = 10.0 def __init__(self, parent, x, y, width, height, data, logScale=False, callback=None): self.canvas = Canvas(parent,background=histogramWidget.BACKGROUND, highlightbackground=histogramWidget.BACKGROUND,width=width,height=height) self.canvas.place(x=x,y=y,width=width,height=height,bordermode="inside") self.logScale = logScale self.callback = callback self.edgeBars = [] self.nodeBars = [] self.binValues = [] self.numBins = len(data) - 1 self.currentBin = self.numBins # start the slider at the highest bin edgeRange = 0.0 nodeRange = 0.0 for values in data.itervalues(): if values[0] > edgeRange: edgeRange = values[0] if values[1] > nodeRange: nodeRange = values[1] edgeRange = float(edgeRange) # ensure that it will yield floats when used in calculations... nodeRange = float(nodeRange) if logScale: edgeRange = math.log(edgeRange,histogramWidget.LOG_BASE) nodeRange = math.log(nodeRange,histogramWidget.LOG_BASE) # calculate the center line - but don't draw it yet self.center_x = histogramWidget.PADDING if self.logScale: self.center_x += histogramWidget.TICK_WIDTH+histogramWidget.PADDING self.center_y = height/2 self.center_x2 = width-histogramWidget.PADDING self.center_y2 = self.center_y + histogramWidget.CENTER_WIDTH # draw the histograms with background-colored baseline rectangles (these allow tooltips to work on very short bars with little area) self.bar_interval = float(self.center_x2 - self.center_x) / (self.numBins+1) bar_x = self.center_x edge_y2 = self.center_y-histogramWidget.PADDING edge_space = edge_y2-histogramWidget.PADDING node_y = self.center_y2+histogramWidget.PADDING node_space = (height-node_y)-histogramWidget.PADDING thresholds = sorted(data.iterkeys()) for threshold in thresholds: self.binValues.append(threshold) edgeWeight = data[threshold][0] nodeWeight = data[threshold][1] if logScale: if edgeWeight > 0: edgeWeight = math.log(edgeWeight,histogramWidget.LOG_BASE) else: edgeWeight = 0 if nodeWeight > 0: nodeWeight = math.log(nodeWeight,histogramWidget.LOG_BASE) else: nodeWeight = 0 bar_x2 = bar_x + self.bar_interval edge_y = histogramWidget.PADDING + int(edge_space*(1.0-edgeWeight/edgeRange)) edge = self.canvas.create_rectangle(bar_x,edge_y,bar_x2,edge_y2,fill=histogramWidget.EDGE_HISTOGRAM_COLOR,width=0) baseline = self.canvas.create_rectangle(bar_x,edge_y2+histogramWidget.ZERO_GAP,bar_x2,edge_y2+histogramWidget.PADDING,fill=histogramWidget.BACKGROUND,width=0) self.canvas.addtag_withtag("Threshold: %f" % threshold,edge) self.canvas.addtag_withtag("No. Edges: %i" % data[threshold][0],edge) self.canvas.tag_bind(edge,"<Enter>",self.updateToolTip) self.canvas.tag_bind(edge,"<Leave>",self.updateToolTip) self.edgeBars.append(edge) self.canvas.addtag_withtag("Threshold: %f" % threshold,baseline) self.canvas.addtag_withtag("No. Edges: %i" % data[threshold][0],baseline) self.canvas.tag_bind(baseline,"<Enter>",self.updateToolTip) self.canvas.tag_bind(baseline,"<Leave>",self.updateToolTip) node_y2 = node_y + int(node_space*(nodeWeight/nodeRange)) node = self.canvas.create_rectangle(bar_x,node_y,bar_x2,node_y2,fill=histogramWidget.NODE_HISTOGRAM_COLOR,width=0) baseline = self.canvas.create_rectangle(bar_x,node_y-histogramWidget.PADDING,bar_x2,node_y-histogramWidget.ZERO_GAP,fill=histogramWidget.BACKGROUND,width=0) self.canvas.addtag_withtag("Threshold: %f" % threshold,node) self.canvas.addtag_withtag("No. Nodes: %i" % data[threshold][1],node) self.canvas.tag_bind(node,"<Enter>",self.updateToolTip) self.canvas.tag_bind(node,"<Leave>",self.updateToolTip) self.nodeBars.append(node) self.canvas.addtag_withtag("Threshold: %f" % threshold,baseline) self.canvas.addtag_withtag("No. Nodes: %i" % data[threshold][1],baseline) self.canvas.tag_bind(baseline,"<Enter>",self.updateToolTip) self.canvas.tag_bind(baseline,"<Leave>",self.updateToolTip) bar_x = bar_x2 # now draw the center line self.centerLine = self.canvas.create_rectangle(self.center_x,self.center_y,self.center_x2,self.center_y2,fill=histogramWidget.CENTER_COLOR,width=0) # draw the tick marks if logarithmic if self.logScale: tick_x = histogramWidget.PADDING tick_x2 = histogramWidget.PADDING+histogramWidget.TICK_WIDTH start_y = edge_y2 end_y = histogramWidget.PADDING dist = start_y-end_y while dist > 1: dist /= histogramWidget.TICK_FACTOR self.canvas.create_rectangle(tick_x,end_y+dist-1,tick_x2,end_y+dist,fill=histogramWidget.TICK_COLOR,width=0) start_y = node_y end_y = height-histogramWidget.PADDING dist = end_y-start_y while dist > 1: dist /= histogramWidget.TICK_FACTOR self.canvas.create_rectangle(tick_x,end_y-dist,tick_x2,end_y-dist+1,fill=histogramWidget.TICK_COLOR,width=0) # draw the update bar bar_x = self.currentBin*self.bar_interval + self.center_x bar_x2 = self.center_x2 bar_y = self.center_y-histogramWidget.UPDATE_WIDTH/2 bar_y2 = bar_y+histogramWidget.UPDATE_WIDTH self.updateBar = self.canvas.create_rectangle(bar_x,bar_y,bar_x2,bar_y2,fill=histogramWidget.UPDATE_COLOR,width=0) # draw the handle handle_x = self.currentBin*self.bar_interval-histogramWidget.HANDLE_WIDTH/2+self.center_x handle_x2 = handle_x+histogramWidget.HANDLE_WIDTH handle_y = self.center_y-histogramWidget.HANDLE_LENGTH/2 handle_y2 = handle_y+histogramWidget.HANDLE_LENGTH self.handleBar = self.canvas.create_rectangle(handle_x,handle_y,handle_x2,handle_y2,fill=histogramWidget.HANDLE_COLOR,width=0) self.canvas.tag_bind(self.handleBar, "<Button-1>",self.adjustHandle) self.canvas.tag_bind(self.handleBar, "<B1-Motion>",self.adjustHandle) self.canvas.tag_bind(self.handleBar, "<ButtonRelease-1>",self.adjustHandle) parent.bind("<Left>",lambda e: self.nudgeHandle(e,-1)) parent.bind("<Right>",lambda e: self.nudgeHandle(e,1)) # init the tooltip as nothing self.toolTipBox = self.canvas.create_rectangle(0,0,0,0,state="hidden",fill=histogramWidget.TOOLTIP_COLOR,width=0) self.toolTip = self.canvas.create_text(0,0,state="hidden",anchor="nw") self.canvas.bind("<Enter>",self.updateToolTip) self.canvas.bind("<Leave>",self.updateToolTip) def adjustHandle(self, event): newBin = int(self.numBins*(event.x-self.center_x)/float(self.center_x2-self.center_x)+0.5) if newBin == self.currentBin or newBin < 0 or newBin > self.numBins: return self.canvas.move(self.handleBar,(newBin-self.currentBin)*self.bar_interval,0) self.currentBin = newBin if self.callback != None: self.callback(self.binValues[newBin]) def nudgeHandle(self, event, distance): temp = self.currentBin+distance if temp < 0 or temp > self.numBins: return self.canvas.move(self.handleBar,distance*self.bar_interval,0) self.currentBin += distance if self.callback != None: self.callback(self.binValues[self.currentBin]) def update(self, currentBins): currentBar = self.canvas.coords(self.updateBar) self.canvas.coords(self.updateBar,currentBins*self.bar_interval+self.center_x,currentBar[1],currentBar[2],currentBar[3]) def updateToolTip(self, event): allTags = self.canvas.gettags(self.canvas.find_overlapping(event.x,event.y,event.x+1,event.y+1)) if len(allTags) == 0: self.canvas.itemconfig(self.toolTipBox,state="hidden") self.canvas.itemconfig(self.toolTip,state="hidden") return outText = "" for t in allTags: if t == "current": continue outText += t + "\n" outText = outText[:-1] # strip the last return self.canvas.coords(self.toolTip,event.x+20,event.y) self.canvas.itemconfig(self.toolTip,state="normal",text=outText,anchor="nw") # correct if our tooltip is off screen textBounds = self.canvas.bbox(self.toolTip) if textBounds[2] >= WIDTH-2*histogramWidget.PADDING: self.canvas.itemconfig(self.toolTip, anchor="ne") self.canvas.coords(self.toolTip,event.x-20,event.y) if textBounds[3] >= HEIGHT-2*histogramWidget.PADDING: self.canvas.itemconfig(self.toolTip, anchor="se") elif textBounds[3] >= HEIGHT-2*histogramWidget.PADDING: self.canvas.itemconfig(self.toolTip, anchor="sw") # draw the box behind it self.canvas.coords(self.toolTipBox,self.canvas.bbox(self.toolTip)) self.canvas.itemconfig(self.toolTipBox, state="normal")
class AppAnalysis: def __init__(self, root): self.canvas = Canvas(root, width = 400, height = 350) self.canvas.configure(cursor="crosshair") self.canvas.pack(expand=YES, fill=BOTH, side='right') self.canvas.bind("<Key>", self.handle_key) self.canvas.bind("<Double-Button-1>", self.set_focus) self.canvas.bind("<Button-1>", self.set_cursor) self.canvas.bind("<Return>", self.remove_highlight) self.image, self.ponto1, self.ponto2 = (None, None, None) self.menubar = Menu(root) filemenu = Menu(self.menubar, tearoff=0) filemenu.add_command(label="Open Image", command=self.openImage) filemenu.add_command(label="Save", command=self.hello) filemenu.add_separator() filemenu.add_command(label="Exit", command=root.quit) self.menubar.add_cascade(label="File", menu=filemenu) editmenu = Menu(self.menubar, tearoff=0) for e in ("Cut","Copy","Paste"): editmenu.add_command(label=e, command=self.hello) self.menubar.add_cascade(label="Edit", menu=editmenu) filtermenu = Menu(self.menubar, tearoff=0) filtermenu.add_command(label="Threshold", command=self.thresholdFilter) self.menubar.add_cascade(label="Filter", menu=filtermenu) reportmenu = Menu(self.menubar, tearoff=0) reportmenu.add_command(label="Relatorio.txt", command=self.generateReport) reportmenu.add_command(label="Relatorio.pdf") reportmenu.add_command(label="Email") self.menubar.add_cascade(label="Report", menu=reportmenu) helpmenu = Menu(self.menubar, tearoff=0) helpmenu.add_command(label="About", command=self.hello) self.menubar.add_cascade(label="Help", menu=helpmenu) root.config(menu=self.menubar) self.toolbar = Frame(root) self.toolbar.pack(side='left', fill='both') clean = Label(self.toolbar, text='Clean') clean.bind("<Button-1>", self.clean) b = Label(self.toolbar, text='B') c = Label(self.toolbar, text='C') d = Label(self.toolbar, text='D') for w in (clean,b,c,d): w.configure(relief="groove", font="Times 12 bold") w.pack(fill='both') def openImage(self): arquivo = tkFileDialog.askopenfile(parent=self.canvas,mode='rb', title='Imagem') e = ['GIF','JPEG','JPG','BMP','PNG','TIF'] if(e.__contains__(arquivo.name.split(".")[-1].upper())): self.ponto1, self.ponto2 = (None,None) img_tmp = Image.open(arquivo) #self.img_name = path.dirname(path.abspath(arquivo.name)) self.img_name = arquivo.name print self.img_name self.new_img_name = arquivo.name.split('/')[-1] + "_tmp.gif" pathtemp = mydir +"/temp/"+ self.new_img_name img_tmp.save(pathtemp) self.image = PhotoImage(file=pathtemp) self.setImage() self.canvas.bind("<Button-1>", self.click) self.proporcao = "" def clean(self, event): self.ponto1, self.ponto2 = (None,None) self.setImage() self.proporcao = "" def setImage(self): self.canvas.delete(ALL) if self.image.width() > 200 and self.image.height > 200: self.canvas.config(width = self.image.width()) self.canvas.config(height = self.image.height()) self.canvas.create_image(0, 0, image=self.image, anchor=NW) def generateReport(self): report = GeradorRelatorio(self.img_name) report.start() def hello(self): print "hello!" def thresholdFilter(self): img = Image.open(self.img_name) new_img = img.filter(ImageFilter.BLUR) aux = mydir +"/temp/"+ self.new_img_name new_img.save(aux) self.image = PhotoImage(file=aux) self.setImage() def click(self, event): if not self.ponto1: self.canvas.create_oval(event.x, event.y, event.x+5, event.y+5, fill="red") self.ponto1 = (event.x,event.y) else: if not self.ponto2: self.canvas.create_oval(event.x, self.ponto1[1], event.x+5, self.ponto1[1]+5, fill="red") self.ponto2 = (event.x,self.ponto1[1]) pontos = [self.ponto1[0]+1,self.ponto1[1]+2, self.ponto2[0]+1,self.ponto2[1]+2] self.canvas.create_line(pontos, tags="theline", fill='red') x = (self.ponto2[0] + self.ponto1[0]) / 2 self.canvas.create_text(x, self.ponto1[1]+8, text="1 umm") def remove_highlight(self,event): self.canvas.delete("highlight") def highlight(self, item): bbox = self.canvas.bbox(item) self.canvas.delete("highlight") if bbox: i = self.canvas.create_rectangle( bbox, fill="white", tag="highlight" ) self.canvas.lower(i, item) def has_focus(self): return self.canvas.focus() def has_selection(self): return self.canvas.tk.call(self.canvas._w, 'select', 'item') def set_focus(self, event): if self.canvas.type(CURRENT) != "text": return self.highlight(CURRENT) self.canvas.focus_set() self.canvas.focus(CURRENT) self.canvas.select_from(CURRENT, 0) self.canvas.select_to(CURRENT, END) def set_cursor(self, event): item = self.has_focus() if not item: return x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) self.canvas.icursor(item, "@%d,%d" % (x, y)) self.canvas.select_clear() def handle_key(self, event): item = self.has_focus() if not item: return insert = self.canvas.index(item, INSERT) if event.char >= " ": if self.has_selection(): self.canvas.dchars(item, SEL_FIRST, SEL_LAST) self.canvas.select_clear() self.canvas.insert(item, "insert", event.char) self.highlight(item) elif event.keysym == "BackSpace": if self.has_selection(): self.canvas.dchars(item, SEL_FIRST, SEL_LAST) self.canvas.select_clear() else: if insert > 0: self.canvas.dchars(item, insert-1, insert) self.highlight(item) elif event.keysym == "Home": self.canvas.icursor(item, 0) self.canvas.select_clear() elif event.keysym == "End": self.canvas.icursor(item, END) self.canvas.select_clear() elif event.keysym == "Right": self.canvas.icursor(item, insert+1) self.canvas.select_clear() elif event.keysym == "Left": self.canvas.icursor(item, insert-1) self.canvas.select_clear() else: pass
class MtgProxyView(Frame): """The View, which takes care of the visual representation of the model. Attributes: root: the root panel for the visual represantion cardModel: the cardModel class which deals with all the internal card data home: the path of where images are located safeHome: the path where PDfs are supposed to be saved cnfData: the path to the config file defaultImage: the path to the default image listFrame: the frame in which the mode is portraied canvas: tha canvas which allows scrolling and a grid myscrollbar: the scrollbar which gives the user the abilty to scroll through the list of cards buttonframe: the frame in which the action buttons are being placed wipeWorkspace: the button which corresponds with the clear worksapce function bSelectDir: the button which corresponds with the selectDir function selectSaveDir: the button which corresponds with the selectSaveDir function bMake: the button which corresponds with the makePdf function addButton: the button which corresponds with the addNewCard function """ def __init__(self): """ This is the the constructor of the MtgProxyView It takes care of all the setup and doesnt require anything from the main """ #basic setup sizex = 765 sizey = 525 posx = 0 posy = 0 self.root = Tk() self.root.title("PyProxies") self.root.wm_geometry("%dx%d+%d+%d" % (sizex, sizey, posx, posy)) self.root.resizable(width=False, height=False) #backend data setup self.cardmodel = Cardmodel() #constants self.home = "" self.safeHome = "" self.cnfData = "upm.cnf" self.defaultImage = "noCard.jpg" self.loadConfig() #list setup self.listframe = Frame(self.root, relief=GROOVE, width=500, height=500, bd=1) self.listframe.place(x=10, y=10) self.canvas = Canvas(self.listframe) self.frame = Frame(self.canvas) self.myscrollbar = Scrollbar(self.listframe, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.myscrollbar.set) #and it scrollbar self.myscrollbar.pack(side="right", fill="y") self.canvas.pack(side="left") self.canvas.create_window((0, 0), window=self.frame, anchor='nw') #button setup self.buttonframe = Frame(self.root, relief=GROOVE, width=100, height=500, bd=1, padx=15, pady=10) self.buttonframe.place(x=535, y=10) self.wipeWorkspace = Button(self.buttonframe, text="clear Workspace", command=self.completeWipe, width=20) self.wipeWorkspace.pack(anchor="sw", pady=5) self.bSelectDir = Button(self.buttonframe, text="select a fitting Directory", command=self.selectDir, width=20) self.bSelectDir.pack(anchor="sw", pady=5) self.selectSaveDir = Button(self.buttonframe, text="Select a save directory", command=self.selectSafeDir, width=20) self.selectSaveDir.pack(anchor="sw", pady=5) self.bMake = Button(self.buttonframe, text="make PDF", command=self.makePdf, width=20) self.bMake.pack(anchor="sw", pady=5) self.addButton = Button(self.frame, text="add a new Card", command=self.addNewCard) self.frame.bind("<Configure>", self.myfunction) self.data() self.root.mainloop() def loadConfig(self): """ This is the functions which loads the configuration. Only the place where Images can be added as sources and where PDFs can be saved, are able to be set and saved. """ configFile = open(self.cnfData, "r+") temp = configFile.read().split("\n") try: self.home = expanduser("~") if os.path.exists(temp[0]): self.home = temp[0] self.safeHome = expanduser("~") if os.path.exists(temp[1]): self.safeHome = temp[1] except IndexError: print "Error" self.home = expanduser("~") self.safeHome = expanduser("~") print "new homes" print self.home print self.safeHome configFile.close() def saveConfig(self): """ This Function takes care of writing the values of the home and the saveHome to the configuration file """ configFile = open(self.cnfData, "w") configFile.write(self.home + "\n" + self.safeHome) print "config saved" configFile.close() self.loadConfig() def completeWipe(self): """ This function clears the workspace of all of its components and resets the Model. """ for i in range(self.cardmodel.getCardCount()): #self.cardHowOften[i]=0 self.cardmodel.setCardHowOften(i, 0) self.cardmodel.setImg(self.defaultImage, i) #self.imgPaths[i] = self.defaultImage self.cardmodel.resetCardCount() for w in self.frame.winfo_children(): w.destroy() self.data() def selectSafeDir(self): """ This function sets the directory where exported PDFs are being stored. Its does this by invoking the tkFileDialog which asks for user input and returns a valid path. """ path = tkFileDialog.askdirectory( initialdir=self.safeHome, title="Select a better save directory.") if isinstance(path, basestring): self.safeHome = path self.saveConfig() def selectDir(self): """ This function provides the user with the functionality to set their starting directory for adding source images. They can do this in order to save time and optimize their workflow. Its does this by invoking the tkFileDialog which asks for user input and returns a valid path. """ path = tkFileDialog.askdirectory( initialdir=self.home, title="Select a better working directory.") if isinstance(path, basestring): self.home = path self.saveConfig() def data(self): """ The data function takes care of going over the entiry model and representing it on the canvas object. It is only supposed to be invoked when the workspace has been cleard beforehand. """ for i in range(self.cardmodel.getCardCount()): #image label pilFile = Image.open(self.cardmodel.getImg(i)) image1 = pilFile.resize((60, 80), Image.ANTIALIAS) image2 = ImageTk.PhotoImage(image1) imageLabel = Label(self.frame, image=image2) imageLabel.image = image2 imageLabel.grid(row=i, column=0, padx=2, pady=2) #other labels Label(self.frame, text="Card is being printed " + str(self.cardmodel.getCardHowOftenAt(i)) + " times.").grid( row=i, column=1) Button(self.frame, text="-", command=lambda i=i: self.decrHowOften(i)).grid(row=i, column=2) Button(self.frame, text="+", command=lambda i=i: self.incrHowOften(i)).grid(row=i, column=3) Button(self.frame, text="add Source", command=lambda i=i: self.getImgPath(i)).grid(row=i, column=4) Button(self.frame, text="X", command=lambda i=i: self.delete(i)).grid(row=i, column=5) self.addButton = Button(self.frame, text="add a new Card", command=self.addNewCard) self.addButton.grid(row=self.cardmodel.getCardCount(), column=0, columnspan=2, padx=10, pady=20, sticky="W") def updateOne(self, i): """ This Function is supposed to only update one row of the Canvas in, which the model is displayed. Args: i: the index of the row which is supposed to be updated """ pilFile = Image.open(self.cardmodel.getImg(i)) image1 = pilFile.resize((60, 80), Image.ANTIALIAS) image2 = ImageTk.PhotoImage(image1) imageLabel = Label(self.frame, image=image2) imageLabel.image = image2 imageLabel.grid(row=i, column=0, padx=2, pady=2) # other labels Label(self.frame, text="Card is being printed " + str(self.cardmodel.getCardHowOftenAt(i)) + " times.").grid( row=i, column=1) Button(self.frame, text="-", command=lambda i=i: self.decrHowOften(i)).grid(row=i, column=2) Button(self.frame, text="+", command=lambda i=i: self.incrHowOften(i)).grid(row=i, column=3) Button(self.frame, text="add Source", command=lambda i=i: self.getImgPath(i)).grid(row=i, column=4) Button(self.frame, text="X", command=lambda i=i: self.delete(i)).grid(row=i, column=5) def delete(self, i): """ This function is supposed to delete one Card and update the model accordingly. Args: i: the indexing of the row, which is supposed to be updated """ self.cardmodel.deleteCard(i) #complete reset for w in self.frame.winfo_children(): w.destroy() self.data() def incrHowOften(self, i): """ This function takes care of increasing the counter of how often a card is supposed to be printed. Args: i: the row in which the the card is located """ self.cardmodel.incrCardHowOften(i) self.updateOne(i) def decrHowOften(self, i): """ This function takes care of decreasing the counter of how often a card is supposed to be printed. Args: i: the row in which the the card is located """ self.cardmodel.decrCardHowOften(i) self.updateOne(i) def addNewCard(self): """ This function adds a new card to the model and updates it with default values. It then invokes the updateOne-function in order to update the view. """ self.cardmodel.addCard() self.addButton.destroy() self.addButton = Button(self.frame, text="add a new Card", command=self.addNewCard) self.addButton.grid(row=self.cardmodel.getCardCount(), column=0, columnspan=2, padx=10, pady=20, sticky="W") self.updateOne(self.cardmodel.getCardCount() - 1) def myfunction(self, event): """ A function which is called in the event of a configuration concerning the frame. It sets the scrollregion of the scrollbar to be the canvas """ self.canvas.configure(scrollregion=self.canvas.bbox("all"), width=500, height=500) def getImgPath(self, i): """ This function allows the user to change the image source of a card. It does this by invoking the tkFileDialog in order to ask for a filename, limited to JPGs and PNGs. If the user input something it updates the model. Args: i: index of the row in which the card is located """ imgPath = tkFileDialog.askopenfilenames(initialdir=self.home, title="Select Image", filetypes=[ ("JPG files", "*.jpg"), ("PNG files", "*.png"), ("JPEG files", "*.jpeg") ]) print imgPath print str(imgPath) == "()" if str(imgPath) != "()" and str(imgPath) != "": print(imgPath[0]) self.cardmodel.setImg(imgPath[0], i) self.updateOne(i) else: print "user didnt select anything" def makePdf(self): """ This function gives the user the functionality to select a filename for the PDF they want to print. Afterwards if a name has been entered the function gives the model to the proxymaker module, which creates a PDF in the desired location. """ name = tkSimpleDialog.askstring( 'Input', 'Enter the desired name for the PDF, without suffix') if name is not None: proxymaker.writeData(self.cardmodel, self.safeHome + "/" + name + ".pdf")
class OriginalImage(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.root = parent self.orginal_img = Canvas(self) self.orginal_img.grid(row=0, column=0) self.orginal_img.bind('<ButtonPress-1>', self.on_mouse_down) self.orginal_img.bind('<B1-Motion>', self.on_mouse_drag) self.orginal_img.bind('<ButtonRelease-1>', self.on_mouse_up) self.orginal_img.bind('<Button-3>', self.on_right_click) self._set_variables_initial_state() def _set_variables_initial_state(self): self.drag_color = CLASS_COLOR[0] self.item = None self.data_observers = [] self.coordinates_observers = [] def get(self): try: return self.orginal_img.image except Exception: return None def register_data_observers(self, observers): self.data_observers.append(observers) def register_coordinates_observers(self, observers): self.coordinates_observers.append(observers) def _notify_data_observers(self, pixel_values): for observer in self.data_observers: observer.add_samples(pixel_values) def _notify_coordinates_observers(self, img_region): for observer in self.coordinates_observers: observer.add_sample_coordinates(img_region) def set_image(self, current_image): self.orginal_img.image = current_image self.orginal_img.photo = PhotoImage(self.orginal_img.image) self.orginal_img.create_image(0, 0, image=self.orginal_img.photo, anchor='nw', tags='img') w, h = self.orginal_img.image.size self.orginal_img.config(width=w, height=h, scrollregion=self.orginal_img.bbox('all')) def set_drag_color(self, color): self.drag_color = color def reset(self): try: self.orginal_img.create_image(0, 0, image=self.orginal_img.photo, anchor='nw', tags='img') self._set_variables_initial_state() except AttributeError: # No image was previously opened pass def on_mouse_down(self, event): self.anchor = (event.widget.canvasx(event.x), event.widget.canvasy(event.y)) self.item = None def on_mouse_drag(self, event): bbox = self.anchor + (event.widget.canvasx( event.x), event.widget.canvasy(event.y)) if self.item is None: self.item = event.widget.create_rectangle(bbox, outline=self.drag_color, fill=self.drag_color) else: event.widget.coords(self.item, *bbox) def on_mouse_up(self, event): if self.item: self.on_mouse_drag(event) box = tuple( (int(round(v)) for v in event.widget.coords(self.item))) box = tuple([i if i > 0 else 0 for i in box]) img_region = self.orginal_img.image.crop(box) pixel_values = list(img_region.getdata()) self._notify_data_observers(pixel_values) self._notify_coordinates_observers(box) def on_right_click(self, event): found = event.widget.find_all() for iid in found: if event.widget.type(iid) == 'rectangle': event.widget.delete(iid)
class Breakout(Tk): def __init__(self): Tk.__init__(self) #self.canvas.delete('all') self.geometry('790x600') self.resizable( 0, 0 ) #set both parameters to false and to check whether window is resizable in x and y directions self.func() # game screen def func(self): self.canvas = Canvas(self, bg='skyblue', width=990, height=600, highlightcolor='green') self.canvas.pack( expand=1, fill=BOTH ) #when it is true and widget expands to fill any space # ball self._initiate_new_ball() #self.level=choice([1]) # paddle self.canvas.create_rectangle(375, 975, 525, 585, fill='red', tags='paddle') self.bind('<Key>', self._move_paddle) # bricks self.bricks = {} brick_coords = [15, 12, 60, 45] for i in range(56): self.canvas.create_rectangle(brick_coords, outline='green', fill=('yellow'), tags='brick' + str(i)) self.bricks['brick' + str(i)] = None brick_coords[0] += 55 brick_coords[2] += 55 if brick_coords[2] > 790: brick_coords[0] = 15 brick_coords[2] = 60 brick_coords[1] += 55 brick_coords[3] += 55 def _initiate_new_ball(self): if self.canvas.find_withtag('ball'): self.canvas.delete('ball') self.x = 300 self.y = 350 self.angle = 240 self.speed = 10 self.level = 0 self.score = 0 self.canvas.create_oval(self.x, self.y, self.x + 10, self.y + 10, fill='orange', outline='red', tags='ball') self.after(2000, self._move_ball) def _move_paddle(self, event): if event.keysym == 'Left': if self.canvas.coords('paddle')[0] > 0: self.canvas.move('paddle', -20, 0) elif event.keysym == 'Right': if self.canvas.coords('paddle')[2] < 990: self.canvas.move('paddle', +20, 0) #def _move_ball1(self): # call1() #self._initiate_new_ball1() def _move_ball(self): # variables to determine where ball is in relation to other objects ball = self.canvas.find_withtag('ball')[0] bounds = self.canvas.find_overlapping(0, 0, 790, 600) paddle = self.canvas.find_overlapping( *self.canvas.coords('paddle')) for brick in self.bricks.iterkeys(): self.bricks[brick] = self.canvas.find_overlapping( *self.canvas.bbox(brick)) # calculate change in x,y values of ball angle = self.angle - 120 # correct for quadrant IV increment_x = cos(radians(angle)) * self.speed increment_y = sin(radians(angle)) * self.speed #self.level += choice([1]) #score=self.score #score=0 # finite state machine to set ball state if ball in bounds: self.ball_state = 'moving' for brick, hit in self.bricks.iteritems(): if ball in hit: self.ball_state = 'hit_brick' delete_brick = brick elif ball in paddle: self.ball_state = 'hit_wall' elif (self.score) // 3 == 56: self.canvas.create_text( WIDTH / 4, HEIGHT / 2.3, text="CONGRATS!! GAME COMPLETED!", font=("Helvetica", 20), fill="orange") self.canvas.create_text(WIDTH / 4, HEIGHT / 2, text=(self.score // 3), font=("Helvetica", 20), fill="red") self.canvas.create_text(WIDTH / 4, HEIGHT / 1.7, text="YOUR SCORE ", font=("Helvetica", 20), fill="darkorange") #image() quit_to_exit() call() elif ball not in bounds: if self.canvas.coords('ball')[1] < 600: self.ball_state = 'hit_wall' else: self.ball_state = 'out_of_bounds' #self.level += choice([1]) self.canvas.create_text( WIDTH / 2.5, HEIGHT / 2.3, text="GAME OVER !!PLEASE CLOSE THE WINDOW TO RESTART!", tag="cr2", font=("Helvetica", 20), fill="orange") self.canvas.create_text(WIDTH / 4, HEIGHT / 2, text="YOUR SCORE IS", tag="cr1", font=("Helvetica", 20), fill="orange") self.canvas.create_text(WIDTH / 4, HEIGHT / 1.7, text=(self.score // 3) + 1, tag="cr", font=("Helvetica", 20), fill="red") quit_to_exit() call() self._initiate_new_ball() #self.bind('<key>',self.game_over) #game = Breakout() #game.mainloop() # handler for ball state if self.ball_state is 'moving': self.canvas.move('ball', increment_x, increment_y) self.after(35, self._move_ball) # self.level +=choice([1]) elif self.ball_state is 'hit_brick' or self.ball_state is 'hit_wall': if self.ball_state == 'hit_brick': self.canvas.delete(delete_brick) del self.bricks[delete_brick] self.canvas.move('ball', -increment_x, -increment_y) # self.level += choice([1]) self.score += choice([1]) self.angle += choice([135]) self.canvas.delete("cr") self.canvas.delete("cr1") self.canvas.delete("cr2") #canvas.create_text(WIDTH/4,HEIGHT/5,text="GAME OVER!") self._move_ball()
class OriginalImage(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.root = parent self.orginal_img = Canvas(self) self.orginal_img.grid(row = 0, column = 0) self.orginal_img.bind('<ButtonPress-1>', self.on_mouse_down) self.orginal_img.bind('<B1-Motion>', self.on_mouse_drag) self.orginal_img.bind('<ButtonRelease-1>', self.on_mouse_up) self.orginal_img.bind('<Button-3>', self.on_right_click) self._set_variables_initial_state() def _set_variables_initial_state(self): self.drag_color = CLASS_COLOR[0] self.item = None self.data_observers = [] self.coordinates_observers = [] def get(self): try: return self.orginal_img.image except Exception: return None def register_data_observers(self, observers): self.data_observers.append(observers) def register_coordinates_observers(self, observers): self.coordinates_observers.append(observers) def _notify_data_observers(self, pixel_values): for observer in self.data_observers: observer.add_samples(pixel_values) def _notify_coordinates_observers(self, img_region): for observer in self.coordinates_observers: observer.add_sample_coordinates(img_region) def set_image(self, current_image): self.orginal_img.image = current_image self.orginal_img.photo = PhotoImage(self.orginal_img.image) self.orginal_img.create_image(0, 0, image = self.orginal_img.photo, anchor = 'nw', tags = 'img') w, h = self.orginal_img.image.size self.orginal_img.config(width = w, height = h, scrollregion = self.orginal_img.bbox('all')) def set_drag_color(self, color): self.drag_color = color def reset(self): try: self.orginal_img.create_image(0, 0, image = self.orginal_img.photo, anchor = 'nw', tags = 'img') self._set_variables_initial_state() except AttributeError: # No image was previously opened pass def on_mouse_down(self, event): self.anchor = (event.widget.canvasx(event.x), event.widget.canvasy(event.y)) self.item = None def on_mouse_drag(self, event): bbox = self.anchor + (event.widget.canvasx(event.x), event.widget.canvasy(event.y)) if self.item is None: self.item = event.widget.create_rectangle(bbox, outline = self.drag_color, fill = self.drag_color) else: event.widget.coords(self.item, *bbox) def on_mouse_up(self, event): if self.item: self.on_mouse_drag(event) box = tuple((int(round(v)) for v in event.widget.coords(self.item))) box = tuple([i if i>0 else 0 for i in box]) img_region = self.orginal_img.image.crop(box) pixel_values = list(img_region.getdata()) self._notify_data_observers(pixel_values) self._notify_coordinates_observers(box) def on_right_click(self, event): found = event.widget.find_all() for iid in found: if event.widget.type(iid) == 'rectangle': event.widget.delete(iid)
class ImageViewer(Frame, object): class _Panner(object): def __init__(self): self.viewers = [] self._factor = 1 self._drags = [] self._cdrag = None def add(self, val): self.viewers.append(val) for mark, end in self._drags: val.canvas.scan_mark(*mark) val.canvas.scan_dragto(*end, gain=1) if self._cdrag: val.canvas.scan_mark(*self._cdrag[0]) val.canvas.scan_dragto(*self._cdrag[1], gain=1) def move_mark(self, x, y): if self._cdrag: self._drags.append(self._cdrag) self._cdrag = [(x, y), (x, y)] for viewer in self.viewers: viewer.canvas.scan_mark(x, y) def move_actual(self, x, y): self._cdrag[1] = (x, y) for viewer in self.viewers: viewer.canvas.scan_dragto(x, y, gain=1) def update(self): for viewer in self.viewers: viewer._update() def __init__(self, master, panner=None): super(ImageViewer, self).__init__(master) self._image = None self._view = None self._view_id = None self.canvas = Canvas(self, background="#000") self.canvas.pack(fill='both', expand=1) self.canvas.bind("<MouseWheel>", self.zoom) self.canvas.bind("<ButtonPress-1>", self.scroll_start) self.canvas.bind("<B1-Motion>", self.scroll_move) # self.canvas.bind("<Enter>", self.focus_widget) # self.canvas.bind("<Leave>", self.unfocus_widget) self.popup_menu = PopupMenu(self.canvas) for val in (10, 25, 50, 75, 100, 150, 200, 250, 300, 500): self.popup_menu.add_command(label="%d%%"%val, command=(lambda v:(lambda :self.set_factor(v/100.)))(val)) self.popup_menu.attach() self._panner = panner if panner is None: self._panner = ImageViewer._Panner() self._panner.add(self) self._focus_prev = None def destroy(self): self._panner.viewers.remove(self) super(ImageViewer, self).destroy() @property def image(self): return self._image @image.setter def image(self, value): self._image = value self.after(1, self.show) @property def factor(self): return self._panner._factor @factor.setter def factor(self, value): self._panner._factor = value self.after(1, self.show) def set_factor(self, value): self.factor = value def zoom(self, event): if event.delta < 0: if self.factor == .1: return self.factor -= .1 elif event.delta > 0: if self.factor == 5: return self.factor += .1 self.show() def scroll_start(self, event): self._panner.move_mark(event.x, event.y) def scroll_move(self, event): self._panner.move_actual(event.x, event.y) def focus_widget(self, event): self._focus_prev = self.canvas.focus_get() self.focus_set() def unfocus_widget(self, event): self._focus_prev.focus_set() def show(self): self._panner.update() def _update(self): if self._image is None: return if self._view_id is not None: self.canvas.delete(self._view_id) x, y = self.image.size x, y = int(round(x*self.factor)), int(round(y*self.factor)) self._view = ImageTk.PhotoImage(self.image.resize((x, y))) self._view_id = self.canvas.create_image(0, 0, image=self._view, anchor="nw") self.canvas.configure(scrollregsion=self.canvas.bbox("ALL"))
class at_graph(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.u = utils('atoutput.pkl') self.km = dict() self.price = dict() self.km[0] = (min(self.u.all_km), max(self.u.all_km)) self.price[0] = (min(self.u.all_price), max(self.u.all_price)) self.zoom_level = 0 try: self.parent.title("Auto trader results") self.is_standalone = True except: self.is_standalone = False self.style = Style() self.style.theme_use("classic") # Assume the parent is the root widget; make the frame take up the # entire widget size. print self.is_standalone if self.is_standalone: self.w, self.h = map(int, self.parent.geometry().split('+')[0].split('x')) self.w, self.h = 800, 800 else: self.w, self.h = 600, 600 self.c = None # Are they hovering over a data point? self.is_hovering = False # Filter the description strings: lower and whiten any non-matching # data point. self.filter = '' self.re = list() self.replot() def replot(self, zlfrac=None): """Replot the graph. If zlfrac is not None, then it should be a fractional value between 0 and 1; this is used to do smooth zooming, which doesn't plot the axes (it only redraws the car points).""" if self.c is not None: self.c.destroy() self.c = Canvas(self, height=self.h, width=self.w, bd=1, bg='#f3f5f9') self.c.grid(sticky=S, pady=1, padx=1) zl = self.zoom_level if zlfrac is not None: z1l, z1h = self.zoom_price_start z2l, z2h = self.zoom_price_end price_low = z1l + (z2l - z1l) * zlfrac price_high = z1h + (z2h - z1h) * zlfrac z1l, z1h = self.zoom_km_start z2l, z2h = self.zoom_km_end km_low = z1l + (z2l - z1l) * zlfrac km_high = z1h + (z2h - z1h) * zlfrac self.axis((price_low, price_high), 'y', draw=False) self.axis((km_low, km_high), 'x', draw=False) self.car_points(draw=False) else: self.axis(self.price[zl], 'y') self.axis(self.km[zl], 'x') self.car_points() self.pack(fill=BOTH, expand=1) def xyp(self, x, y): "Given x in km and y in $, return canvas position (xp, yp)." xp = int(math.floor((1.0 * x - self.x1) / (self.x2 - self.x1) \ * (self.xp2 - self.xp1) + self.xp1 + 0.5)) yp = int(math.floor((1.0 * y - self.y1) / (self.y2 - self.y1) \ * (self.yp2 - self.yp1) + self.yp1 + 0.5)) return (xp, yp) def axis(self, arange, ax, draw=True): "Add an axis ax='x' or 'y', with arange=(min, max) values." if draw: a1, a2, ast = self.u.axis(*arange) else: a1, a2 = arange ast = (a2 - a1) * 0.2 nt = int(math.floor((a2 - a1) / ast + 0.5)) + 1 st_offset = 50 # Remember the min and max axis values, along with the canvas points # that correspond to each location (xp1 and xp2). This allows us to # calculate where on the canvas a particular (x, y) value falls. if ax == 'x': self.x1, self.x2 = a1, a2 self.xp1, self.xp2 = st_offset, self.w - st_offset self.xtick = [a1 + i * ast for i in range(nt)] # Remember where the midpoint of the axis is, relative to canvas. self.xmid = (self.xp1 + self.xp2) / 2 else: self.y1, self.y2 = a1, a2 self.yp1, self.yp2 = self.h - st_offset, st_offset self.ytick = [a1 + i * ast for i in range(nt)] # Remember where the midpoint of the axis is, relative to canvas. self.ymid = (self.yp1 + self.yp2) / 2 # Figure out tick labels. atick = ['%g' % ((a1 + i * ast) / 1000) for i in range(nt)] # Figure out maximum decimal places on all tick labels, and ensure # they all have that many decimal places. max_dec = max(map(lambda x: 0 if '.' not in x else len(x.split('.')[1]), atick)) if max_dec > 0: atick = map(lambda x: x + '.' + '0'*max_dec if '.' not in x else x + '0'*(max_dec - len(x.split('.')[1])), atick) yst, xst = self.h - st_offset, st_offset # Draw axis line proper, and axis label. if draw: if ax == 'x': self.c.create_line(xst, yst, self.w - st_offset, yst) xp = (xst + self.w - st_offset) / 2 self.c.create_text(xp, yst + 30, text='Mileage (km x 1000)') else: self.c.create_line(xst, yst, xst, st_offset) self.c.create_text(xst, st_offset - 30, text='Price') self.c.create_text(xst, st_offset - 15, text='($000)') tick_anchor = [N, E][ax == 'y'] tick_x, tick_y = xst, yst tick_step = ([self.w, self.h][ax == 'y'] - st_offset * 2 * 1.0) / \ (nt - 1) label_offset = 3 for i1, tick in enumerate(atick): x_of, y_of = -label_offset, label_offset if ax == 'y': y_of = int(-i1 * tick_step) else: x_of = int(i1 * tick_step) if draw: self.c.create_text(tick_x + x_of, tick_y + y_of, text=tick, anchor=tick_anchor) x_mini, y_mini = 0, 0 x_maxi, y_maxi = 0, 0 if ax == 'y': x_of += label_offset x_mini, x_maxi = 8, self.w - st_offset * 2 # Remember what y coord this grid line is at. if i1 == 0: self.y_grid = [] self.y_grid.append(tick_y + y_of) else: y_of -= label_offset y_mini, y_maxi = -8, st_offset * 2 - self.h # Remember what x coord this grid line is at. if i1 == 0: self.x_grid = [] self.x_grid.append(tick_x + x_of) if draw: # Draw the little solid tick, next to the axis. self.c.create_line(tick_x + x_of, tick_y + y_of, tick_x + x_of + x_mini, tick_y + y_of + y_mini) # Draw a dashed grid line, across the entire graph. self.c.create_line(tick_x + x_of, tick_y + y_of, tick_x + x_of + x_maxi, tick_y + y_of + y_maxi, dash=(1, 3)) def car_points(self, draw=True): "Plot the cars themselves." # 199 215 151 151 199 224 230 162 157 250 224 167 178 165 192 249 200 216 204 204 204 191 173 158 color_order = ['#c7d797', '#97c7e0', '#e6a29d', '#fae0a7', '#b2a5c0', '#f9c8d8', '#bfad9e', '#cccccc'] #color_order = ['#98df8a', '#dbdb8d', '#aec7e8', '#c9acd4', '#f7b6d2', # '#ffbb80', '#dc9b8d', '#e9ab17', '#dddddd'] # Those colors above aren't saturated enough. Saturate them more. color_order = map(lambda x: resaturate(x, -80), color_order) # Change color depending on year. cy = dict() for i1, year in enumerate(reversed(sorted(set(self.u.all_year)))): cy[year] = color_order[-1] if i1 < len(color_order): cy[year] = color_order[i1] i1 = -1 # Tuples of (index into self.u.all_* arrays, x position, y position). self.ov_dict = dict() if draw: self.c.focus_set() self.c.bind('<Button-1>', func=self.zoom) self.c.bind('<Button-2>', func=self.unzoom) self.c.bind('<Left>', func=self.left_key) self.c.bind('<Right>', func=self.right_key) self.c.bind('<Up>', func=self.up_key) self.c.bind('<Down>', func=self.down_key) legend = set() osz = 3 + self.zoom_level * 1 # Total vehicle count, and vehicles which pass the filter count. self.vcount = self.fcount = 0 for year, km, price in zip(self.u.all_year, self.u.all_km, self.u.all_price): x, y = self.xyp(km, price) i1 += 1 if x < self.x_grid[0] or x > self.x_grid[-1] or \ y > self.y_grid[0] or y < self.y_grid[-1]: continue self.vcount += 1 legend.add((year, cy[year])) filtered = False if not re.search(self.filter, self.u.all_descr[i1], re.I): filtered = True # If a data point is filtered out, make its outline reflect its # model year, and fill it with white. # # Else, make its outline and fill color reflect the model year, and # upon mouseover, make it entirely red. ov = self.c.create_oval(x-osz, y-osz, x+osz, y+osz, outline=cy[year], activeoutline=['red', cy[year]][filtered], fill=[cy[year], 'white'][filtered], activefill=['red', 'white'][filtered], ) self.ov_dict[ov] = (i1, x, y, cy[year], filtered) # If a data point is filtered out, mousing over it does nothing, # and also, lower it behind everything else. if filtered: self.c.lower(ov) else: self.fcount += 1 if draw: use_tag = 'Tag %d' % i1 self.c.addtag_withtag(use_tag, ov) self.c.tag_bind(use_tag, sequence='<Enter>', func=self.mouseover) self.c.tag_bind(use_tag, sequence='<Leave>', func=self.mouseoff) self.c.tag_bind(use_tag, sequence='<Button-1>', func=self.select) if draw: # OK, add a legend for every year that's displayed. i1 = 0 for yr, color in reversed(sorted(legend)): xp, yp = self.x_grid[-1] + 10, self.y_grid[-1] + 15 * i1 self.c.create_oval(xp-osz, yp-osz, xp+osz, yp+osz, outline=color, fill=color) self.c.create_text(xp + 8, yp, text=str(yr), anchor=W) i1 += 1 # And, add a title. tistr = 'Vehicle count: %d' % self.vcount if self.fcount != self.vcount: tistr = 'Filtered vehicle count: %d' % self.fcount xp = (self.x_grid[0] + self.x_grid[-1]) / 2 yp = self.y_grid[-1] - 30 self.c.create_text(xp, yp, text=tistr, font=('Helvetica', '16')) zstr1 = 'Click on a blank graph location to zoom in' zstr2 = 'Right click to zoom out' if self.zoom_level == 0: zstr = zstr1 elif self.zoom_level == 2: zstr = zstr2 else: zstr = zstr1 + ', or r' + zstr2[1:] self.c.create_text(xp, yp + 16, text=zstr, font=('Helvetica', '14')) def mouseover(self, event): oval = event.widget.find_closest(event.x, event.y)[0] # XXX Sometimes, the closest widget is an axis grid line, not an oval. # Need to handle this correctly eventually. if oval not in self.ov_dict: return self.is_hovering = True ind, x, y, color, filtered = self.ov_dict[oval] # Figure out how high the box needs to be by creating the text off- # graph, then getting its bbox and deleting it. w = 200 de_text = self.u.all_descr[ind] deobj = self.c.create_text(self.w + 3, self.h + 3, text=de_text, anchor=N+W, width=w-6, font=('Helvetica', '14')) bbox = self.c.bbox(deobj) self.c.delete(deobj) h = 18 + bbox[3] - bbox[1] border = 5 if x > self.xmid: x -= (w + border) else: x += border if y > self.ymid: y -= (h + border) else: y += border self.re = list() self.re.append(self.c.create_rectangle(x, y, x + w, y + h, fill=resaturate(color, 50))) pr_text = '$%s' % self.u.commafy(self.u.all_price[ind]) self.re.append(self.c.create_text(x + 3, y + 3, text=pr_text, anchor=N+W, font=('Helvetica', '10'))) km_text = '%skm' % self.u.commafy(self.u.all_km[ind]) self.re.append(self.c.create_text(x + w - 3, y + 3, text=km_text, anchor=N+E, font=('Helvetica', '10'))) wh_text = self.u.all_wherestr[ind] if wh_text[0].isdigit(): wh_text += ' away' self.re.append(self.c.create_text(x + w/2, y + 3, text=wh_text, anchor=N, font=('Helvetica', '10'))) self.re.append(self.c.create_text(x + 3, y + 16, text=de_text, anchor=N+W, width=w-6, font=('Helvetica', '14'))) def set_filter(self, st): "Given a string 'st', filter ovals whose description doesn't match." self.filter = st self.replot() def mouseoff(self, event): "Code for mousing off a data point." # The tooptip rectangle and all its sub-objects need to be destroyed. map(self.c.delete, self.re) # Also, need to note that we're no longer over an oval -- that way, # Button-1 events will cause a zoom, rather than launching a web page. self.is_hovering = False def _zoom_animation(self): import time from math import tanh scale = 5 for i1 in range(-scale, scale+1): self.replot(zlfrac=0.5 + 0.5*tanh(i1*2.0/scale)/tanh(2.0)) self.c.update() def zoom(self, event): # Only zoom in if we're actually within the graph boundaries. if event.x <= self.x_grid[0] or event.x > self.x_grid[-1]: return if event.y >= self.y_grid[0] or event.y < self.y_grid[-1]: return # Don't zoom if we're hovering over a data point: let the web browser # event handler operate. if self.is_hovering: return # Don't zoom in more than twice. if self.zoom_level >= 2: return # Find the grid square which we're inside. for i1 in range(len(self.x_grid) - 1): if event.x <= self.x_grid[i1 + 1]: xgrid = i1 + 1 break for i1 in range(len(self.y_grid) - 1): if event.y >= self.y_grid[i1 + 1]: ygrid = i1 + 1 break self.zoom_level += 1 zl = self.zoom_level # Make the limits of the new graph be those of the grid square which # was clicked inside. self.km[zl] = (self.xtick[xgrid-1], self.xtick[xgrid]) self.price[zl] = (self.ytick[ygrid-1], self.ytick[ygrid]) if zl == 1: self.zoom_price_start = self.u.axis(*self.price[0])[:2] self.zoom_km_start = self.u.axis(*self.km[0])[:2] else: self.zoom_price_start = self.price[zl - 1] self.zoom_km_start = self.km[zl - 1] self.zoom_price_end = self.price[zl] self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def unzoom(self, event): # If already at maximum zoom, nothing to be done. if self.zoom_level == 0: return # If not clicking inside graph boundaries, don't unzoom. if event.x <= self.x_grid[0] or event.x > self.x_grid[-1]: return if event.y >= self.y_grid[0] or event.y < self.y_grid[-1]: return self.zoom_level -= 1 zl = self.zoom_level self.zoom_price_start = self.price[zl + 1] self.zoom_km_start = self.km[zl + 1] if zl == 0: self.zoom_price_end = self.u.axis(*self.price[0])[:2] self.zoom_km_end = self.u.axis(*self.km[0])[:2] else: self.zoom_price_end = self.price[zl] self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def left_key(self, event): zl = self.zoom_level if zl == 0: return # If at left edge already, don't scroll. kz = self.km[zl] if self.km[0][0] > kz[0]: return self.zoom_price_start = self.zoom_price_end = self.price[zl] self.zoom_km_start = kz self.km[zl] = (kz[0] - (kz[1] - kz[0]), kz[0]) self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def right_key(self, event): zl = self.zoom_level if zl == 0: return # If at right edge already, don't scroll. kz = self.km[zl] if self.km[0][1] < kz[1]: return self.zoom_price_start = self.zoom_price_end = self.price[zl] self.zoom_km_start = kz self.km[zl] = (kz[1], kz[1] + (kz[1] - kz[0])) self.zoom_km_end = self.km[zl] self._zoom_animation() self.replot() def down_key(self, event): zl = self.zoom_level if zl == 0: return # If at bottom edge already, don't scroll. pz = self.price[zl] if self.price[0][0] > pz[0]: return self.zoom_km_start = self.zoom_km_end = self.km[zl] self.zoom_price_start = pz self.price[zl] = (pz[0] - (pz[1] - pz[0]), pz[0]) self.zoom_price_end = self.price[zl] self._zoom_animation() self.replot() def up_key(self, event): zl = self.zoom_level if zl == 0: return # If at top edge already, don't scroll. pz = self.price[zl] if self.price[0][1] < pz[1]: return self.zoom_km_start = self.zoom_km_end = self.km[zl] self.zoom_price_start = pz self.price[zl] = (pz[1], pz[1] + (pz[1] - pz[0])) self.zoom_price_end = self.price[zl] self._zoom_animation() self.replot() def select(self, event): "Open a web page, when a data point has been clicked on." oval = event.widget.find_closest(event.x, event.y)[0] # XXX As above, sometimes the closest widget is a grid line, not an # oval. Need to handle this correctly, eventually. if oval not in self.ov_dict: return ind, xp, yp, color, filtered = self.ov_dict[oval] webbrowser.open(self.u.all_alink[ind])
class Application(Frame, object): """The application main class.""" WIDTH, HEIGHT = 1280, 720 BG = 'white' FONT = 'Verdana' FILE_OPEN_OPTIONS = { 'mode': 'rb', 'title': 'Choose *.json file', 'defaultextension': '.json', 'filetypes': [('JSON file', '*.json')] } DEFAULTS = 'default_settings.yaml' def __init__(self, master=None): """Creates application main window with sizes self.WIDTH and self.HEIGHT. :param master: instance - Tkinter.Tk instance """ super(Application, self).__init__(master) self.master.title('Engine Game') self.master.geometry('{}x{}'.format(self.WIDTH, self.HEIGHT)) self.master.protocol('WM_DELETE_WINDOW', self.exit) self.source = None self._map = None self.points = None self.lines = None self.captured_point = None self.x0 = None self.y0 = None self.scale_x = None self.scale_y = None self.font_size = None self.coordinates = {} self.captured_lines = {} self.canvas_obj = AttrDict() self.icons = { 0: PhotoImage(file=join('icons', 'player_city.png')), 1: PhotoImage(file=join('icons', 'city.png')), 2: PhotoImage(file=join('icons', 'market.png')), 3: PhotoImage(file=join('icons', 'store.png')), 4: PhotoImage(file=join('icons', 'point.png')), 5: PhotoImage(file=join('icons', 'player_train.png')), 6: PhotoImage(file=join('icons', 'train.png')), 7: PhotoImage(file=join('icons', 'crashed_train.png')), 8: PhotoImage(file=join('icons', 'collision.png')), 9: PhotoImage(file=join('icons', 'play.png')), 10: PhotoImage(file=join('icons', 'play_pressed.png')), 11: PhotoImage(file=join('icons', 'stop.png')), 12: PhotoImage(file=join('icons', 'stop_pressed.png')) } self.queue_requests = { 0: self.set_status_bar, 1: self.set_player_idx, 2: self.build_map, 3: self.refresh_map, 4: self.set_available_games, 99: self.bot_control } self.settings_window = None if exists(expanduser(self.DEFAULTS)): with open(expanduser(self.DEFAULTS), 'r') as cfg: defaults = DefaultsDict.from_yaml(cfg) self.host = None if not defaults.host else str(defaults.host) self.port = None if not defaults.port else int(defaults.port) self.timeout = None if not defaults.timeout else int(defaults.timeout) self.username = None if not defaults.username else str(defaults.username) self.password = None if not defaults.password else str(defaults.password) else: self.host, self.port, self.timeout, self.username, self.password = None, None, None, None, None self.player_idx = None self.posts = {} self.trains = {} self.select_game_window = False self.available_games = None self.game = None self.num_players = None self.num_turns = None self.bot = Bot() self.bot_thread = None self.menu = Menu(self) filemenu = Menu(self.menu) filemenu.add_command(label='Open file', command=self.file_open) filemenu.add_command(label='Server settings', command=self.open_server_settings) filemenu.add_command(label='Select game', command=self.select_game) filemenu.add_command(label='Exit', command=self.exit) self.menu.add_cascade(label='Menu', menu=filemenu) master.config(menu=self.menu) self._status_bar = StringVar() self.label = Label(master, textvariable=self._status_bar) self.label.pack() self.frame = Frame(self) self.frame.bind('<Configure>', self._resize_frame) self.canvas = Canvas(self.frame, bg=self.BG, scrollregion=(0, 0, self.winfo_width(), self.winfo_height())) self.canvas.bind('<Button-1>', self._capture_point) self.canvas.bind('<Motion>', self._move_point) self.canvas.bind('<B1-ButtonRelease>', self._release_point) self.canvas.bind('<Configure>', self._resize_canvas) hbar = Scrollbar(self.frame, orient=HORIZONTAL) hbar.pack(side=BOTTOM, fill=X) hbar.config(command=self.canvas.xview) vbar = Scrollbar(self.frame, orient=VERTICAL) vbar.pack(side=RIGHT, fill=Y) vbar.config(command=self.canvas.yview) self.canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set) self.canvas.pack(fill=BOTH, expand=True) self.play = Label(self.canvas, bg='white') self.play.configure(image=self.icons[9]) self.play.bind('<Button-1>', self._play_press) self.play.bind('<B1-ButtonRelease>', self._play_release) self.stop = Label(self.canvas, bg='white') self.stop.configure(image=self.icons[11]) self.stop.bind('<Button-1>', self._stop_press) self.stop.bind('<B1-ButtonRelease>', self._stop_release) self.frame.pack(fill=BOTH, expand=True) self.weighted = IntVar(value=1) self.weighted_check = Checkbutton(self, text='Proportionally to length', variable=self.weighted, command=self._proportionally) self.weighted_check.pack(side=LEFT) self.show_weight = IntVar() self.show_weight_check = Checkbutton(self, text='Show length', variable=self.show_weight, command=self.show_weights) self.show_weight_check.pack(side=LEFT) self.pack(fill=BOTH, expand=True) self.requests_executor() self.get_available_games() self.set_status_bar('Click Play to start the game') self.play.place(rely=0.5, relx=0.5, anchor=CENTER) @property def map(self): """Returns the actual map.""" return self._map @map.setter def map(self, value): """Clears previously drawn map and assigns a new map to self._map.""" self.clear_map() self.canvas.configure(scrollregion=(0, 0, self.canvas.winfo_width(), self.canvas.winfo_height())) self.x0, self.y0 = self.canvas.winfo_width() / 2, self.canvas.winfo_height() / 2 self._map = value @staticmethod def midpoint(x_start, y_start, x_end, y_end): """Calculates a midpoint coordinates between two points. :param x_start: int - x coordinate of the start point :param y_start: int - y coordinate of the start point :param x_end: int - x coordinate of the end point :param y_end: int - y coordinate of the end point :return: 2-tuple of a midpoint coordinates """ return (x_start + x_end) / 2, (y_start + y_end) / 2 def _resize_frame(self, event): """Calculates new font size each time frame size changes. :param event: Tkinter.Event - Tkinter.Event instance for Configure event :return: None """ self.font_size = int(0.0125 * min(event.width, event.height)) def _resize_canvas(self, event): """Redraws map each time Canvas size changes. Scales map each time visible part of Canvas is enlarged. :param event: Tkinter.Event - Tkinter.Event instance for Configure event :return: None """ if self.map: k = min(float(event.width) / float(self.x0 * 2), float(event.height) / float(self.y0 * 2)) self.scale_x, self.scale_y = self.scale_x * k, self.scale_y * k self.x0, self.y0 = self.x0 * k, self.y0 * k self.redraw_map() self.redraw_trains() x_start, y_start, x_end, y_end = self.canvas.bbox('all') x_start = 0 if x_start > 0 else x_start y_start = 0 if y_start > 0 else y_start self.canvas.configure(scrollregion=(x_start, y_start, x_end, y_end)) def _proportionally(self): """Rebuilds map and redraws trains.""" self.build_map() self.redraw_trains() def _capture_point(self, event): """Stores captured point and it's lines. :param event: Tkinter.Event - Tkinter.Event instance for ButtonPress event :return: None """ x, y = self.canvas.canvasx(event.x), self.canvas.canvasy(event.y) obj_ids = self.canvas.find_overlapping(x - 5, y - 5, x + 5, y + 5) if not obj_ids: return for obj_id in obj_ids: if obj_id in self.canvas_obj.point.keys(): self.captured_point = obj_id point_idx = self.canvas_obj.point[obj_id]['idx'] self.captured_lines = {} for line_id, attr in self.canvas_obj.line.items(): if attr['start_point'] == point_idx: self.captured_lines[line_id] = 'start_point' if attr['end_point'] == point_idx: self.captured_lines[line_id] = 'end_point' if self.weighted.get(): self.weighted.set(0) def _release_point(self, event): """Writes new coordinates for a moved point and resets self.captured_point and self.captured_lines. :param event: Tkinter.Event - Tkinter.Event instance for ButtonRelease event :return: None """ if self.captured_point: idx = self.canvas_obj.point[self.captured_point]['idx'] x, y = self.canvas.canvasx(event.x), self.canvas.canvasy(event.y) self.coordinates[idx] = (x, y) self.points[idx]['x'], self.points[idx]['y'] = (x - self.x0) / self.scale_x, (y - self.y0) / self.scale_y self.captured_point = None self.captured_lines = {} def _move_point(self, event): """Moves point and its lines. Moves weights if self.show_weight is set to 1. In case some point is moved beyond Canvas border Canvas scrollregion is resized correspondingly. :param event: Tkinter.Event - Tkinter.Event instance for Motion event :return: None """ if self.captured_point: new_x, new_y = self.canvas.canvasx(event.x), self.canvas.canvasy(event.y) self.canvas.coords(self.captured_point, new_x, new_y) indent_y = self.icons[self.canvas_obj.point[self.captured_point]['icon']].height() / 2 + self.font_size if self.canvas_obj.point[self.captured_point]['text_obj']: self.canvas.coords(self.canvas_obj.point[self.captured_point]['text_obj'], new_x, new_y - indent_y) self.coordinates[self.canvas_obj.point[self.captured_point]['idx']] = (new_x, new_y) self.canvas.configure(scrollregion=self.canvas.bbox('all')) for line_id, attr in self.captured_lines.items(): line_attrs = self.canvas_obj.line[line_id] if attr == 'start_point': x, y = self.coordinates[line_attrs['end_point']] self.canvas.coords(line_id, new_x, new_y, x, y) else: x, y = self.coordinates[line_attrs['start_point']] self.canvas.coords(line_id, x, y, new_x, new_y) if self.show_weight.get(): mid_x, mid_y = self.midpoint(new_x, new_y, x, y) self.canvas.coords(line_attrs['weight_obj'][1], mid_x, mid_y) r = self.font_size * len(str(line_attrs['weight'])) self.canvas.coords(line_attrs['weight_obj'][0], mid_x - r, mid_y - r, mid_x + r, mid_y + r) self.redraw_trains() def _play_press(self, _): """Draws play button pressed icon.""" self.play.configure(image=self.icons[10]) def _play_release(self, _): """Draws play button icon and calls bot_control method.""" self.play.configure(image=self.icons[9]) self.bot_control() def _stop_press(self, _): """Draws stop button pressed icon.""" self.stop.configure(image=self.icons[12]) def _stop_release(self, _): """Draws stop buton icon and calls bot_control method.""" self.stop.configure(image=self.icons[11]) self.bot_control() def set_player_idx(self, value): """Sets a player idx value.""" self.player_idx = value def file_open(self): """Opens file dialog and builds and draws a map once a file is chosen. Stops bot if its started.""" path = tkFileDialog.askopenfile(parent=self.master, **self.FILE_OPEN_OPTIONS) if path: if self.bot_thread: self.bot_control() self.posts, self.trains = {}, {} self.source = path.name self.weighted_check.configure(state=NORMAL) self.build_map() def open_server_settings(self): """Opens server settings window.""" ServerSettings(self, title='Server settings') def select_game(self): """Opens select game window.""" self.select_game_window = True SelectGame(self, title='Select game') self.select_game_window = False self.set_status_bar('Click Play to start the game') def exit(self): """Closes application and stops bot if its started.""" if self.bot_thread: self.bot_control() self.master.destroy() def bot_control(self): """Starts bot for playing the game or stops it if it is started.""" if not self.bot_thread: self.bot_thread = Thread(target=self.bot.start, kwargs={ 'host': self.host, 'port': self.port, 'time_out': self.timeout, 'username': self.username, 'password': self.password, 'game': self.game, 'num_players': self.num_players, 'num_turns': self.num_turns}) self.bot_thread.start() else: self.bot.stop() self.bot_thread.join() self.bot_thread = None def get_available_games(self): """Requests a list of available games.""" if self.select_game_window: self.bot.get_available_games(host=self.host, port=self.port, time_out=self.timeout) self.after(1000, self.get_available_games) def set_available_games(self, games): """Sets new value for available games list.""" self.available_games = games def set_status_bar(self, value): """Assigns new status bar value and updates it. :param value: string - status bar string value :return: None """ self._status_bar.set(value) self.label.update() def build_map(self, source=None): """Builds and draws new map. :param source: string - source string; could be JSON string or path to *.json file. :return: None """ if source: self.source = source if self.source: self.map = Graph(self.source, weighted=self.weighted.get()) self.set_status_bar('Map title: {}'.format(self.map.name)) self.points, self.lines = self.map.get_coordinates() self.draw_map() def draw_map(self): """Draws map by prepared coordinates.""" self.draw_lines() self.draw_points() def clear_map(self): """Clears previously drawn map and resets coordinates and scales.""" self.canvas.delete('all') self.scale_x, self.scale_y = None, None self.coordinates = {} def redraw_map(self): """Redraws existing map by existing coordinates.""" if self.map: self.coordinates = {} for obj_id in self.canvas_obj.line: self.canvas.delete(obj_id) self.draw_lines() self.redraw_points() def redraw_points(self): """Redraws map points by existing coordinates.""" if self.map: for obj_id, attrs in self.canvas_obj.point.items(): if attrs['text_obj']: self.canvas.delete(attrs['text_obj']) self.canvas.delete(obj_id) self.draw_points() def redraw_trains(self): """Redraws existing trains.""" if self.trains and hasattr(self.canvas_obj, 'train'): for obj_id, attrs in self.canvas_obj.train.items(): self.canvas.delete(attrs['text_obj']) self.canvas.delete(obj_id) self.draw_trains() @prepare_coordinates def draw_points(self): """Draws map points by prepared coordinates.""" point_objs = {} captured_point_idx = self.canvas_obj.point[self.captured_point]['idx'] if self.captured_point else None for idx in self.points.keys(): x, y = self.coordinates[idx] if self.posts and idx in self.posts.keys(): post_type = self.posts[idx]['type'] if post_type == 1: status = '{}/{} {}/{} {}/{}'.format(self.posts[idx]['population'], self.posts[idx]['population_capacity'], self.posts[idx]['product'], self.posts[idx]['product_capacity'], self.posts[idx]['armor'], self.posts[idx]['armor_capacity']) elif post_type == 2: status = '{}/{}'.format(self.posts[idx]['product'], self.posts[idx]['product_capacity']) else: status = '{}/{}'.format(self.posts[idx]['armor'], self.posts[idx]['armor_capacity']) image_id = 0 if post_type == 1 and self.posts[idx]['player_idx'] == self.player_idx else post_type point_id = self.canvas.create_image(x, y, image=self.icons[image_id]) y -= (self.icons[post_type].height() / 2) + self.font_size text_id = self.canvas.create_text(x, y, text=status, font="{} {}".format(self.FONT, self.font_size)) else: post_type = 4 point_id = self.canvas.create_image(x, y, image=self.icons[post_type]) text_id = None point_objs[point_id] = {'idx': idx, 'text_obj': text_id, 'icon': post_type} self.captured_point = point_id if idx == captured_point_idx else self.captured_point self.canvas_obj['point'] = point_objs @prepare_coordinates def draw_lines(self): """Draws map lines by prepared coordinates and shows their weights if self.show_weight is set to 1.""" line_objs, captured_lines_idx = {}, {} if self.captured_lines: for line_id in self.captured_lines.keys(): captured_lines_idx[self.canvas_obj.line[line_id]['idx']] = line_id for idx, attrs in self.lines.items(): x_start, y_start = self.coordinates[attrs['start_point']] x_stop, y_stop = self.coordinates[attrs['end_point']] line_id = self.canvas.create_line(x_start, y_start, x_stop, y_stop) line_objs[line_id] = {'idx': idx, 'weight': attrs['weight'], 'start_point': attrs['start_point'], 'end_point': attrs['end_point'], 'weight_obj': ()} if idx in captured_lines_idx.keys(): self.captured_lines[line_id] = self.captured_lines.pop(captured_lines_idx[idx]) self.canvas_obj['line'] = line_objs self.show_weights() @prepare_coordinates def draw_trains(self): """Draws trains by prepared coordinates.""" trains = {} for train in self.trains.values(): start_point = self.lines[train['line_idx']]['start_point'] end_point = self.lines[train['line_idx']]['end_point'] weight = self.lines[train['line_idx']]['weight'] position = train['position'] x_start, y_start = self.coordinates[start_point] x_end, y_end = self.coordinates[end_point] delta_x, delta_y = int((x_start - x_end) / weight) * position, int((y_start - y_end) / weight) * position x, y = x_start - delta_x, y_start - delta_y if train['cooldown'] > 0: icon = 7 status = None else: icon = 5 if train['player_idx'] == self.player_idx else 6 status = '{}/{}'.format(train['goods'], train['goods_capacity']) indent_y = self.icons[icon].height() / 2 train_id = self.canvas.create_image(x, y - indent_y, image=self.icons[icon]) text_id = self.canvas.create_text(x, y - (2 * indent_y + self.font_size), text=status, font="{} {}".format(self.FONT, self.font_size)) if status else None trains[train_id] = {'icon': icon, 'text_obj': text_id} self.canvas_obj['train'] = trains def show_weights(self): """Shows line weights when self.show_weight is set to 1 and hides them when it is set to 0.""" if not self.canvas_obj: return if self.show_weight.get(): for line in self.canvas_obj.line.values(): if line['weight_obj']: for obj in line['weight_obj']: self.canvas.itemconfigure(obj, state='normal') else: x_start, y_start = self.coordinates[line['start_point']] x_end, y_end = self.coordinates[line['end_point']] x, y = self.midpoint(x_start, y_start, x_end, y_end) value = line['weight'] size = self.font_size r = int(size) * len(str(value)) oval_id = self.canvas.create_oval(x - r, y - r, x + r, y + r, fill=self.BG, width=0) text_id = self.canvas.create_text(x, y, text=value, font="{} {}".format(self.FONT, str(size))) line['weight_obj'] = (oval_id, text_id) else: for line in self.canvas_obj.line.values(): if line['weight_obj']: for obj in line['weight_obj']: self.canvas.itemconfigure(obj, state='hidden') def requests_executor(self): """Dequeues and executes requests. Assigns corresponding label to bot control button.""" if not self.bot.queue.empty(): request_type, request_body = self.bot.queue.get_nowait() if request_type == 99 and request_body: self.open_server_settings() request_body = None if request_body is not None: self.queue_requests[request_type](request_body) else: self.queue_requests[request_type]() if self.bot_thread and self.bot_thread.is_alive(): if self.play.place_info(): self.play.place_forget() self.stop.place(rely=0.99, relx=0.995, anchor=SE) else: if self.stop.place_info(): self.stop.place_forget() self.play.place(rely=0.5, relx=0.5, anchor=CENTER) self.after(50, self.requests_executor) def refresh_map(self, dynamic_objects): """Refreshes map with passed dynamic objects. :param dynamic_objects: dict - dict of dynamic objects :return: None """ for post in dynamic_objects['posts']: self.posts[post['point_idx']] = post for train in dynamic_objects['trains']: self.trains[train['idx']] = train self.redraw_points() self.redraw_trains()
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