From 5ecad6ce8928b9b0631dc1667f75c655b6648522 Mon Sep 17 00:00:00 2001 From: Vitali Graf Date: Sun, 28 Dec 2025 13:19:47 +0100 Subject: [PATCH] =?UTF-8?q?Feature:=20Konfigurierbare=20Worker-Anzahl=20f?= =?UTF-8?q?=C3=BCr=20parallele=20Transformationen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fügt UI-Element und Einstellung für max_workers hinzu: Änderungen: - AppSettings.max_workers Feld hinzugefügt (Standard: 8 Worker) - Menü-Item "Performance-Einstellungen..." im Projekt-Menü - QInputDialog zum einfachen Ändern der Worker-Anzahl (1-32) - TransformationThread verwendet jetzt app_settings.max_workers - Tooltip zeigt aktuelle Worker-Anzahl an Benutzung: 1. Projekt-Menü → Performance-Einstellungen... 2. Worker-Anzahl eingeben (empfohlen: 8-12 für 16-Kern-System) 3. Einstellung wird sofort gespeichert 4. Beim nächsten Transformation aktiv Alternative: max_workers direkt in config.json ändern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/conf.py | 16 ++++++++------- src/ui/MainWindow.py | 46 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/conf.py b/src/conf.py index 34a6766..94522e0 100644 --- a/src/conf.py +++ b/src/conf.py @@ -62,8 +62,8 @@ class XslDir(BaseModel): id: int name: str path_to_root_dir: Path - - + + class SSLMode(str, Enum): DISABLE = "disable" ALLOW = "allow" @@ -72,6 +72,7 @@ class SSLMode(str, Enum): VERIFY_CA = "verify-ca" VERIFY_FULL = "verify-full" + class PostgreSqlDb(BaseModel): id: int name: str @@ -141,6 +142,7 @@ class AppSettings(BaseSettings): pdf_projects: list[Project] = [] postgresql_dbs: list[PostgreSqlDb] = [] theme: str | None = None + max_workers: int = 8 # Anzahl paralleler Worker für Transformationen (Standard: 8) # UI-Zustand window_geometry: tuple[int, int, int, int] | None = None # (x, y, width, height) @@ -165,7 +167,7 @@ class AppSettings(BaseSettings): # Ordner existert nicht if not config_path.parent.exists(): config_path.parent.mkdir(parents=True, exist_ok=True) - + if not config_path.parent.is_dir() or not os.access(config_path.parent, os.W_OK): logger.exception(f"{config_path.parent} ist kein Verzeichnis oder es gibt keine Schreibrechte") sys.exit(1) @@ -205,16 +207,16 @@ class ProjectData(BaseModel): """ nodes: list[TreeNode] = [] - + @classmethod def readSettings(cls, project_dir: Path): # Explizit UTF-8 Encoding verwenden project_yaml_path = project_dir / "project.yaml" - with open(project_yaml_path, 'r', encoding='utf-8') as f: - yaml = YAML(typ='safe') + with open(project_yaml_path, "r", encoding="utf-8") as f: + yaml = YAML(typ="safe") yaml_data = yaml.load(f) return cls.model_validate(yaml_data) - + def writeSettings(self, project_dir: Path): with open(project_dir / "project.yaml", "w", encoding="utf8") as f: f.write(to_yaml_str(self)) diff --git a/src/ui/MainWindow.py b/src/ui/MainWindow.py index 8353416..a76073a 100644 --- a/src/ui/MainWindow.py +++ b/src/ui/MainWindow.py @@ -549,6 +549,9 @@ class MainWindow(QMainWindow): # Vorhandene Projekte-Menü initialisieren self._setup_projects_menu() + # Performance-Einstellungen-Menü initialisieren + self._setup_performance_menu() + # if theme := app_settings.theme: self.change_theme(theme) @@ -644,6 +647,47 @@ class MainWindow(QMainWindow): logger.info(f"Projekte-Menü initialisiert mit {len(app_settings.pdf_projects)} Projekten") + def _setup_performance_menu(self): + """Fügt ein Menü-Item für Performance-Einstellungen hinzu.""" + # Füge Separator vor der Performance-Einstellung hinzu + self.ui.menuProjekt.addSeparator() + + # Erstelle Aktion für Performance-Einstellungen + performance_action = QAction("Performance-Einstellungen...", self) + performance_action.setToolTip(f"Parallele Worker: {app_settings.max_workers}") + performance_action.triggered.connect(self._open_performance_settings) + + # Füge die Aktion zum Projekt-Menü hinzu + self.ui.menuProjekt.addAction(performance_action) + + logger.debug(f"Performance-Menü initialisiert (max_workers={app_settings.max_workers})") + + def _open_performance_settings(self): + """Öffnet einen Dialog für Performance-Einstellungen.""" + from PySide6.QtWidgets import QInputDialog + + current_workers = app_settings.max_workers + new_workers, ok = QInputDialog.getInt( + self, + "Performance-Einstellungen", + "Anzahl paralleler Worker für Transformationen:", + current_workers, # value + 1, # minValue + 32, # maxValue + 1, # step + ) + + if ok and new_workers != current_workers: + app_settings.max_workers = new_workers + app_settings.save() + logger.info(f"max_workers geändert: {current_workers} → {new_workers}") + QMessageBox.information( + self, + "Einstellungen gespeichert", + f"Anzahl paralleler Worker wurde auf {new_workers} gesetzt.\n\n" + f"Die Änderung wird bei der nächsten Transformation wirksam.", + ) + def open_existing_project(self, project: Project): """ Öffnet ein vorhandenes Projekt. @@ -3970,7 +4014,7 @@ class MainWindow(QMainWindow): return # Erstelle und konfiguriere Thread - self.transformation_thread = TransformationThread(jobs, force=force) + self.transformation_thread = TransformationThread(jobs, force=force, max_workers=app_settings.max_workers) # Verbinde Signale self.transformation_thread.job_started.connect(self._on_transformation_job_started)