- 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>
v5_modify — 窗口拖拽与文本输入修复
故障描述
- 窗口无法拖动:鼠标左键点击并拖动窗口区域时,窗口不跟随移动。
- 聊天输入框无法输入文字:在输入框中点击后无法输入文字。
环境
- 平台:Linux (Fedora 40)
- Qt 平台:xcb(Wayland 下存在鼠标事件兼容性问题)
- Python:3.13 + PySide6
- 桌宠窗口:无边框、置顶、Tool 类型
故障 1:窗口拖动失效
根因分析
问题 A:super() 在动态类中调用失败
PetWindow 使用 type() 动态创建,eventFilter 方法中调用 super().eventFilter() 在 PySide6 中会导致 SystemError 或属性错误。
问题 B:鼠标事件未到达事件过滤器
WA_TransparentForMouseEvents属性使QWebEngineView将鼠标事件传递给下层窗口- 但
QWebEngineView本身没有安装事件过滤器,所以即使live2d_container安装了过滤器,WebEngineView仍然先接收并处理了MouseButtonPress事件 - 事件类型
68 (ChildAdded)和69 (ChildPolished)能到达过滤器,但MouseButtonPress (2)始终没有触发
问题 C:Wayland vs X11 平台差异
QT_QPA_PLATFORM=wayland 时 Qt 的鼠标事件分发机制与 xcb 不同,导致事件冒泡行为不一致。xcb 平台下事件能正常到达过滤器。
修复方案
1. 修复 eventFilter 中的 super() 调用
# 错误 ❌
return super().eventFilter(obj, event)
# 正确 ✅
return self._QtWidgets.QMainWindow.eventFilter(self, obj, event)
2. 多层事件过滤器安装
在三个层级同时安装事件过滤器:
# _init_ui 中
live2d_container.installEventFilter(self) # Live2D 容器
central.installEventFilter(self) # 中央部件
# _init_live2d 中
self._live2d_widget.installEventFilter(self) # Live2D WebEngineView 控件
3. eventFilter 中添加 Live2D 控件判断
is_live2d_target = (hasattr(self, '_live2d_widget')
and self._live2d_widget is not None
and obj == self._live2d_widget)
if obj != live2d_container and obj != self.centralWidget() and not is_live2d_target:
return self._QtWidgets.QMainWindow.eventFilter(self, obj, event)
4. Qt 平台强制使用 xcb
# main.py
if sys.platform.startswith("linux") and os.environ.get("QT_QPA_PLATFORM") is None:
os.environ["QT_QPA_PLATFORM"] = "xcb" # 而非 wayland
5. 启用 Hover 事件属性
central.setAttribute(self._QtCore.Qt.WidgetAttribute.WA_Hover)
故障 2:聊天输入框无法输入
根因分析
_chat_container(包含输入框的部件)错误地设置了 WA_TransparentForMouseEvents 属性,导致鼠标事件穿透该部件,下层的 live2d_container 接收到事件并触发拖拽流程,输入框无法获得焦点。
修复方案
移除了 _chat_container 上的 WA_TransparentForMouseEvents 属性,让输入框可以正常接收鼠标事件。
# 已移除此错误设置
# self._chat_container.setAttribute(self._QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents)
修改的文件
| 文件 | 修改内容 |
|---|---|
main.py |
默认平台改为 xcb |
ui/pet_window.py |
事件过滤器多层安装、修复 super() 调用、启用 WA_Hover |
验证方法
/home/e2hang/miniforge3/envs/ezvibe/bin/python3 main.py
- ✅ 鼠标左键按住 Live2D 区域或窗口主体可拖动窗口
- ✅ 聊天输入框可正常输入文字
- ✅ 按钮点击正常
- ⚠️ Live2D 渲染在 X11 下可能存在 SSL handshake 警告,不影响功能
相关技术点
QMainWindow.eventFilter()vssuper().eventFilter()在动态类中的差异WA_TransparentForMouseEvents与鼠标事件传递- Qt 平台插件:
xcbvswayland的事件分发差异 - 多层事件过滤器覆盖:容器 → 中央部件 → 子控件