4

上下文:我正在尝试创建一个类似推子的小部件,它可以在同一个视图中有多个实例,每个实例都可以由不同的手指同时控制。

我想使用Qt的手势识别系统,但我还需要一些超出标准的功能Qt::PanGesture。为此,我对 和 进行了子类QGestureQGestureRecognizer。在FooGestureRecognizer::recognize(...)中,我目前正在拦截QMouseEvents 和QTouchEvents (至少目前是这样)。

在 Windows 上,我只收到QMouseEvents - 我处理它们并且一切都按预期工作(尽管当我的输入来自物理鼠标时,显然我不必处理多点触控问题)。我收到的事件(按顺序):

  • QEvent::MouseButtonPress
  • 一串QEvent::MouseMoves
  • QEvent::MouseButtonRelease

在 Android 上,我收到QMouseEvents 和QTouchEvents 的奇怪组合(按顺序):

  • QEvent::TouchBegin
  • QEvent::MouseButtonPress
  • QEvent::MouseMove(位置没有实际变化)
  • 另一个QEvent::MouseButtonPress(不知道为什么我需要另一个)
  • QEvent::MouseMove正如预期的那样,我的实际字符串
  • QEvent::MouseButtonRelease

全局属性Qt::AA_SynthesizeMouseForUnhandledTouchEventstrue默认的。关闭它会将我收到的事件更改为:

  • QEvent::TouchBegin

...没有其他的。

那么这是一个前置问题:我可以在内部做什么QGestureRecognizer::recognize()来告诉 Qt 我正在处理QEvent::TouchBegin,并且它不需要QEvent::MouseButtonPress为我合成 a ? event->accept()似乎没有任何区别。

实际问题:如果(看起来)Qt 正在MouseEvent从 s 合成 s TouchEvent,为什么我看到 I see QEvent::MouseMoveandQEvent::MouseButtonRelease但没有QEvent::TouchUpdateor QEvent::TouchRelease

代码是可用的,但为了简洁起见,我没有在这里包含它。如果需要请询问。

4

1 回答 1

4

QTouchEvent文档

QEvent::TouchUpdate 和 QEvent::TouchEnd 事件被发送到接受 QEvent::TouchBegin 事件的小部件或项目。如果 QEvent::TouchBegin 事件未被接受且未被事件过滤器过滤,则在下一个 QEvent::TouchBegin 之前不会发送更多触摸事件。

这个问题的根源是QGestureRecognizer不接受初始的TouchBegin,因此我们没有收到任何进一步的触摸事件。我通过以下方式解决了这个问题:

  1. 创建QObject我拥有的瘦事件过滤器QGestureRecognizer

包含以下代码:

bool FooGestureRecognizer::FooEventFilter::eventFilter(QObject *Object, QEvent *Event)
{
  if(Event->type() == QEvent::TouchBegin)
  {
    return true;
  }
  else
  {
    return QObject::eventFilter(Object, Event);
  }
}
  1. 安装我的事件过滤器并调用setAttribute(Qt::WA_AcceptTouchEvents)通过.TargetFooGestureRecognizer::create()

Returning truefromeventFilter告诉 Qt 我的推子有兴趣接收更多的触摸事件,并且这些触摸事件按预期传递给手势识别器。

这个解决方案感觉像是一种 hack,而且在未来的 Qt 版本中可能不需要,所以我将密切关注这段代码。

笔记:

  • 在 a 的构造过程中QGestureRecognizercreate()使用 null 调用Target(期望返回一个虚拟对象QGesture)。如果您在所有Targets 上安装事件过滤器,请注意这一点。
  • 我的应用程序需要以一种方式处理桌面鼠标事件,并以另一种方式处理多指触摸事件,所以我禁用了Qt::AA_SynthesizeMouseForUnhandledTouchEvents. 保持此启用可能会导致其他注意事项(例如,我不确定您是否需要为return true中的所有触摸事件eventFilter,以避免它们被复制为合成鼠标事件)。
于 2014-04-30T15:29:43.837 回答