Why does my QGestureRecognizer not receive Touch Events?

送分小仙女□ 提交于 2019-12-12 11:34:19

问题


Context: I'm trying to create a fader-like widget that can have multiple instances in the same view, each of which can be controlled simultaneously by different fingers.

I want to use Qt's gesture recognition system, but I also need some functionality above and beyond the standard Qt::PanGesture. To this end, I've subclassed both QGesture and QGestureRecognizer. In FooGestureRecognizer::recognize(...), I'm currently intercepting both QMouseEvents and QTouchEvents (for the time being, at least).

On Windows I only receive QMouseEvents - I handle them and everything works as expected (though obviously I don't have to deal with the multitouch problem when my input is from a physical mouse). The events I receive (in order):

  • QEvent::MouseButtonPress
  • A string of QEvent::MouseMoves
  • QEvent::MouseButtonRelease

On Android, I receive a strange mix of QMouseEvents and QTouchEvents (in order):

  • QEvent::TouchBegin
  • QEvent::MouseButtonPress
  • QEvent::MouseMove (with no actual change in position)
  • Another QEvent::MouseButtonPress (not sure why I needed another one)
  • My actual string of QEvent::MouseMoves, as expected
  • QEvent::MouseButtonRelease

The global attribute Qt::AA_SynthesizeMouseForUnhandledTouchEvents is true by default. Turning it off changes the events I receive to:

  • QEvent::TouchBegin

...nothing else.

Here's a precursor question then: What can I do inside QGestureRecognizer::recognize() to tell Qt that I'm handling the QEvent::TouchBegin, and that it doesn't need to synthesize a QEvent::MouseButtonPress for me? event->accept() doesn't appear to make any difference.

The actual question: If (as it appears) Qt is synthesizing MouseEvents from TouchEvents, why do I see I see QEvent::MouseMove and QEvent::MouseButtonRelease but not QEvent::TouchUpdate or QEvent::TouchRelease?

Code is available, but in the interests of conciseness I've not included it here. Please ask if needed.


回答1:


From the QTouchEvent docs:

The QEvent::TouchUpdate and QEvent::TouchEnd events are sent to the widget or item that accepted the QEvent::TouchBegin event. If the QEvent::TouchBegin event is not accepted and not filtered by an event filter, then no further touch events are sent until the next QEvent::TouchBegin.

The root of this problem is that QGestureRecognizer does not accept the initial TouchBegin, and hence we don't receive any further touch events. I got around this by:

  1. Creating a thin event filter QObject owned by my QGestureRecognizer.

Containing the following code:

bool FooGestureRecognizer::FooEventFilter::eventFilter(QObject *Object, QEvent *Event)
{
  if(Event->type() == QEvent::TouchBegin)
  {
    return true;
  }
  else
  {
    return QObject::eventFilter(Object, Event);
  }
}
  1. Installing my event filter AND calling setAttribute(Qt::WA_AcceptTouchEvents) on every valid* Target that comes through FooGestureRecognizer::create().

Returning true from eventFilter tells Qt that my fader is interested in receiving further touch events, and these touch events are delivered as expected to the gesture recognizer.

This solution feels like a hack, and one that might not be necessary in future versions of Qt, so I'm going to keep an eye on this code.

Notes:

  • During the construction of a QGestureRecognizer, create() is called with a null Target (expecting a dummy QGesture to be returned). Watch out for this if you're installing event filters on all Targets.
  • My application needs to handle desktop mouse events in one way, and multi-finger touch events in another, so I've disabled Qt::AA_SynthesizeMouseForUnhandledTouchEvents. Keeping this enabled may lead to other considerations (e.g. I'm not sure if you'd need to return true for all touch events in eventFilter, so as to avoid them being duplicated as synthesised mouse events).


来源:https://stackoverflow.com/questions/23369431/why-does-my-qgesturerecognizer-not-receive-touch-events

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!