Files
EzVibe/docs/v5_modify/README.md
e2hang 96cb28fe08 feat: multi-layer eventFilter for window drag + text input fix + Qt platform xcb
- 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>
2026-05-19 23:36:58 +08:00

131 lines
3.9 KiB
Markdown
Raw Permalink 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.
# v5_modify — 窗口拖拽与文本输入修复
## 故障描述
1. **窗口无法拖动**:鼠标左键点击并拖动窗口区域时,窗口不跟随移动。
2. **聊天输入框无法输入文字**:在输入框中点击后无法输入文字。
## 环境
- 平台Linux (Fedora 40)
- Qt 平台xcbWayland 下存在鼠标事件兼容性问题)
- Python3.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)` 始终没有触发
**问题 CWayland vs X11 平台差异**
`QT_QPA_PLATFORM=wayland` 时 Qt 的鼠标事件分发机制与 `xcb` 不同,导致事件冒泡行为不一致。`xcb` 平台下事件能正常到达过滤器。
### 修复方案
**1. 修复 `eventFilter` 中的 `super()` 调用**
```python
# 错误 ❌
return super().eventFilter(obj, event)
# 正确 ✅
return self._QtWidgets.QMainWindow.eventFilter(self, obj, event)
```
**2. 多层事件过滤器安装**
在三个层级同时安装事件过滤器:
```python
# _init_ui 中
live2d_container.installEventFilter(self) # Live2D 容器
central.installEventFilter(self) # 中央部件
# _init_live2d 中
self._live2d_widget.installEventFilter(self) # Live2D WebEngineView 控件
```
**3. `eventFilter` 中添加 Live2D 控件判断**
```python
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**
```python
# 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 事件属性**
```python
central.setAttribute(self._QtCore.Qt.WidgetAttribute.WA_Hover)
```
---
## 故障 2聊天输入框无法输入
### 根因分析
`_chat_container`(包含输入框的部件)错误地设置了 `WA_TransparentForMouseEvents` 属性,导致鼠标事件穿透该部件,下层的 `live2d_container` 接收到事件并触发拖拽流程,输入框无法获得焦点。
### 修复方案
移除了 `_chat_container` 上的 `WA_TransparentForMouseEvents` 属性,让输入框可以正常接收鼠标事件。
```python
# 已移除此错误设置
# self._chat_container.setAttribute(self._QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents)
```
---
## 修改的文件
| 文件 | 修改内容 |
|------|----------|
| `main.py` | 默认平台改为 `xcb` |
| `ui/pet_window.py` | 事件过滤器多层安装、修复 `super()` 调用、启用 `WA_Hover` |
---
## 验证方法
```bash
/home/e2hang/miniforge3/envs/ezvibe/bin/python3 main.py
```
- ✅ 鼠标左键按住 Live2D 区域或窗口主体可拖动窗口
- ✅ 聊天输入框可正常输入文字
- ✅ 按钮点击正常
- ⚠️ Live2D 渲染在 X11 下可能存在 SSL handshake 警告,不影响功能
---
## 相关技术点
- `QMainWindow.eventFilter()` vs `super().eventFilter()` 在动态类中的差异
- `WA_TransparentForMouseEvents` 与鼠标事件传递
- Qt 平台插件:`xcb` vs `wayland` 的事件分发差异
- 多层事件过滤器覆盖:容器 → 中央部件 → 子控件