import tkinter as tk import argparse gcode_file_path = " " bedsizex = 0 bedsizey = 0 scale_factor = 1.0 x_offset = 48.0 y_offset = 48.0 laser_on = False last_position = {"x": 0.0, "y": 0.0} global canvas debug = True def parse_arguments(): global gcode_file_path global bedsizex global bedsizey parser = argparse.ArgumentParser(description='Simulate gcode for laser plotter.') parser.add_argument("-i", "--input", dest='inputfile', metavar='data.gcode', help="path to gcode file", required=True) parser.add_argument("-bx", "--bedsizex", dest='bedsizex', default="376", help="x size of bed in mm", required=False) parser.add_argument("-by", "--bedsizey", dest='bedsizey', default="315", help="y size of bed in mm", required=False) args = parser.parse_args() gcode_file_path = args.inputfile bedsizex = int(args.bedsizex) bedsizey = int(args.bedsizey) def plot_paths(canvas): gcode_file = open(gcode_file_path, "r") for line in gcode_file.readlines(): if(not line.startswith(';')): #filter comments #print(line) if(line.startswith('M5')): if(debug): print("[decoder] laser off") laser_on = False if(line.startswith('M3')): if(debug): print("[decoder] laser on") laser_on = True if(line.startswith('G1')): x = float(line[(int(line.find('X'))+1):(int(line.find('Y')-1))]) * (scale_factor*1) + x_offset y = (bedsizey * scale_factor-y_offset) - (float(line[(int(line.find('Y'))+1):(int(line.find(';')-1))])* (scale_factor*1)) if(debug): print("[decoder] movement to " + str(x) + " " + str(y)) if(laser_on == True): canvas.create_line(last_position["x"], last_position["y"], x, y, width=5, fill='red') else: canvas.create_line(last_position["x"], last_position["y"], x, y, width=3, fill='green') last_position["x"] = x last_position["y"] = y class Example(tk.Frame): def __init__(self, root): tk.Frame.__init__(self, root) self.canvas = tk.Canvas(self, width=400, height=400, background="bisque") self.xsb = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview) self.ysb = tk.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,1000,1000)) self.master.title("gcode simulator") 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) actual_bedsize_x = bedsizex * scale_factor actual_bedsize_y = bedsizey * scale_factor self.canvas.create_line(x_offset, y_offset, x_offset, (actual_bedsize_y-y_offset), width=2, fill='black') self.canvas.create_line(actual_bedsize_x-x_offset, y_offset, actual_bedsize_x-x_offset, (actual_bedsize_y-y_offset), width=2, fill='black') self.canvas.create_line(x_offset, y_offset, actual_bedsize_x-x_offset, y_offset, width=2, fill='black') self.canvas.create_line(x_offset, (actual_bedsize_y-y_offset), actual_bedsize_x-x_offset, (actual_bedsize_y-y_offset), width=2, fill='black') plot_paths(self.canvas) # This is what enables using the mouse: self.canvas.bind("", self.move_start) self.canvas.bind("", self.move_move) #linux scroll self.canvas.bind("", self.zoomerP) self.canvas.bind("", self.zoomerM) #windows scroll self.canvas.bind("",self.zoomer) #move def move_start(self, event): self.canvas.scan_mark(event.x, event.y) def move_move(self, event): self.canvas.scan_dragto(event.x, event.y, gain=1) #windows zoom def zoomer(self,event): if (event.delta > 0): self.canvas.scale("all", event.x, event.y, 1.1, 1.1) elif (event.delta < 0): self.canvas.scale("all", event.x, event.y, 0.9, 0.9) 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")) if __name__ == "__main__": parse_arguments() if(bedsizex < bedsizey): scale_factor = float(720/bedsizey)*0.8 else: scale_factor = float(1280/bedsizex)*0.8 print("scale factor: " + str(scale_factor)) last_position = {"x": x_offset, "y": bedsizey * scale_factor-y_offset} #set to initial start at home pos root = tk.Tk() Example(root).pack(fill="both", expand=True) root.geometry(str(int(bedsizex*scale_factor+x_offset))+"x"+str(int(bedsizey*scale_factor+y_offset))+"+300+300") root.mainloop()