def console_connect(self) -> None: """Turn the OS command line (stdout) log to console.""" logger.info("Connect to GUI console.") XStream.stdout().message_written.connect(self.__append_to_console) self.console_connect_button.setEnabled(False) self.console_disconnect_button.setEnabled(True) logger.info("Connect to GUI console.")
def __close_work(self) -> None: """Close the thread.""" if not self.work.isRunning(): return self.stop_signal.emit() logger.info("The thread has been canceled.") self.work.wait()
def load_example(self, is_import: bool = False) -> bool: """Load example to new workbook.""" # load example by expression example_name, ok = QInputDialog.getItem(self, "Examples", "Select an example to load:", sorted(example_list), 0, False) if not ok: return False if not is_import: self.reset() self.main_clear() if self.prefer.open_project_actions_option == 1: self.command_stack.beginMacro("Add mechanism") expr, inputs = example_list[example_name] self.parse_expression(expr) if not is_import: if self.prefer.open_project_actions_option == 1: self.command_stack.endMacro() self.command_stack.beginMacro("Add inputs data") # Import without inputs data self.load_inputs(inputs) if self.prefer.open_project_actions_option == 0: self.command_stack.clear() self.command_stack.setUndoLimit(self.prefer.undo_limit_option) elif self.prefer.open_project_actions_option == 1: self.command_stack.endMacro() self.set_file_name(example_name, is_example=True) self.workbook_saved() logger.info(f"Example \"{example_name}\" has been loaded.") return True
def new_main_window() -> None: """Start a new window.""" w = type(self)() if not ARGUMENTS.debug_mode: w.console_connect() w.show() logger.info("New window started.")
def console_disconnect(self) -> None: """Turn the console log to OS command line (stdout).""" logger.info("Disconnect from GUI console.") XStream.back() self.console_connect_button.setEnabled(True) self.console_disconnect_button.setEnabled(False) logger.info("Disconnect from GUI console.")
def __algorithm(self) -> Dict[str, Any]: """Get the algorithm result.""" t0 = perf_counter() expression, tf = self.__generate_process() time_spend = perf_counter() - t0 cpu_info = cpu.info[0] last_gen = tf[-1][0] mechanism = { 'Algorithm': self.type_num.value, 'time': time_spend, 'last_gen': last_gen, 'last_fitness': tf[-1][1], 'interrupted': str(last_gen) if self.is_stop else 'False', 'settings': self.settings, 'hardware_info': { 'os': f"{system()} {release()} {machine()}", 'memory': f"{virtual_memory().total / (1 << 30):.04f} GB", 'cpu': cpu_info.get("model name", cpu_info.get('ProcessorNameString', '')), }, 'time_fitness': tf, } mechanism.update(self.mech_params) mechanism['Expression'] = expression logger.info(f"cost time: {time_spend:.02f} [s]") return mechanism
def __path_dlg(self, item: QListWidgetItem) -> None: """View path data.""" name = item.text().split(":")[0] try: data = self.__path_data[name] except KeyError: return points_text = ", ".join(f"Point{i}" for i in range(len(data))) if QMessageBox.question(self, "Path data", f"This path data including {points_text}.", (QMessageBox.Save | QMessageBox.Close), QMessageBox.Close) != QMessageBox.Save: return file_name = self.output_to( "path data", ["Comma-Separated Values (*.csv)", "Text file (*.txt)"]) if not file_name: return with open(file_name, 'w', encoding='utf-8', newline='') as stream: writer = csv.writer(stream) for point in data: for coordinate in point: writer.writerow(coordinate) writer.writerow(()) logger.info(f"Output path data: {file_name}")
def save_reply_box(self, title: str, file_name: str) -> None: """Show message when successfully saved.""" size = size_format(QFileInfo(file_name).size()) QMessageBox.information( self, f"Initial Saved: {title}", f"Successfully saved:\n{file_name}\n" f"Size: {size}") logger.info(f"Saved: [\"{file_name}\"] ({size})")
def closeEvent(self, event: QCloseEvent) -> None: """Close event to avoid user close the window accidentally.""" if self.check_file_changed(): event.ignore() return if self.inputs_widget.inputs_play_shaft.isActive(): self.inputs_widget.inputs_play_shaft.stop() self.save_settings() XStream.back() logger.info("Exit") event.accept()
def run(self) -> None: """Start the algorithm loop.""" for name, path in self.mech_params['Target'].items(): logger.debug(f"- [P{name}] ({len(path)})") t0 = perf_counter() for self.current_loop in range(self.loop): logger.info( f"Algorithm [{self.current_loop + 1}]: {self.type_num}") if self.is_stop: # Cancel the remaining tasks logger.info("Canceled.") continue self.result.emit(self.__algorithm()) logger.info(f"total cost time: {perf_counter() - t0:.02f} [s]") self.finished.emit()
def __interrupt(self) -> None: """Interrupt the process.""" if self.work.isRunning(): self.stop_signal.emit() logger.info("The thread has been interrupted.")
def load_data(self, file_name: str, data: Dict[str, Any]) -> None: """Load file method.""" self.main_clear() ver = data.get('pyslvs_ver', "") if ver: logger.info(f"Load data from Pyslvs {ver}") del ver dlg = QProgressDialog("Loading project", "Cancel", 0, 8, self.parent()) dlg.setLabelText("Reading file ...") dlg.show() # Mechanism data dlg.setValue(1) dlg.setLabelText("Loading mechanism ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add mechanism") links_data: Dict[str, str] = data.get('links', {}) self.add_empty_links(links_data) mechanism_data: str = data.get('mechanism', "") self.parse_expression(mechanism_data) self.__end_group() # Input data dlg.setValue(2) dlg.setLabelText("Loading inputs data ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add inputs data") input_data: List[Dict[str, int]] = data.get('input', []) i_attr = [] for b, d in input_data: QCoreApplication.processEvents() i_attr.append((b, d)) self.load_inputs(i_attr) self.__end_group() # Storage data dlg.setValue(3) dlg.setLabelText("Loading storage ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add storage") storage_data: Dict[str, str] = data.get('storage', {}) self.load_storage(storage_data) self.__end_group() # Path data dlg.setValue(4) dlg.setLabelText("Loading paths ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add paths") path_data: Dict[str, Sequence[Tuple[float, float]]] = data.get('path', {}) self.load_paths(path_data) self.__end_group() # Collection data dlg.setValue(5) dlg.setLabelText("Loading graph collections ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add graph collections") collection_data: List[Tuple[Tuple[int, int], ...]] = data.get('collection', []) self.load_collections(collection_data) self.__end_group() # Configuration data dlg.setValue(6) dlg.setLabelText("Loading synthesis configurations ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add synthesis configurations") config_data: Dict[str, Dict[str, Any]] = data.get('triangle', {}) self.load_config(config_data) self.__end_group() # Algorithm data dlg.setValue(7) dlg.setLabelText("Loading synthesis results ...") if dlg.wasCanceled(): dlg.deleteLater() return self.main_clear() self.__set_group("Add synthesis results") algorithm_data: List[Dict[str, Any]] = data.get('algorithm', []) self.load_algorithm(algorithm_data) self.__end_group() # Workbook loaded dlg.setValue(8) dlg.deleteLater() # File type option align (ignore previous one) self.prefer.file_type_option = data.get('file_type', 0) # Show overview dialog dlg = OverviewDialog(self.parent(), QFileInfo(file_name).baseName(), storage_data, i_attr, path_data, collection_data, config_data, algorithm_data) dlg.show() dlg.exec_() dlg.deleteLater()
def __new_workbook(self) -> None: """Create (Clean) a new workbook.""" if self.check_file_changed(): return self.clear() logger.info("Created a new workbook.")