项目中遇到触摸屏上 ,手长按自定义控件,MousePresssEvent 和 MouseReleaseEvent事件几乎同时触发,无法达到鼠标长按的效果,通过添加日志,QT触摸屏上TouchEvent 和 MouseEvent触发的顺序
/*
* QT触摸屏上TouchEvent 和 MouseEvent触发的顺序
* TouchBegin -» TouchEnd -» MouseButtonPress -» MouseButtonRelease
* MouseButtonPress 和 MouseButtonRelease 同时触发。所以触摸屏上无法触发鼠标长按事件
*/
要实现鼠标长按的效果,需要单独处理TouchBegin 和 TouchEnd事件
项目中用的是qt4.8版本,qt5和qt6版本未验证
但是翻看qt4.8.6的源码,按照代码理解,正常的事件触发顺序应该是
TouchBegin -» MouseButtonPress -» TouchEnd -» MouseButtonRelease
bool QWidget::event(QEvent *event)
{
Q_D(QWidget);
//这里忽略一些不相关的代码
//...
switch (event->type()) {
case QEvent::MouseButtonPress:
// Don't reset input context here. Whether reset or not is
// a responsibility of input method. reset() will be
// called by mouseHandler() of input method if necessary
// via mousePressEvent() of text widgets.
#if 0
resetInputContext();
#endif
mousePressEvent((QMouseEvent*)event);
break;
case QEvent::MouseButtonRelease:
mouseReleaseEvent((QMouseEvent*)event);
break;
//...
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
{
#ifndef Q_WS_MAC
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad)
break;
// fake a mouse event!
QEvent::Type eventType = QEvent::None;
switch (touchEvent->type()) {
case QEvent::TouchBegin:
eventType = QEvent::MouseButtonPress;
break;
case QEvent::TouchUpdate:
eventType = QEvent::MouseMove;
break;
case QEvent::TouchEnd:
eventType = QEvent::MouseButtonRelease;
break;
default:
Q_ASSERT(!true);
break;
}
if (eventType == QEvent::None)
break;
//这里应该回到上面的 QEvent::MouseButtonPress 和 QEvent::MouseButtonRelease的case里了,但日志打出来并不是这样
QMouseEvent mouseEvent(eventType,
touchPoint.pos().toPoint(),
touchPoint.screenPos().toPoint(),
Qt::LeftButton,
Qt::LeftButton,
touchEvent->modifiers());
(void) QApplication::sendEvent(this, &mouseEvent);
#endif // Q_WS_MAC
break;
}
//...
}
造成理论和实际结果不一致的原因,还没有追踪到,后面继续追踪补充
在QT4.8项目中,触摸屏的TouchEvent与MouseEvent触发顺序出现异常,导致TouchBegin和TouchEnd后,MousePresssEvent和MouseReleaseEvent几乎同时触发,无法实现长按效果。正常顺序应为TouchBegin -> MouseButtonPress -> TouchEnd -> MouseButtonRelease。为解决长按问题,需单独处理TouchBegin和TouchEnd事件。
1万+

被折叠的 条评论
为什么被折叠?



