瀏覽代碼

adding corrections done with AI to allow Linuw running

Eric Streit 4 周之前
父節點
當前提交
0dc066690f
共有 5 個文件被更改,包括 102 次插入 和 13 次删除
  1. 84 1
      gui/utils_qt.py
  2. 4 3
      gui/views/calibration_view_qt.py
  3. 3 2
      gui/views/checker_view_qt.py
  4. 8 5
      gui/views/raster_view_qt.py
  5. 3 2
      gui/views/simulation_view_qt.py

+ 84 - 1
gui/utils_qt.py

@@ -1,10 +1,93 @@
 import os
 import os
-from PyQt6.QtWidgets import QLabel, QWidget, QVBoxLayout, QFrame, QProgressBar
+from PyQt6.QtWidgets import QLabel, QWidget, QVBoxLayout, QFrame, QProgressBar, QFileDialog
 from PyQt6.QtGui import QPixmap, QPainter, QColor
 from PyQt6.QtGui import QPixmap, QPainter, QColor
 from PyQt6.QtSvg import QSvgRenderer
 from PyQt6.QtSvg import QSvgRenderer
 from PyQt6.QtCore import Qt, QSize, QPointF, QTimer
 from PyQt6.QtCore import Qt, QSize, QPointF, QTimer
 
 
 
 
+# ══════════════════════════════════════════════════════════════════
+#  DIALOGUES FICHIERS  (QFileDialog isolé du stylesheet parent)
+# ══════════════════════════════════════════════════════════════════
+
+_FILE_DIALOG_QSS = """
+    QDialog { background-color: #2b2b2b; color: #DCE4EE; }
+    QLabel { color: #DCE4EE; background: transparent; }
+    QLineEdit { background-color: #1a1a1a; color: #DCE4EE;
+                border: 1px solid #444; border-radius: 4px; padding: 4px;
+                selection-background-color: #1f538d; }
+    QListView, QTreeView { background-color: #1e1e1e; color: #DCE4EE;
+                           border: 1px solid #333; outline: none; }
+    QListView::item, QTreeView::item { color: #DCE4EE; }
+    QListView::item:selected, QTreeView::item:selected { background-color: #1f538d; color: white; }
+    QListView::item:hover, QTreeView::item:hover { background-color: #333333; }
+    QHeaderView::section { background-color: #252525; color: #DCE4EE;
+                           border: 1px solid #333; padding: 4px; }
+    QPushButton { background-color: #444444; color: #ffffff;
+                  border: 1px solid #555; border-radius: 4px; padding: 5px 14px; }
+    QPushButton:hover { background-color: #555555; }
+    QPushButton:default { background-color: #1f538d; border-color: #2a6dbd; }
+    QComboBox { background-color: #1a1a1a; color: #DCE4EE;
+                border: 1px solid #444; border-radius: 4px; padding: 3px 8px; }
+    QComboBox QAbstractItemView { background-color: #1e1e1e; color: #DCE4EE;
+                                  selection-background-color: #1f538d;
+                                  border: 1px solid #444; }
+    QToolButton { background-color: #333333; color: #DCE4EE; border: none; border-radius: 4px; }
+    QToolButton:hover { background-color: #444444; }
+    QToolButton:checked { background-color: #1f538d; }
+    QSplitter::handle { background-color: #333333; }
+    QScrollBar:vertical, QScrollBar:horizontal { background: #202020; }
+    QScrollBar::handle:vertical, QScrollBar::handle:horizontal { background: #3e3e3e; border-radius: 3px; }
+    QScrollBar::add-line, QScrollBar::sub-line { height: 0; width: 0; }
+"""
+
+
+def _file_dialog(parent, title, default, name_filter, file_mode, accept_mode):
+    """
+    Construit un QFileDialog Qt-widget autonome.
+    Evite le dialogue natif Linux (portal D-Bus, instable sous XCB) et isole
+    le dialogue du stylesheet du parent (qui donnait un fond noir illisible).
+    """
+    dlg = QFileDialog(parent)
+    dlg.setFileMode(file_mode)
+    dlg.setAcceptMode(accept_mode)
+    dlg.setOption(QFileDialog.Option.DontUseNativeDialog, True)
+    if title:
+        dlg.setWindowTitle(title)
+    if name_filter:
+        dlg.setNameFilter(name_filter)
+    if default:
+        dlg.selectFile(default)
+    dlg.setStyleSheet(_FILE_DIALOG_QSS)
+
+    ok = dlg.exec()
+    selected = ""
+    if ok and dlg.selectedFiles():
+        selected = dlg.selectedFiles()[0]
+    return selected, dlg.selectedNameFilter()
+
+
+def get_open_file(parent, title="", directory="", filter_=""):
+    """Ouvre un sélecteur de fichier (widget Qt isolé). Retourne (path, selected_filter)."""
+    return _file_dialog(parent, title, directory, filter_,
+                        QFileDialog.FileMode.ExistingFile,
+                        QFileDialog.AcceptMode.AcceptOpen)
+
+
+def get_save_file(parent, title="", directory="", filter_=""):
+    """Ouvre un sélecteur d'enregistrement (widget Qt isolé). Retourne (path, selected_filter)."""
+    return _file_dialog(parent, title, directory, filter_,
+                        QFileDialog.FileMode.AnyFile,
+                        QFileDialog.AcceptMode.AcceptSave)
+
+
+def get_existing_directory(parent, title="", directory=""):
+    """Ouvre un sélecteur de dossier (widget Qt isolé)."""
+    path, _ = _file_dialog(parent, title, directory, "",
+                           QFileDialog.FileMode.Directory,
+                           QFileDialog.AcceptMode.AcceptOpen)
+    return path
+
+
 # ══════════════════════════════════════════════════════════════════
 # ══════════════════════════════════════════════════════════════════
 #  SVG / ICÔNES
 #  SVG / ICÔNES
 # ══════════════════════════════════════════════════════════════════
 # ══════════════════════════════════════════════════════════════════

