class Application(tk.Tk): """A window for users to recreate their picture with nails and threads. Steps to re-weave are proposed, so that the picture will be recreated. The computation is done in an extra thread. The steps can be saved/loaded in a companioning .json file to the picture.""" def __init__(self): tk.Tk.__init__(self) self.init_values() self.create_widgets() self.create_daemon() def create_daemon(self): self.weave_daemon = crunch_pic.weave_thread(self, "") self.weave_daemon.setDaemon(True) def start_daemon(self): self.weave_daemon.json_file = self.json_file if self.weave_daemon.is_alive(): raise Exception("Daemon is still alive!") self.weave_daemon.join() self.weave_daemon.restart() else: self.weave_daemon.start() def on_closing(self): if self.weave_daemon.is_alive(): self.weave_daemon.save_now() time.sleep(0.1) else: logging.debug("No weave daemon found!") self.destroy() def init_values(self): """Some values are loaded. Some for an initial .json-creation.""" #values of the menu itself self.protocol("WM_DELETE_WINDOW", self.on_closing) style = ttk.Style(self) style.theme_use('clam') self.default_font = tkFont.nametofont("TkDefaultFont") self.default_font.configure(size=11) self.option_add("*Font", self.default_font) self.main_color = self.cget('bg') self.red = "#BB2222" self.halfred = str(rgb.halfway(self.main_color, self.red)) self.quarred = str(rgb.halfway(self.main_color, self.halfred)) self.green = "#22BB22" self.halfgreen = str(rgb.halfway(self.main_color, self.green)) self.quargreen = str(rgb.halfway(self.main_color, self.halfgreen)) self.x_padding = 5 self.y_padding = 5 self.button_padding = 10 self.mark = tk.IntVar() self.mark.set(1) self.resizable(0, 0) #standard values of the picture and the weaving self.nailsx = 100 self.nailsy = 100 self.steps_done = 0 self.two_sided_nail = True self.color_scheme = "bw" self.steps = [] self.current_step = -1 def open_file(self): """ The File open menu has been clicked. The user gets to choose a existing project (a .json) which they can view or compute new steps in. Otherwise the user choses a .jpg and the .json will be created from scratch, after a prompt asking for some parameters. """ self.file = file_dialog.askopenfilename( title='Choose picture to weave or finished weaving.json', filetypes=[("JSON", "*.json"), ("JSON", "*.JSON"), ("JPG", "*.JPG"), ("JPG", "*.jpeg"), ("JPG", "*.jpg")], initialdir="weaves/example") if self.file: if self.file.partition(".")[2].lower() == "json": self.load(self.file) return elif self.file.partition(".")[2].lower() in ["jpeg", "jpg"]: self.picture_file = self.file new_picture_window.Config_Dialog(self, self.picture_file, self.nailsx, self.nailsy) return raise Exception("File type not recognized:", self.file.partition(".")[2].lower(), "of file", self.file) def load(self, json_file): #if thread is running dump it into (old) .json_file and exit it #read (new) .json_file #load the two canvasses #update table content self.current_step = -1 self.tframe.destroy() self.place_table() self.json_file = json_file (self.nailsx, self.nailsy, self.steps_done, self.two_sided_nail, self.color_scheme, self.steps, self.picture_file) = json_read_write.read_json(json_file) self.start_daemon() self.reload_table(0) self.table.setSelectedRow(-1) display.load([(0, self.canvas_pic), (1, self.canvas_pos)], self.picture_file, self.nailsx, self.nailsy) for button in [ self.start_button, self.back_button, self.play_button, self.end_button ]: button.config(state=tk.ACTIVE) def reload_table(self, already_loaded=-1): while self.steps and type(self.steps[0]) == type([]): if not self.steps: return time.sleep(0.01) if already_loaded < 0: already_loaded = len(self.steps) for e, row in enumerate(self.steps[already_loaded:]): self.add_row_to_table(e, row) self.table.adjustColumnWidths() self.table.autoResizeColumns() self.table.redrawVisible() def add_row_to_table(self, e, row): r = self.table.addRow(key="Step " + str(e + 1)) nail1, nail2 = row self.table.model.setValueAt(str(nail1.number), e, 0) self.table.model.setValueAt(nail1.direction, e, 1) self.table.model.setValueAt(str(nail2.number), e, 2) self.table.model.setValueAt(nail2.direction.lower(), e, 3) def new_row(self, e, row): self.add_row_to_table(e, row) self.mark_current_row() def back_to_start(self): """User pressed back_to_start-button, and displays are reset.""" if self.current_step >= 0: display.delete_lines(range(self.current_step + 1)) self.current_step = -1 self.mark_current() def back_one_step(self): """User pressed back-button, and displays are reset and played back till one step before the current.""" if self.current_step >= 0: display.delete_lines([self.current_step]) self.current_step -= 1 self.mark_current() def play_one_step(self): """User pressed forward-button, and displays are updated with the next step.""" if self.current_step + 1 < len(self.steps): self.current_step += 1 display.draw_lines([(self.current_step, self.steps[self.current_step])]) self.mark_current() def play_to_end(self): """User pressed back-to-end-button, and displays are updated with the last step.""" if self.current_step + 1 < len(self.steps): display.draw_lines([ (k, self.steps[k]) for k in range(self.current_step + 1, len(self.steps)) ]) self.current_step = len(self.steps) - 1 self.mark_current() def mark_current_row(self): """Update the table with the current row, jump to it and highlight it. If no step has been perfomed no row will be highlighted.""" self.table.set_yviews( 'moveto', max(0, float(self.current_step) / (len(self.steps) + 0.5))) if self.current_step >= 0: self.table.setSelectedRow(self.current_step) else: self.table.setSelectedRow(-1) self.table.redrawVisible() def mark_current(self): """The row of the current step will be highlighted and shown in the table. If the user wants fat lines for the current step, they will be drawn onto the canvas in fat and red.""" self.mark_current_row() if self.mark.get() and self.current_step >= 0: display.draw_lines( [(self.current_step, self.steps[self.current_step])], True) else: display.remove_marking() def place_buttons(self): """The play, back, to_end, to_start buttons are placed in the bottom.""" self.button_frame = ttk.Frame(self) self.button_frame.grid(column=0, row=3, columnspan=2, padx=self.x_padding, pady=self.y_padding, sticky=tk.S) self.start_photo, self.back_photo, self.play_photo, self.end_photo = display.create_photos( ) self.start_button = ttk.Button(self.button_frame, command=self.back_to_start, image=self.start_photo, state=tk.DISABLED) self.start_button.grid(column=0, row=0, padx=self.button_padding) self.back_button = ttk.Button(self.button_frame, command=self.back_one_step, image=self.back_photo, state=tk.DISABLED) self.back_button.grid(column=1, row=0, padx=self.button_padding) self.play_button = ttk.Button(self.button_frame, command=self.play_one_step, image=self.play_photo, state=tk.DISABLED) self.play_button.grid(column=2, row=0, padx=self.button_padding) self.end_button = ttk.Button(self.button_frame, command=self.play_to_end, image=self.end_photo, state=tk.DISABLED) self.end_button.grid(column=3, row=0, padx=self.button_padding) def place_canvasses(self): """ The three canvasses are placed. The left (canvas_pic) is for the original photo. The right (canvopen_fileas_pos) is a view, of what the user should recreate themselves. """ self.canvas_pic = tk.Canvas(self, bg="white", height=200, width=200) self.canvas_pic.grid(column=0, row=1, padx=self.x_padding, pady=self.y_padding) self.canvas_pos = tk.Canvas(self, bg="white", height=200, width=200) self.canvas_pos.grid(column=1, row=1, padx=self.x_padding, pady=self.y_padding) def place_table(self): """The table in the bottom describing the steps and their order.""" self.tframe = ttk.Frame(self, width=460, height=130) self.tframe.grid(column=0, row=2, columnspan=2, padx=self.x_padding, pady=self.y_padding) self.tframe.grid_propagate(0) self.table = TableCanvas(self.tframe, rows=0, cols=0, read_only=True, rowselectedcolor=self.quarred, editable=False) self.table.show() self.table.addColumn(newname="From") self.table.addColumn(newname="NESW") self.table.addColumn(newname="to") self.table.addColumn(newname="nesw") def about(self): """The about window, that pops up, in the help context.""" self.about_window = tk.Toplevel(self) self.about_window.title("About") self.about_window.resizable(0, 0) self.about_window.geometry("250x170") self.about_frame = ttk.Frame(master=self.about_window) self.about_frame.pack_propagate(0) self.about_frame.pack(fill=tk.BOTH, expand=1) ttk.Label(self.about_frame, font=tkFont.Font(size=10, weight='bold'), width=240, wraplength=240, text="Copyright 2018 Alexander Boll", justify=tk.LEFT).pack(padx=5, pady=2) ttk.Label( self.about_frame, font=tkFont.Font(size=10), width=240, wraplength=240, text= "This program can instruct you, how to weave a photo, with a couple of nails and a thread.\n\nYou can use and modify it for free, under the MIT license.", justify=tk.LEFT).pack(padx=5, pady=2) ttk.Button(self.about_frame, text="Ok", width=10, command=self.about_window.destroy).pack(pady=8) self.about_window.transient(self) self.about_window.grab_set() def place_menu(self): """The menu bar.""" self.menubar = tk.Menu(self) self.config(menu=self.menubar) self.file_menu = tk.Menu(self.menubar, tearoff=0) self.file_menu.add_command(label="Open file", command=self.open_file, font=self.default_font) self.file_menu.add_command(label="Start/continue weaving", command=self.create_daemon, background=self.quargreen, activebackground=self.halfgreen, state=tk.DISABLED, font=self.default_font) self.file_menu.add_command(label="Reload .json file", command=self.reload_table, state=tk.DISABLED, font=self.default_font) self.file_menu.add_command(label="Quit", command=self.quit, background=self.quarred, activebackground=self.halfred, font=self.default_font) self.menubar.add_cascade(label="File", menu=self.file_menu) self.view_menu = tk.Menu(self.menubar, tearoff=0) self.view_menu.add_checkbutton(label="Mark last move(s)", variable=self.mark, command=self.mark_current) self.menubar.add_cascade(label="View", menu=self.view_menu) self.help_menu = tk.Menu(self.menubar, tearoff=0) self.help_menu.add_command(label="About", command=self.about) self.menubar.add_cascade(label="Help", menu=self.help_menu) def create_widgets(self): """The main parts of the app are created and placed on the grid of the window.""" self.place_canvasses() self.place_table() self.place_buttons() self.place_menu()
def analyse(self): # verify input arguments if self.script_path.get() == '': print( 'Parameter error, please select the folder of source script to be converted.' ) return # generate command support_list = "tf1.15_api_support_list.xlsx" if self.main_file.get() == '': if self.output_path.get() == '' and self.report_path.get() == '': call_main_py = 'python main.py -i {} -l {}'.format( '\"' + self.script_path.get() + '\"', support_list) elif self.output_path.get() == '': call_main_py = 'python main.py -i {} -l {} -r {}'.format( '\"' + self.script_path.get() + '\"', support_list, '\"' + self.report_path.get() + '\"') elif self.report_path.get() == '': call_main_py = 'python main.py -i {} -l {} -o {}'.format( '\"' + self.script_path.get() + '\"', support_list, '\"' + self.output_path.get() + '\"') else: call_main_py = 'python main.py -i {} -l {} -o {} -r {}'.format( '\"' + self.script_path.get() + '\"', support_list, '\"' + self.output_path.get() + '\"', '\"' + self.report_path.get() + '\"') else: if self.output_path.get() == '' and self.report_path.get() == '': call_main_py = 'python main.py -i {} -l {} -m {}'.format( '\"' + self.script_path.get() + '\"', support_list, '\"' + self.main_file.get() + '\"') elif self.output_path.get() == '': call_main_py = 'python main.py -i {} -l {} -r {} -m {}'.format( '\"' + self.script_path.get() + '\"', support_list, '\"' + self.report_path.get() + '\"', '\"' + self.main_file.get() + '\"') elif self.report_path.get() == '': call_main_py = 'python main.py -i {} -l {} -o {} -m {}'.format( '\"' + self.script_path.get() + '\"', support_list, '\"' + self.output_path.get() + '\"', '\"' + self.main_file.get() + '\"') else: call_main_py = 'python main.py -i {} -l {} ' \ '-o {} -r {} -m {}'.format('\"' + self.script_path.get() + '\"', support_list, '\"' + self.output_path.get() + '\"', '\"' + self.report_path.get() + '\"', '\"' + self.main_file.get() + '\"') os.system(call_main_py) self.hide() new_frame = tk.Toplevel() new_frame.title("Report") handler = lambda: self.back_to_main(new_frame) tk.Button(new_frame, text='重新开始分析', command=handler).grid(row=5, column=2, padx=10, pady=10, stick=tk.W) tk.Button(new_frame, text='退出', command=exit).grid(row=5, column=1, padx=10, pady=10, stick=tk.E) # load analysis report if self.report_path.get() == '': self.report_path.set(os.getcwd()) report_dir = self.report_path.get() lateset = [] for item in os.listdir(report_dir): if 'report_npu' in item: lateset.append(item) lateset.sort() report_path = os.path.join(report_dir, lateset[-1], 'api_analysis_report.xlsx') if not os.path.exists(report_path): print("No api analysis report generated.") return report = pd.read_excel(report_path) file_index = report['序号'].values.tolist() file_name = report['脚本文件名'].values.tolist() code_line = report['代码行'].values.tolist() code_module = report['模块名'].values.tolist() code_api = report['API名'].values.tolist() support_type = report['工具迁移API支持度'].values.tolist() migrate_advice = report['说明'].values.tolist() table = TableCanvas(new_frame) table.show() table.addColumn('6') table.addColumn('7') for i in range(len(file_name) - 10): table.addRow() for i in range(len(file_name)): table.model.setValueAt(file_index[i], i, 0) table.model.setValueAt(file_name[i], i, 1) table.model.setValueAt(code_line[i], i, 2) table.model.setValueAt(code_module[i], i, 3) table.model.setValueAt(code_api[i], i, 4) table.model.setValueAt(support_type[i], i, 5) table.model.setValueAt(migrate_advice[i], i, 6) table.model.columnlabels['1'] = '序号' table.model.columnlabels['2'] = '脚本文件名' table.model.columnlabels['3'] = '代码行' table.model.columnlabels['4'] = '模块名' table.model.columnlabels['5'] = 'API名' table.model.columnlabels['6'] = '工具迁移API支持度' table.model.columnlabels['7'] = '说明' table.show()
def analyse(self): """Initiate API analysis""" util_global._init() # verify input arguments if not self.script_path.get(): raise ValueError( "Parameter error, please select the folder of source script to be converted." ) input_dir = self.script_path.get() if str(input_dir).endswith('/'): input_dir = input_dir[:-1] input_dir = input_dir.replace('\\', '/') support_list = os.path.join(os.path.dirname(os.path.abspath(__file__)), "tf1.15_api_support_list.xlsx") output = self.get_output_dir() report = self.get_report_dir() main_file = self.get_main_file() distributed_mode = self.get_distributed_mode() if input_dir + '/' in output + '/' or input_dir + '/' in report + '/': print( "<output> or <report> could not be the subdirectory of <input>, please try another option." ) sys.exit(2) util_global.set_value('input', input_dir) util_global.set_value('list', support_list) util_global.set_value('output', output) util_global.set_value('report', report) util_global.set_value('main', main_file) util_global.set_value('distributed_mode', distributed_mode) check_input_and_output_dir(input_dir, output) init_loggers(report) conver() self.hide() new_frame = tk.Toplevel() new_frame.title("Report") handler = lambda: self.back_to_main(new_frame) tk.Button(new_frame, text='重新开始分析', command=handler).grid(row=5, column=2, padx=10, pady=10, stick=tk.W) tk.Button(new_frame, text='退出', command=exit).grid(row=5, column=1, padx=10, pady=10, stick=tk.E) # load analysis report if self.report_path.get() == '': self.report_path.set(os.getcwd()) report_dir = self.report_path.get() lateset = [] for item in os.listdir(report_dir): if 'report_npu' in item: lateset.append(item) lateset.sort() report_path = os.path.join(report_dir, lateset[-1], 'api_analysis_report.xlsx') if not os.path.exists(report_path): print("No api analysis report generated.") return report = pd.read_excel(report_path) file_index = report['序号'].values.tolist() file_name = report['脚本文件名'].values.tolist() code_line = report['代码行'].values.tolist() code_module = report['模块名'].values.tolist() code_api = report['API名'].values.tolist() support_type = report['工具迁移API支持度'].values.tolist() migrate_advice = report['说明'].values.tolist() table = TableCanvas(new_frame) table.show() table.addColumn('6') table.addColumn('7') for i in range(len(file_name) - 10): table.addRow() for i in range(len(file_name)): table.model.setValueAt(file_index[i], i, 0) table.model.setValueAt(file_name[i], i, 1) table.model.setValueAt(code_line[i], i, 2) table.model.setValueAt(code_module[i], i, 3) table.model.setValueAt(code_api[i], i, 4) table.model.setValueAt(support_type[i], i, 5) table.model.setValueAt(migrate_advice[i], i, 6) table.model.columnlabels['1'] = '序号' table.model.columnlabels['2'] = '脚本文件名' table.model.columnlabels['3'] = '代码行' table.model.columnlabels['4'] = '模块名' table.model.columnlabels['5'] = 'API名' table.model.columnlabels['6'] = '工具迁移API支持度' table.model.columnlabels['7'] = '说明' table.show()