def __init__(self, parent=None, picks=[], editButtons=False, checkCallback=None): """ Parameters ---------- :param parent: the parent window :param picks: the list of pairs to show :param editButtons: Indicator whether a configuration button should be displayed :param checkCallback: Callback for each pair """ Frame.__init__(self, parent) self.parent = parent self.vars = [] self.checks = [] self.buttons = [] relY = 0 relX = 0 enable_functionality = 'active' # Iterate over all pairs of check buttons and buttons for pick in picks: var = IntVar() algorithm_show_function = self.get_algorithm_show_function( str(pick)) # Create a check button dynamically check_button = Checkbutton( self, text=pick, variable=var, state=enable_functionality, command=lambda: self.set_button_state(checkCallback)) check_button.place(relx=relX, rely=relY, height=30, width=150) set_widget_to_left(check_button) if editButtons: # Create a configuration button dynamically edit_button = HoverButton(self, text=pick + " configuration", state='disabled', command=algorithm_show_function) edit_button.place(relx=relX + 0.35, rely=relY, height=30, width=220) edit_button.configure(cursor="hand2") self.buttons.append(edit_button) self.vars.append(var) self.checks.append(check_button) relY = relY + 0.1
class TuningLoadingWindow(tk.Frame): """ A Class used to be presented tuning model process is running in the background of the application Methods ------- reset_widgets() Description | Reset check bar values back_window() Description | Handle a click on back button stop_model_process() Description | Handle a click on stop button reinitialize() Description | Reinitialize frame values and view update_clock() Description | Updates the time on the clock loading_process() Description | Run chosen models and move to results window """ def __init__(self, parent, controller): """ Parameters ---------- :param parent: window :param controller: GUI controller """ tk.Frame.__init__(self, parent) # Page init self.controller = controller self.menubar = Menubar(controller) # Disables ability to tear menu bar into own window self.controller.option_add('*tearOff', 'FALSE') system_logo = CROSS_WINDOWS_SETTINGS.get('LOGO') photo_location = os.path.join(system_logo) global logo_img logo_img = tk.PhotoImage(file=photo_location) # Page header self.logo_png = tk.Button(self) self.logo_png.place(relx=0.28, rely=0.029, height=172, width=300) set_logo_configuration(self.logo_png, image=logo_img) self.instructions = tk.Label(self) self.instructions.place(relx=0.015, rely=0.3, height=32, width=635) self.instructions.configure(text='''Tuning parameters, please wait...''') set_widget_to_left(self.instructions) # Page body loading_gif = LOADING_WINDOW_SETTINGS.get('LOADING_GIF') delay_between_frames = LOADING_WINDOW_SETTINGS.get('DELAY_BETWEEN_FRAMES') self.title_font = Font(family='Helvetica', size=12, weight="bold") self.loading_gif = AnimatedGif(self, loading_gif, delay_between_frames) self.loading_gif.place(relx=0.1, rely=0.35, height=330, width=600) self.clock_label = tk.Label(self, text="", font=self.title_font) self.clock_label.place(relx=0.38, rely=0.7, height=32, width=150) # Page footer self.stop_button = HoverButton(self, command=self.stop_model_process) self.stop_button.place(relx=0.813, rely=0.839, height=25, width=81) set_button_configuration(self.stop_button, text='''Stop''') self.back_button = HoverButton(self, command=self.back_window) self.back_button.place(relx=0.017, rely=0.839, height=25, width=81) set_button_configuration(self.back_button, text='''Back''') self.back_button.configure(state='disabled') self.copyright = tk.Label(self) self.copyright.place(relx=0, rely=0.958, height=25, width=750) set_copyright_configuration(self.copyright) # Page logic self.loading_gif.start() def reset_widgets(self): """ Reset check bar values :return: empty values in the widgets """ pass def back_window(self): """ Handle back button click :return: previous window """ self.controller.reinitialize_frame("TuneModel") def stop_model_process(self): """ Handle stop button click :return: freeze state """ self.back_button.configure(state='active') self.stop_button.configure(state='disabled') try: self.model_process_thread.join() except Exception: pass def reinitialize(self): """ Reinitialize frame values and view :return: new frame view """ self.model_process_thread = threading.Thread(name='model_process', target=self.loading_process) self.model_process_thread.start() self.start_time = timer() self.update_clock() def update_clock(self): """ Updates the time on the clock :return: updated time """ now = timer() duration = timedelta(seconds=now - self.start_time) self.clock_label.configure(text=strfdelta(duration, '%H:%M:%S')) self.controller.after(200, self.update_clock) def loading_process(self): """ Run tuning parameters process and move to results window :return: results window """ self.controller.run_tuning() self.controller.reinitialize_frame("TuneResultsWindow")
class LoadingWindow(tk.Frame): """ A Class used to be presented while the models are running in the background of the application Methods ------- reset_widgets() Description | Reset check bar values stop_model_process() Description | Handle a click on stop button reinitialize() Description | Reinitialize frame values and view update_clock() Description | Updates the time on the clock loading_process() Description | Run chosen models and move to results window show_model_process_label(y_coordinate, algorithm): Description | Show model process label on the screen """ def __init__(self, parent, controller): """ Parameters ---------- :param parent: window :param controller: GUI controller """ tk.Frame.__init__(self, parent) # Page init self.controller = controller self.menubar = Menubar(controller) # Disables ability to tear menu bar into own window self.controller.option_add('*tearOff', 'FALSE') system_logo = CROSS_WINDOWS_SETTINGS.get('LOGO') stop_logo = LOADING_WINDOW_SETTINGS.get('STOP') photo_location = os.path.join(system_logo) stop_photo_location = os.path.join(stop_logo) global logo_img, stop_img logo_img = tk.PhotoImage(file=photo_location) stop_img = tk.PhotoImage(file=stop_photo_location) # Page header self.logo_png = tk.Button(self) self.logo_png.place(relx=0.28, rely=0.029, height=172, width=300) set_logo_configuration(self.logo_png, image=logo_img) self.instructions = tk.Label(self) self.instructions.place(relx=0.015, rely=0.3, height=32, width=635) self.instructions.configure( text='''Creating models and runs them, please wait...''', font=Font(size=9, weight=BOLD)) set_widget_to_left(self.instructions) # Page body self.stop_png = tk.Button(self) self.loading_gif_animation = LOADING_WINDOW_SETTINGS.get('LOADING_GIF') self.delay_between_frames = LOADING_WINDOW_SETTINGS.get( 'DELAY_BETWEEN_FRAMES') self.title_font = Font(family='Helvetica', size=12, weight="bold") self.loading_gif = AnimatedGif(self, self.loading_gif_animation, self.delay_between_frames) self.loading_gif.place(relx=0.1, rely=0.38, height=330, width=600) self.clock_label = tk.Label(self, text="", font=self.title_font) self.clock_label.place(relx=0.38, rely=0.73, height=32, width=150) # Page footer self.stop_button = HoverButton(self, command=self.stop_model_process) self.stop_button.place(relx=0.813, rely=0.839, height=25, width=81) set_button_configuration(self.stop_button, text='''Stop''') self.copyright = tk.Label(self) self.copyright.place(relx=0, rely=0.958, height=25, width=750) set_copyright_configuration(self.copyright) # Page logic self.loading_gif.start() def reset_widgets(self): """ Reset check bar values :return: empty values in the widgets """ pass def stop_model_process(self): """ Handle stop button click :return: freeze state """ if self.event.isSet(): # check if the event flag is True or False self.event.clear() self.stop_button.configure(text='Resume') self.loading_gif.place_forget() self.stop_png.place(relx=0.385, rely=0.5, height=132, width=132) set_logo_configuration(self.stop_png, image=stop_img) else: self.event.set() self.stop_button.configure(text='Stop') self.stop_png.place_forget() self.loading_gif.place(relx=0.1, rely=0.35, height=330, width=600) self.start_time = timer() - self.prev_saved_time self.update_clock() def reinitialize(self): """ Reinitialize frame values and view :return: new frame view """ self.stop_button.configure(text='Stop') self.event = threading.Event() self.model_process_thread = threading.Thread( name='model_process', target=self.loading_process) self.model_process_thread.start() self.start_time = timer() self.event.set() self.update_clock() def update_clock(self): """ Updates the time on the clock :return: updated time """ if not self.event.isSet(): return now = timer() duration = timedelta(seconds=now - self.start_time) self.prev_saved_time = now - self.start_time self.clock_label.configure(text=strfdelta(duration, '%H:%M:%S')) self.controller.after(200, self.update_clock) def loading_process(self): """ Run chosen models and move to results window :return: results window """ similarity_score, test_data_path, results_path, new_model_running = self.controller.init_models( ) if new_model_running: chosen_algorithms = self.controller.get_algorithms() else: chosen_algorithms = set( self.controller.get_existing_algorithms().keys()) y_coordinate = 0.34 enumerate_details = 0 for algorithm in chosen_algorithms: if new_model_running: print_text = '''{0} : Creates a new model and runs the test data on it...'''.format( algorithm) else: print_text = '''{0} : Runs the test data...'''.format( algorithm) if enumerate_details < 4: self.algorithm_process_finished = tk.Label(self) self.algorithm_process_finished.place(relx=0.015, rely=y_coordinate, height=22, width=400) self.algorithm_process_finished.configure(text=print_text) set_widget_to_left(self.algorithm_process_finished) y_coordinate += 0.04 self.controller.run_models(algorithm, similarity_score, test_data_path, results_path, new_model_running, self.event) enumerate_details += 1 self.controller.reinitialize_frame("ResultsWindow") def show_model_process_label(self, y_coordinate, algorithm): """ Show model process label on the screen :param y_coordinate: y place coordinate :param algorithm: which algorithm to display :return: new label """ self.model_process_finished = tk.Label(self) self.model_process_finished.place(relx=0.015, rely=y_coordinate, height=22, width=215) self.model_process_finished.configure( text='''{0} model runs on the test...'''.format(algorithm)) set_widget_to_left(self.model_process_finished)
class ExistingAlgorithmsWindow(tk.Frame): """ A Class used to enable the user load existing machine learning model Methods ------- reset_widgets() Description | Reset check bar values back_window() Description | Handle back button click set_input_entry() Description | Set input entry and update the state set_algorithm_path() Description | Set the algorithm path in the UI next_window() Description | Handle next button click validate_next_step() Description | Validation before approving the move to the next window update_selected_algorithms() Description | Updates local variables which algorithms were selected by the user set_load_model_parameters() Description | Updates input settings and move to next window """ def __init__(self, parent, controller): """ Parameters ---------- :param parent: window :param controller: GUI controller """ tk.Frame.__init__(self, parent) # Page init self.controller = controller self.menubar = Menubar(controller) # Disables ability to tear menu bar into own window self.controller.option_add('*tearOff', 'FALSE') system_logo = CROSS_WINDOWS_SETTINGS.get('LOGO') photo_location = os.path.join(system_logo) global logo_img logo_img = tk.PhotoImage(file=photo_location) # Page header self.logo_png = tk.Button(self) self.logo_png.place(relx=0.28, rely=0.029, height=172, width=300) set_logo_configuration(self.logo_png, image=logo_img) self.instructions = tk.Label(self) self.instructions.place(relx=0.015, rely=0.3, height=32, width=635) self.instructions.configure( text='''Please insert paths for existing models.''') set_widget_to_left(self.instructions) # Page body self.algorithms = dict() self.browse_buttons = dict() self.input_entries = dict() # LSTM existing algorithm self.lstm_var = tk.IntVar() self.lstm_check_button = tk.Checkbutton(self) self.lstm_check_button.place(relx=0.015, rely=0.38, height=32, width=146) self.lstm_check_button.configure(text="LSTM", variable=self.lstm_var, command=lambda: self.set_input_entry("LSTM", self.lstm_var.get())) set_widget_to_left(self.lstm_check_button) self.lstm_input = tk.Entry(self) self.lstm_input.place(relx=0.195, rely=0.38, height=25, relwidth=0.624) self.lstm_input.configure(state='disabled') self.lstm_btn = HoverButton(self, command=lambda: self.set_algorithm_path("LSTM")) self.lstm_btn.place(relx=0.833, rely=0.38, height=25, width=60) self.lstm_btn.configure(state='disabled') set_button_configuration(self.lstm_btn, text='''Browse''') self.browse_buttons["LSTM"] = self.lstm_btn self.input_entries["LSTM"] = self.lstm_input # SVR existing algorithm self.svr_var = tk.IntVar() self.svr_check_button = tk.Checkbutton(self) self.svr_check_button.place(relx=0.015, rely=0.47, height=32, width=146) self.svr_check_button.configure(text="SVR", variable=self.svr_var, command=lambda: self.set_input_entry("SVR", self.svr_var.get())) set_widget_to_left(self.svr_check_button) self.svr_input = tk.Entry(self) self.svr_input.place(relx=0.195, rely=0.47, height=25, relwidth=0.624) self.svr_input.configure(state='disabled') self.svr_btn = HoverButton(self, command=lambda: self.set_algorithm_path("SVR")) self.svr_btn.place(relx=0.833, rely=0.47, height=25, width=60) self.svr_btn.configure(state='disabled') set_button_configuration(self.svr_btn, text='''Browse''') self.browse_buttons["SVR"] = self.svr_btn self.input_entries["SVR"] = self.svr_input # MLP existing algorithm self.mlp_var = tk.IntVar() self.mlp_check_button = tk.Checkbutton(self) self.mlp_check_button.place(relx=0.015, rely=0.56, height=32, width=146) self.mlp_check_button.configure(text="MLP", variable=self.mlp_var, command=lambda: self.set_input_entry("MLP", self.mlp_var.get())) set_widget_to_left(self.mlp_check_button) self.mlp_input = tk.Entry(self) self.mlp_input.place(relx=0.195, rely=0.56, height=25, relwidth=0.624) self.mlp_input.configure(state='disabled') self.mlp_btn = HoverButton(self, command=lambda: self.set_algorithm_path("MLP")) self.mlp_btn.place(relx=0.833, rely=0.56, height=25, width=60) self.mlp_btn.configure(state='disabled') set_button_configuration(self.mlp_btn, text='''Browse''') self.browse_buttons["MLP"] = self.mlp_btn self.input_entries["MLP"] = self.mlp_input # Random Forest existing algorithm self.random_forest_var = tk.IntVar() self.random_forest_check_button = tk.Checkbutton(self) self.random_forest_check_button.place(relx=0.015, rely=0.65, height=32, width=146) self.random_forest_check_button.configure(text="Random Forest", variable=self.random_forest_var, command=lambda: self.set_input_entry("Random Forest", self.random_forest_var.get())) set_widget_to_left(self.random_forest_check_button) self.random_forest_input = tk.Entry(self) self.random_forest_input.place(relx=0.195, rely=0.65, height=25, relwidth=0.624) self.random_forest_input.configure(state='disabled') self.random_forest_btn = HoverButton(self, command=lambda: self.set_algorithm_path("Random Forest")) self.random_forest_btn.place(relx=0.833, rely=0.65, height=25, width=60) self.random_forest_btn.configure(state='disabled') set_button_configuration(self.random_forest_btn, text='''Browse''') self.browse_buttons["Random Forest"] = self.random_forest_btn self.input_entries["Random Forest"] = self.random_forest_input # Page footer self.next_button = HoverButton(self, command=self.next_window) self.next_button.place(relx=0.813, rely=0.839, height=25, width=81) set_button_configuration(self.next_button, text='''Next''') self.back_button = HoverButton(self, command=self.back_window) self.back_button.place(relx=0.017, rely=0.839, height=25, width=81) set_button_configuration(self.back_button, text='''Back''') self.copyright = tk.Label(self) self.copyright.place(relx=0, rely=0.958, height=25, width=750) set_copyright_configuration(self.copyright) def reset_widgets(self): """ Reset check bar values :return: empty values in the widgets """ widgets = [ self.lstm_input, self.svr_input, self.mlp_input, self.random_forest_input ] variables = [ self.lstm_var, self.svr_var, self.mlp_var, self.random_forest_var ] check_buttons = [ self.lstm_check_button, self.svr_check_button, self.mlp_check_button, self.random_forest_check_button ] for widget in widgets: clear_text(widget) widget['state'] = 'disabled' for var, check_button in zip(variables, check_buttons): var.set(0) check_button['variable'] = var def back_window(self): """ Handle back button click :return: previous window """ self.controller.set_new_model_running(False) self.controller.show_frame("MainWindow") def set_input_entry(self, entry_name, state): """ Set input entry and update the state :param entry_name: input's algorithm name :param state: input's state :return: updated input """ if state: self.browse_buttons[entry_name]['state'] = 'active' self.input_entries[entry_name]['state'] = 'normal' self.algorithms[entry_name] = "" else: self.input_entries[entry_name].delete(0, END) self.browse_buttons[entry_name]['state'] = 'disabled' self.input_entries[entry_name]['state'] = 'disabled' self.algorithms.pop(entry_name, None) def set_algorithm_path(self, algorithm): """ Set the algorithm path in the UI :param algorithm: input algorithm :return: updated state """ self.input_entries[algorithm].delete(0, END) path = set_path() self.input_entries[algorithm].insert(0, path) def next_window(self): """ Handle next button click :return: if validations pass move to next window """ self.update_selected_algorithms() if self.validate_next_step(): self.set_load_model_parameters() def validate_next_step(self): """ Validation before approving the move to the next window :return: """ if not self.algorithms: win32api.MessageBox(0, 'Please select algorithm & path for the model before the next step.', 'Invalid algorithm', 0x00001000) return False if not is_valid_model_paths(self.algorithms.values()): win32api.MessageBox(0, 'At least one of your algorithms paths invalid or not include the required files! ' 'Please check that there are no duplicate files in the same directory.', 'Invalid inputs', 0x00001000) return False if not is_valid_model_data_file(self.algorithms.values()): win32api.MessageBox(0, 'At least one of the required data is missing in model_data json file!', 'Missing data', 0x00001000) return False return True def update_selected_algorithms(self): """ Updates local variables which algorithms were selected by the user :return: updated selection """ tmp_algorithms = dict() for algorithm in self.algorithms: tmp_algorithms[algorithm] = self.input_entries[algorithm].get() self.algorithms = tmp_algorithms def set_load_model_parameters(self): """ Updates input settings and move to next window :return: next window """ self.controller.set_existing_algorithms(self.algorithms) self.controller.reinitialize_frame("SimilarityFunctionsWindow")