+ 4 - 3
gui/views/calibration_view_qt.py

@@ -2,7 +2,7 @@ import os
 import tempfile
 import tempfile
 from PyQt6.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout, QBoxLayout, QFrame, 
 from PyQt6.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout, QBoxLayout, QFrame, 
                              QLabel, QScrollArea, QStackedWidget, QPushButton, 
                              QLabel, QScrollArea, QStackedWidget, QPushButton, 
-                             QLineEdit, QGridLayout, QButtonGroup, QFileDialog,
+                             QLineEdit, QGridLayout, QButtonGroup,
                              QMessageBox, QComboBox)
                              QMessageBox, QComboBox)
 from PyQt6.QtCore import Qt, QSize, QTimer
 from PyQt6.QtCore import Qt, QSize, QTimer
 from PyQt6.QtGui import QIcon, QPixmap
 from PyQt6.QtGui import QIcon, QPixmap
@@ -12,6 +12,7 @@ from core.themes import get_theme
 from gui.switch import Switch
 from gui.switch import Switch
 from core.translations import TRANSLATIONS
 from core.translations import TRANSLATIONS
 from gui.utils_qt import get_svg_pixmap
 from gui.utils_qt import get_svg_pixmap
+from gui.utils_qt import get_save_file
 from engine.calibrate_engine import CalibrateEngine
 from engine.calibrate_engine import CalibrateEngine
 
 
 
 
@@ -1136,7 +1137,7 @@ class CalibrationView(QWidget):
             gcode_content = self.calibrate_engine.generate_latency_calibration(settings)
             gcode_content = self.calibrate_engine.generate_latency_calibration(settings)
 
 
             lat_val = settings["latency"]
             lat_val = settings["latency"]
