- Fix window drag: install eventFilter on live2d_container, central, and _live2d_widget; fix super() call in dynamic class - Fix text input: remove WA_TransparentForMouseEvents from _chat_container - Force QT_QPA_PLATFORM=xcb on Linux (wayland has mouse event issues) - Add HealthTracker module, update AgentBrain with health integration - Update scheduler and memory modules - Add v5_modify documentation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
EzVibe v3 演进修改记录
本文档记录从 EVOLUTION_ROADMAP.md 出发的所有实际代码改动。 对应 Phase 3 的已完成项。
Phase 3:系统托盘与交互升级
Phase 3.1 — 系统托盘(System Tray)集成
改动文件:ui/pet_window.py
新增功能:
QSystemTrayIcon在窗口初始化时一并创建- 托盘菜单包含所有主要功能的快捷入口
- 双击托盘图标显示/隐藏主窗口
- 托盘图标右键菜单完整替代右键菜单功能
托盘菜单结构:
🐤 显示/隐藏窗口
───────────────────
🎭 情绪状态 → 😸 Happy / 😼 Focused / 😾 Annoyed / 😺 Sleepy / 🐱 Idle
🧪 测试功能 → 💧 喝水提醒 / 🦵 伸展提醒 / 💬 互动测试
───────────────────
⚙️ 设置
🔔 健康统计
───────────────────
ℹ️ 关于 → EzVibe v2.0
───────────────────
❌ 退出
关键代码(_init_tray):
def _init_tray(self):
try:
self._tray = self._QtWidgets.QSystemTrayIcon(self)
self._tray.setToolTip("EzVibe 桌宠")
self._tray.setContextMenu(self._build_tray_menu())
self._tray.activated.connect(self._on_tray_activated)
try:
self._tray.setVisible(True)
except Exception:
pass
except Exception:
self._tray = None
关键代码(_build_tray_menu):
def _build_tray_menu(self):
menu = self._QtWidgets.QMenu()
menu.setStyleSheet(
"QMenu { background: rgba(255,255,255,250); border-radius: 8px; "
"font-size: 13px; }"
"QMenu::item:selected { background: rgba(74,144,217,50); }"
)
# ... 菜单项 ...
return menu
Phase 3.2 — 设置对话框(Settings Dialog)
改动文件:ui/pet_window.py
新增内部类:
class _SettingsDialog:
"""设置对话框:LLM后端、提醒间隔、显示模式等"""
def __init__(self, parent, QtWidgets, QtCore):
self._parent = parent
self._dialog = QtWidgets.QDialog(parent)
self._dialog.setWindowTitle("⚙️ EzVibe 设置")
self._dialog.setFixedSize(360, 280)
self._build_ui()
def _build_ui(self):
# LLM 后端选择(下拉框)
self._llm_combo = QtWidgets.QComboBox()
# 提醒间隔(SpinBox,10-300秒)
self._interval_spin = QtWidgets.QSpinBox()
# 显示模式(NORMAL / QUIET / AGGRESSIVE)
self._mode_combo = QtWidgets.QComboBox()
# 窗口透明度(Slider 50%-100%)
self._opacity_slider = QtWidgets.QSlider(Qt.Orientation.Horizontal)
def _on_save(self):
opacity = self._opacity_slider.value() / 100.0
self._parent.set_opacity(opacity)
self._dialog.close()
入口方法:
def _show_settings(self):
dialog = self._SettingsDialog(self, self._QtWidgets, self._QtCore)
dialog.exec()
Phase 3.3 — 健康统计对话框(Health Stats Dialog)
改动文件:ui/pet_window.py
新增内部类:
class _HealthStatsDialog:
"""健康统计对话框:显示今日/本周健康数据"""
def __init__(self, parent, QtWidgets, QtCore):
self._parent = parent
self._dialog = QtWidgets.QDialog(parent)
self._dialog.setWindowTitle("🔔 健康统计")
self._dialog.setFixedSize(320, 240)
self._build_ui()
def _build_ui(self):
# 标题:📊 今日健康概览
# 喝水次数 / 伸展次数 / 静坐时长 / 连续站立
# 关闭按钮
入口方法:
def _show_health_stats(self):
dialog = self._HealthStatsDialog(self, self._QtWidgets, self._QtCore)
dialog.exec()
Phase 3.4 — 托盘退出与窗口联动
改动文件:ui/pet_window.py
新增方法:
def _quit_app(self):
"""退出应用"""
self._running = False
self.close()
self._QtWidgets.QApplication.instance().quit()
def _toggle_window(self):
"""切换窗口显示/隐藏"""
if self.isVisible():
self.hide()
self._show_action.setText("🐤 显示窗口")
else:
self.show()
self.activateWindow()
self._show_action.setText("🐤 隐藏窗口")
文件变更清单
| 文件 | 变更类型 | 对应 Phase |
|---|---|---|
| ui/pet_window.py | 修改 | 3.1, 3.2, 3.3, 3.4 |
运行命令
# 使用 conda ai 环境
conda activate ai
# 完整 GUI 模式(含系统托盘)
/home/e2hang/miniforge3/envs/ai/bin/python main.py
# Dummy 模式(无 GUI / 无托盘)
/home/e2hang/miniforge3/envs/ai/bin/python main.py --dummy