QTest中QPlainTextEdit右键/中键鼠标事件不被接受问题求助
QPlainTextEdit单元测试中右键/中键点击事件不被接受的问题
问题现象
子类化(或直接使用原生)QPlainTextEdit且未重写鼠标相关事件时,在Qt 5.15.2的单元测试中:
- 模拟左键点击,光标可正常移动到目标位置,无异常提示
- 模拟右键或中键点击同一位置,控制台输出以下警告:
Mouse event "MousePress" not accepted by receiving widget
Mouse event "MouseRelease" not accepted by receiving widget
同时重写mousePressEvent/mouseReleaseEvent后,发现这些函数并未被调用,控件完全接收不到右键/中键事件。
测试代码如下:
widget->setMouseTracking(true); widget->setFocus(); QCoreApplication::processEvents(); QTest::qWait(1000); // 测试用等待,确保控件状态稳定 // 左键点击正常,光标移动到目标位置 QTest::mouseClick(widget, Qt::LeftButton, Qt::NoModifier, widget->cursorRect().center()); // 右键点击触发警告,事件不被接受 QTest::mouseClick(widget, Qt::RightButton, Qt::NoModifier, widget->cursorRect().center());
原因分析
QPlainTextEdit继承自QAbstractScrollArea,其文本交互逻辑由内部的viewport()视图组件处理:
- 左键事件会被QPlainTextEdit本身处理(用于移动光标),因此直接发送事件给控件对象可正常响应
- 右键、中键事件的处理逻辑属于内部视图组件,直接向QPlainTextEdit对象发送这类事件时,控件本身不处理该事件,就会返回"未接受"状态,触发警告;同时内部视图也无法收到事件,导致自定义重写的鼠标事件函数不会被调用
解决方法
方法1:向内部视图发送事件
将鼠标事件直接发送给QPlainTextEdit的viewport()组件,而非控件本身:
// 替换原mouseClick调用,改为向viewport发送事件 QTest::mouseClick(widget->viewport(), Qt::RightButton, Qt::NoModifier, widget->cursorRect().center());
事件会被正确传递到负责文本交互的内部视图,既可以触发右键菜单、中键滚动等默认行为,也不会出现事件未被接受的警告。
方法2:通过事件过滤器自定义处理
如果需要自定义右键/中键的行为,可以给viewport()安装事件过滤器,拦截并处理事件:
// 在测试类或控件子类中给viewport安装事件过滤器 widget->viewport()->installEventFilter(this); // 实现eventFilter函数 bool TestClass::eventFilter(QObject *watched, QEvent *event) { if (watched == widget->viewport() && event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); if (mouseEvent->button() == Qt::RightButton) { // 自定义右键点击逻辑 event->accept(); return true; } } return QObject::eventFilter(watched, event); }
这种方式可以在测试中自定义处理右键/中键事件,同时避免事件未被接受的警告。
内容的提问来源于stack exchange,提问作者stackomatiker
相关产品推荐
相关产品推荐