-            file_path, _ = QFileDialog.getSaveFileName(
+            file_path, _ = get_save_file(
                 self,
                 self,
                 self.texts.get("save_dialog_title", "Save Calibration G-Code"),
                 self.texts.get("save_dialog_title", "Save Calibration G-Code"),
                 f"latency_test_{lat_val}ms.nc",
                 f"latency_test_{lat_val}ms.nc",
@@ -1192,7 +1193,7 @@ class CalibrationView(QWidget):
 
 
             # 4. Dialogue de sauvegarde
             # 4. Dialogue de sauvegarde
             mode_name = settings["scan_mode"].split()[0].lower()
             mode_name = settings["scan_mode"].split()[0].lower()
-            file_path, _ = QFileDialog.getSaveFileName(
+            file_path, _ = get_save_file(
                 self, "Save LineStep Test", f"linestep_grid_{mode_name}.nc", "G-Code (*.nc *.gcode)"
                 self, "Save LineStep Test", f"linestep_grid_{mode_name}.nc", "G-Code (*.nc *.gcode)"
             )
             )
 
 

+ 3 - 2
gui/views/checker_view_qt.py

@@ -12,7 +12,7 @@ import numpy as np
 
 
 from PyQt6.QtWidgets import (
 from PyQt6.QtWidgets import (
     QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
     QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
-    QProgressBar, QSizePolicy, QFileDialog, QMessageBox, QPlainTextEdit,
+    QProgressBar, QSizePolicy, QMessageBox, QPlainTextEdit,
     QDoubleSpinBox,
     QDoubleSpinBox,
 )
 )
 from PyQt6.QtCore import (
 from PyQt6.QtCore import (
@@ -28,6 +28,7 @@ from core.utils import truncate_path
 from core.translations import TRANSLATIONS
 from core.translations import TRANSLATIONS
 from utils.paths import SVG_ICONS
 from utils.paths import SVG_ICONS
 from gui.utils_qt import get_svg_pixmap
 from gui.utils_qt import get_svg_pixmap
+from gui.utils_qt import get_open_file
 from gui.switch import Switch
 from gui.switch import Switch
 
 
 
 
@@ -1032,7 +1033,7 @@ class CheckerViewQt(QWidget):
     def _on_open_file(self):
     def _on_open_file(self):
         """Ouvre un QFileDialog et charge le fichier sélectionné."""
         """Ouvre un QFileDialog et charge le fichier sélectionné."""
         stds = 'G-Code (*.nc *.gcode *.gc *.tap *.txt);;All files (*.*)'
         stds = 'G-Code (*.nc *.gcode *.gc *.tap *.txt);;All files (*.*)'
-        path, _ = QFileDialog.getOpenFileName(
+        path, _ = get_open_file(
             self, self.t.get('open_file', 'Open G-Code file'), '', stds)
             self, self.t.get('open_file', 'Open G-Code file'), '', stds)
         if path:
         if path:
             self._load_file(path)
             self._load_file(path)

+ 8 - 5
gui/views/raster_view_qt.py

@@ -21,7 +21,7 @@ import numpy as np
 from PyQt6.QtWidgets import (
 from PyQt6.QtWidgets import (
     QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
     QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
     QComboBox, QLineEdit, QSlider, QScrollArea, QSplitter,
     QComboBox, QLineEdit, QSlider, QScrollArea, QSplitter,
-    QTextEdit, QSizePolicy, QFileDialog, QMessageBox, QTabWidget,
+    QTextEdit, QSizePolicy, QMessageBox, QTabWidget,
 )
 )
 from PyQt6.QtCore import Qt, QTimer, QSize, QPointF, QRectF
 from PyQt6.QtCore import Qt, QTimer, QSize, QPointF, QRectF
 from PyQt6.QtGui import (
 from PyQt6.QtGui import (
@@ -40,6 +40,9 @@ from gui.utils_qt import (
     hide_loading_overlay,
     hide_loading_overlay,
     PanZoomMixin,
     PanZoomMixin,
     translate_ui_widgets,
     translate_ui_widgets,
+    get_open_file,
+    get_save_file,
+    get_existing_directory,
 )
 )
 from core.translations import TRANSLATIONS
 from core.translations import TRANSLATIONS
 from core.themes import get_theme
 from core.themes import get_theme
@@ -1994,7 +1997,7 @@ class RasterViewQt(QWidget):
     # ── Sélection fichiers ────────────────────────────────────────────
     # ── Sélection fichiers ────────────────────────────────────────────
 
 
     def select_input(self):
     def select_input(self):
-        path, _ = QFileDialog.getOpenFileName(
+        path, _ = get_open_file(
             self, "Select Image", "",
             self, "Select Image", "",
             "Image files (*.jpg *.jpeg *.png *.bmp)"
             "Image files (*.jpg *.jpeg *.png *.bmp)"
         )
         )
@@ -2007,7 +2010,7 @@ class RasterViewQt(QWidget):
             self._schedule_preview()
             self._schedule_preview()
 
 
     def select_output(self):
     def select_output(self):
-        directory = QFileDialog.getExistingDirectory(self, "Select Output Folder")
+        directory = get_existing_directory(self, "Select Output Folder")
         if directory:
         if directory:
             self.output_dir = directory
             self.output_dir = directory
             folder = os.path.basename(directory) or directory
             folder = os.path.basename(directory) or directory
@@ -2017,7 +2020,7 @@ class RasterViewQt(QWidget):
     # ── Profils ───────────────────────────────────────────────────────
     # ── Profils ───────────────────────────────────────────────────────
 
 
     def export_profile(self):
     def export_profile(self):
-        path, _ = QFileDialog.getSaveFileName(
+        path, _ = get_save_file(
             self, "Export Profile",
             self, "Export Profile",
             os.path.join(self.application_path, "alig_profile.json"),
             os.path.join(self.application_path, "alig_profile.json"),
             "JSON (*.json)"
             "JSON (*.json)"
@@ -2038,7 +2041,7 @@ class RasterViewQt(QWidget):
                              f"Export failed:\n{err}")
                              f"Export failed:\n{err}")
 
 
     def load_profile_from(self):
     def load_profile_from(self):
-        path, _ = QFileDialog.getOpenFileName(
+        path, _ = get_open_file(
             self, "Load Profile", self.application_path, "JSON (*.json)"
             self, "Load Profile", self.application_path, "JSON (*.json)"
         )
         )
         if path:
         if path:

+ 3 - 2
gui/views/simulation_view_qt.py

@@ -20,7 +20,7 @@ import numpy as np
 
 
 from PyQt6.QtWidgets import (
 from PyQt6.QtWidgets import (
     QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
     QWidget, QFrame, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
-    QProgressBar, QSizePolicy, QFileDialog, QMessageBox, QPlainTextEdit,
+    QProgressBar, QSizePolicy, QMessageBox, QPlainTextEdit,
 )
 )
 from PyQt6.QtCore import (
 from PyQt6.QtCore import (
     Qt, QTimer, QThread, pyqtSignal, QRect, QRectF, QPointF, QLineF, QSize
     Qt, QTimer, QThread, pyqtSignal, QRect, QRectF, QPointF, QLineF, QSize
@@ -36,6 +36,7 @@ from core.translations import TRANSLATIONS
 from core.themes import get_theme
 from core.themes import get_theme
 from utils.paths import SVG_ICONS
 from utils.paths import SVG_ICONS
 from gui.utils_qt import get_svg_pixmap
 from gui.utils_qt import get_svg_pixmap
+from gui.utils_qt import get_save_file
 from gui.switch import Switch
 from gui.switch import Switch
 
 
 
 
@@ -1771,7 +1772,7 @@ class SimulationViewQt(QWidget):
         parts = [f'{l} (Default) (*{e})' if e == ext else f'{l} (*{e})'
         parts = [f'{l} (Default) (*{e})' if e == ext else f'{l} (*{e})'
                  for e, l in stds]
                  for e, l in stds]
         parts.append('All files (*.*)')
         parts.append('All files (*.*)')
-        path, _ = QFileDialog.getSaveFileName(
+        path, _ = get_save_file(
             self, self.t.get('export_as', 'Export G-Code As…'),
             self, self.t.get('export_as', 'Export G-Code As…'),
             os.path.join(meta.get('output_dir', ''), f'{name}{ext}'),
             os.path.join(meta.get('output_dir', ''), f'{name}{ext}'),
             ';;'.join(parts))
             ';;'.join(parts))