|
|
@@ -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
|
|
|
|
|
|
# ---------- 定时任务 ----------
|