def load_example(self, is_import: bool = False) -> bool:
     """Load example to new project."""
     # load example by expression
     example_name, ok = QInputDialog.getItem(self, "Examples",
                                             "Select an example to load:",
                                             all_examples(), 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.project_saved()
     logger.info(f"Example \"{example_name}\" has been loaded.")
     return True
Beispiel #2
0
 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.")
Beispiel #3
0
 def __task(self) -> Dict[str, Any]:
     """Get the algorithm result."""
     t0 = process_time()
     a = algorithm(self.alg)(
         self.planar,
         self.settings,
         progress_fun=self.progress_update.emit,
         interrupt_fun=lambda: self.is_stop,
     )
     expression = a.run()
     tf = a.history()
     time_spend = process_time() - t0
     last_gen = tf[-1][0]
     mechanism = {
         'algorithm': self.alg.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()}",
             'cpu': processor(),
         },
         'time_fitness': tf,
         'callback': self.planar.callback,
     }
     mechanism.update(self.mech)
     mechanism['expression'] = expression
     logger.info(f"cost time: {time_spend:.02f} [s]")
     return mechanism
Beispiel #4
0
 def __path_dlg(self, item: QListWidgetItem) -> None:
     """View path data."""
     name = item.text().split(":", maxsplit=1)[0]
     try:
         paths = self.__paths[name]
     except KeyError:
         return
     points_text = ", ".join(f"Point{i}" for i in range(len(paths)))
     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:
         w = writer(stream)
         for path in paths:
             for point in path:
                 w.writerow(point)
             w.writerow(())
     logger.info(f"Output path data: {file_name}")
Beispiel #5
0
 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.")
Beispiel #6
0
 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()
Beispiel #7
0
 def __algorithm(self) -> Dict[str, Any]:
     """Get the algorithm result."""
     t0 = process_time()
     algorithm = ALGORITHM[self.algorithm](
         self.planar,
         self.settings,
         progress_fun=self.progress_update.emit,
         interrupt_fun=lambda: self.is_stop,
     )
     expression = algorithm.run()
     tf = algorithm.history()
     time_spend = process_time() - t0
     info = cpu.info[0]
     my_cpu = info.get("model name", info.get('ProcessorNameString', ''))
     last_gen = tf[-1][0]
     mechanism = {
         'algorithm': self.algorithm.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()}",
             'cpu': my_cpu,
         },
         'time_fitness': tf,
     }
     mechanism.update(self.mech)
     mechanism['expression'] = expression
     logger.info(f"cost time: {time_spend:.02f} [s]")
     return mechanism
Beispiel #8
0
 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})")
Beispiel #9
0
 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()
Beispiel #10
0
 def load_data(self, file_name: str, data: _Data) -> None:
     """Load file method."""
     self.main_clear()
     ver = data.get('pyslvs_ver', "")
     if ver:
         logger.info(f"Load data from version {ver}")
     del ver
     self.dlg = QProgressDialog("Loading project", "Cancel", 0, 7,
                                self._parent)
     self.dlg.show()
     try:
         mechanism_data = self.__load_mech(data)
         storage_data = self.__load_storage(data)
         input_data = self.__load_input(data)
         paths = self.__load_path(data)
         collection_data = self.__load_collection(data)
         config_data = self.__load_config(data)
         algorithm_data = self.__load_algorithm(data)
         self.__load_background(data)
     except Exception as e:
         QMessageBox.warning(self._parent, "Load error", f"Exception:\n{e}")
         self.dlg.deleteLater()
         self.dlg = None
         return
     # File type option align (ignore previous one)
     self.prefer.file_type_option = data.get('file_type', 0)
     # Show overview dialog
     self.dlg.deleteLater()
     self.dlg = OverviewDialog(
         self._parent,
         QFileInfo(file_name).baseName(),
         mechanism_data,
         storage_data,
         input_data,
         paths,
         collection_data,
         config_data,
         algorithm_data,
         self.get_background_path()
     )
     self.dlg.show()
     self.dlg.exec_()
     self.dlg.deleteLater()
     self.dlg = None
Beispiel #11
0
def main() -> None:
    """Startup function."""
    global _app
    t0 = process_time()
    exit_code = 0
    from sys import argv, exit
    from logging import shutdown
    from platform import system
    from pyslvs_ui.info import ARGUMENTS, logger
    if ARGUMENTS.cmd in {'gui', None}:
        from qtpy.QtCore import Qt, qInstallMessageHandler
        from qtpy.QtWidgets import QApplication, QSplashScreen
        from qtpy.QtGui import QPixmap
        _app = QApplication(argv)
        # Depress Qt warning
        qInstallMessageHandler(lambda _0, _1, _2: None)
        # Load QRC file
        from pyslvs_ui.icons_rc import qInitResources
        qInitResources()
        # Splash
        sp = QSplashScreen(QPixmap(":/icons/splash.png"))
        sp.showMessage(f"{__author__} {__copyright__}",
                       Qt.AlignBottom | Qt.AlignRight)
        sp.show()
        # Force enable fusion style on macOS
        if system() == 'Darwin':
            ARGUMENTS.fusion = True
        if ARGUMENTS.fusion:
            _app.setStyle('fusion')
        # Main window
        from .main_window import MainWindow
        w = MainWindow.new()
        sp.finish(w)
        sp.deleteLater()
        logger.info(f"Startup with: {process_time() - t0:.02f}s")
        if not ARGUMENTS.debug_mode:
            w.console_connect()
        del sp, w
        exit_code = _app.exec_()
    elif ARGUMENTS.cmd == 'test':
        from importlib import import_module
        import_module('pyslvs_ui.main_window')
        logger.info("All module loaded successfully.")
        logger.info(f"Loaded with: {process_time() - t0:.02f}s")
    elif ARGUMENTS.cmd == 'extract':
        logger.info(f"Start CLI: {process_time() - t0:.02f}s")
        # TODO: CLI mode
    else:
        raise ValueError(f"unknown command: {ARGUMENTS.cmd}")
    shutdown()
    exit(exit_code)
Beispiel #12
0
 def run(self) -> None:
     """Start the algorithm loop."""
     for name, path in self.mech['target'].items():
         logger.debug(f"- [P{name}] ({len(path)})")
     t0 = process_time()
     for self.loop in range(self.loop):
         logger.info(f"Algorithm [{self.loop + 1}]: {self.alg}")
         if self.is_stop:
             # Cancel the remaining tasks
             logger.info("Canceled.")
             continue
         self.result.emit(self.__task())
     logger.info(f"total cost time: {process_time() - t0:.02f} [s]")
     self.finished.emit()
Beispiel #13
0
 def __new_project(self) -> None:
     """Create (Clean) a new project."""
     if self.check_file_changed():
         return
     self.clear()
     logger.info("Created a new project.")
Beispiel #14
0
 def __interrupt(self) -> None:
     """Interrupt the process."""
     if self.work.isRunning():
         self.stop_signal.emit()
         logger.info("The thread has been interrupted.")