Browse Source

fix: pyttsx3 单线程队列播报避免 runAndWait 冲突;增加到达工位语音提示

lsfoo 4 months ago
parent
commit
995a33c6b9
2 changed files with 28 additions and 5 deletions
  1. 5 0
      .vscode/settings.json
  2. 23 5
      hookvision/main_window.py

+ 5 - 0
.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+    "python-envs.defaultEnvManager": "ms-python.python:conda",
+    "python-envs.defaultPackageManager": "ms-python.python:conda",
+    "editor.fontFamily": "Fira Code Retina"
+}

+ 23 - 5
hookvision/main_window.py

@@ -1,6 +1,7 @@
 import os
 import logging
 import threading
+import queue
 from PySide6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
                                QPushButton, QLabel, QGridLayout, QScrollArea,
                                QToolButton, QFrame, QApplication, QCheckBox)
@@ -57,7 +58,10 @@ class MainWindow(QMainWindow):
         self.tts_engine = pyttsx3.init()
         self.tts_engine.setProperty('rate', 150)
         self.last_voice_state = None
-        self.voice_enabled = True  # 默认开启
+        self.voice_enabled = True
+        self._voice_queue = queue.Queue()
+        self._voice_thread = threading.Thread(target=self._voice_worker, daemon=True)
+        self._voice_thread.start()
 
         self.setWindowTitle(config.app_name)
 
@@ -269,6 +273,21 @@ class MainWindow(QMainWindow):
     def on_voice_toggle(self, state):
         self.voice_enabled = (state == Qt.Checked)
 
+    def _speak(self, msg: str):
+        self._voice_queue.put(msg)
+
+    def _voice_worker(self):
+        while True:
+            msg = self._voice_queue.get()
+            if msg is None:
+                break
+            try:
+                self.tts_engine.say(msg)
+                self.tts_engine.runAndWait()
+            except Exception as e:
+                logging.warning(f"语音播报失败: {e}")
+            self._voice_queue.task_done()
+
     # ---------- 工位图标 ----------
     def get_bucket_icon(self, is_active):
         icon_dir = os.path.join(os.path.dirname(__file__), "..", "assets")
@@ -428,6 +447,8 @@ class MainWindow(QMainWindow):
     def activate_bucket(self, bucket: BucketModel):
         if self.active_bucket == bucket:
             return
+        if bucket and self.voice_enabled:
+            self._speak(f"到达{bucket.description}")
         if self.left_player:
             self.left_player.stop()
             self.left_player = None
@@ -736,10 +757,7 @@ class MainWindow(QMainWindow):
         # 语音播报(带开关和防重复)
         if self.voice_enabled and state in (HookState.HOOKING, HookState.READY) and state != self.last_voice_state:
             msg = "挂包中" if state == HookState.HOOKING else "挂包成功"
-            def speak():
-                self.tts_engine.say(msg)
-                self.tts_engine.runAndWait()
-            threading.Thread(target=speak, daemon=True).start()
+            self._speak(msg)
             self.last_voice_state = state
 
     # ---------- 定时任务 ----------