base_agent/uas/inout/main.py

174 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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()