# v5_modify — 窗口拖拽与文本输入修复 ## 故障描述 1. **窗口无法拖动**:鼠标左键点击并拖动窗口区域时,窗口不跟随移动。 2. **聊天输入框无法输入文字**:在输入框中点击后无法输入文字。 ## 环境 - 平台: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()` 调用** ```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` 的事件分发差异 - 多层事件过滤器覆盖:容器 → 中央部件 → 子控件