base_agent/uas/inout/main.py

174 lines
7.9 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
# -*- coding: utf-8 -*-
"""
IO 模块完整演示
运行: python main.py
依赖: pip install PyQt5 SpeechRecognition pyaudio pyttsx3
"""
import logging
import sys
from PyQt5.QtCore import Qt, QTimer, pyqtSlot
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QWidget,
QVBoxLayout, QSplitter,
QTabWidget, QStatusBar
)
# ── 处理器 ────────────────────────────────────────────────────────
from processors.text_processor import PIPELINE_PRESETS
from uas.io.base_io import IOType
from uas.io.dispatcher import IODispatcher
# ── 核心模块 ──────────────────────────────────────────────────────
from uas.io.signals import io_signals
from inputs.speech_input import SpeechInputWidget
# ── 输入模块 ──────────────────────────────────────────────────────
from inputs.text_input import TextInputWidget, ConsoleTextInput
from outputs.speech_output import SpeechOutputWidget
# ── 输出模块 ──────────────────────────────────────────────────────
from outputs.text_output import TextOutputWidget
# ── 日志 ──────────────────────────────────────────────────────────
logging.basicConfig(
level = logging.DEBUG,
format = "%(asctime)s [%(levelname)-8s] %(name)s - %(message)s",
)
logger = logging.getLogger("main")
# ─────────────────────────────────────────────────────────────────
# 主窗口
# ─────────────────────────────────────────────────────────────────
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("🛰️ IO 通信模块 — PyQt5 信号槽演示")
self.resize(1100, 700)
self._setup_dispatcher()
self._setup_ui()
self._connect_signals()
self._auto_demo()
# ── 分发器初始化 ──────────────────────────────────────────────
def _setup_dispatcher(self):
self.dispatcher = IODispatcher(max_threads=4, parent=self)
# 注册文本处理链full 预设)
for proc in PIPELINE_PRESETS["full"]:
self.dispatcher.register_processor(IOType.TEXT, proc)
# 注册语音处理链
for proc in PIPELINE_PRESETS["speech"]:
self.dispatcher.register_processor(IOType.SPEECH, proc)
self.dispatcher.start()
logger.info("✅ 分发器已启动")
# ── UI 构建 ───────────────────────────────────────────────────
def _setup_ui(self):
central = QWidget()
self.setCentralWidget(central)
main_layout = QVBoxLayout(central)
main_layout.setContentsMargins(6, 6, 6, 6)
# 水平分割:左=输入,右=输出
splitter = QSplitter(Qt.Horizontal)
# ── 左侧:输入 Tab ────────────────────────────────────────
input_tabs = QTabWidget()
self.text_input = TextInputWidget()
self.speech_input = SpeechInputWidget()
input_tabs.addTab(self.text_input, "📝 文本输入")
input_tabs.addTab(self.speech_input, "🎤 语音输入")
splitter.addWidget(input_tabs)
# ── 右侧:输出 Tab ────────────────────────────────────────
output_tabs = QTabWidget()
self.text_output = TextOutputWidget()
self.speech_output = SpeechOutputWidget()
output_tabs.addTab(self.text_output, "📄 文本输出")
output_tabs.addTab(self.speech_output, "🔊 语音输出")
splitter.addWidget(output_tabs)
splitter.setSizes([420, 660])
main_layout.addWidget(splitter)
# ── 状态栏 ────────────────────────────────────────────────
self._status = QStatusBar()
self.setStatusBar(self._status)
self._status.showMessage("就绪 | IODispatcher 运行中")
# ── 信号连接 ──────────────────────────────────────────────────
def _connect_signals(self):
# 全局信号监听(用于状态栏更新)
io_signals.input_received.connect(self._on_input_received)
io_signals.input_processed.connect(self._on_processed)
io_signals.error_occurred.connect(self._on_error)
io_signals.speech_recognized.connect(self._on_speech_recognized)
@pyqtSlot(str, str, object)
def _on_input_received(self, data_id: str, io_type: str, data):
self._status.showMessage(
f"📥 收到输入 [{io_type}] id={data_id[:8]} 正在处理..."
)
@pyqtSlot(str, str, object)
def _on_processed(self, data_id: str, io_type: str, data):
self._status.showMessage(
f"✅ 处理完成 [{io_type}] id={data_id[:8]}"
)
@pyqtSlot(str, str, str)
def _on_error(self, data_id: str, source: str, msg: str):
self._status.showMessage(f"❌ 错误 [{source}]: {msg}")
@pyqtSlot(str)
def _on_speech_recognized(self, text: str):
self._status.showMessage(f"🎤 语音识别: {text}")
# ── 自动演示 ──────────────────────────────────────────────────
def _auto_demo(self):
"""启动后自动注入几条测试消息"""
demo_texts = [
"Hello World这是第一条测试消息。",
"PyQt5 信号与槽机制实现异步IO分发",
"支持文本、语音、文件等多种输入输出类型!",
]
console_input = ConsoleTextInput(self)
def inject_next(idx=0):
if idx < len(demo_texts):
console_input.inject(demo_texts[idx])
QTimer.singleShot(800, lambda: inject_next(idx + 1))
QTimer.singleShot(500, inject_next)
def closeEvent(self, event):
self.dispatcher.stop()
self.speech_input.stop()
event.accept()
# ─────────────────────────────────────────────────────────────────
# 入口
# ─────────────────────────────────────────────────────────────────
def main():
app = QApplication(sys.argv)
app.setStyle("Fusion")
win = MainWindow()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()