Контекст: я пытаюсь создать фейдер-подобный виджет, который может иметь несколько экземпляров в одном представлении, каждый из которых может управляться одновременно разными пальцами.
Я хочу использовать Qt’s система распознавания жестов, но мне также нужна некоторая функциональность сверх стандарта Qt::PanGesture
, С этой целью я подкласс QGesture
а также QGestureRecognizer
, В FooGestureRecognizer::recognize(...)
Я перехватываю оба QMouseEvent
с и QTouchEvent
с (пока, по крайней мере).
На винде я только получаю QMouseEvent
s — я справляюсь с ними, и все работает, как и ожидалось (хотя, очевидно, мне не приходится сталкиваться с проблемой мультитача, когда мой ввод осуществляется с физической мыши). События, которые я получаю (по порядку):
QEvent::MouseButtonPress
QEvent::MouseMove
sQEvent::MouseButtonRelease
На Android я получаю странную смесь QMouseEvent
с и QTouchEvent
s (по порядку):
QEvent::TouchBegin
QEvent::MouseButtonPress
QEvent::MouseMove
(без фактического изменения позиции)QEvent::MouseButtonPress
(не уверен, зачем мне нужен еще один)QEvent::MouseMove
с, как и ожидалосьQEvent::MouseButtonRelease
Глобальный атрибут Qt::AA_SynthesizeMouseForUnhandledTouchEvents
является true
по умолчанию. Отключение меняет события, которые я получаю:
QEvent::TouchBegin
…ничего больше.
Вот вопрос-прекурсор: Что я могу сделать внутри QGestureRecognizer::recognize()
сказать Qt, что я обрабатываю QEvent::TouchBegin
и что ему не нужно синтезировать QEvent::MouseButtonPress
для меня? event->accept()
Похоже, не имеет никакого значения.
Актуальный вопрос: Если (как кажется) Qt синтезирует MouseEvent
с из TouchEvent
s, почему я вижу, я вижу QEvent::MouseMove
а также QEvent::MouseButtonRelease
но нет QEvent::TouchUpdate
или же QEvent::TouchRelease
?
Код доступен, но в интересах краткости я не включил его здесь. Пожалуйста, спросите, если это необходимо.
События QEvent :: TouchUpdate и QEvent :: TouchEnd отправляются виджету или элементу, который принял событие QEvent :: TouchBegin. Если событие QEvent :: TouchBegin не принято и не отфильтровано фильтром событий, дальнейшие события касания не отправляются до следующего QEvent :: TouchBegin.
Корень этой проблемы в том, что QGestureRecognizer
не принимает начальное TouchBegin
и, следовательно, мы не получаем никаких дальнейших событий касания. Я обошел это путем:
QObject
принадлежит моей QGestureRecognizer
,Содержит следующий код:
bool FooGestureRecognizer::FooEventFilter::eventFilter(QObject *Object, QEvent *Event)
{
if(Event->type() == QEvent::TouchBegin)
{
return true;
}
else
{
return QObject::eventFilter(Object, Event);
}
}
setAttribute(Qt::WA_AcceptTouchEvents)
на каждый действительный * Target
что приходит через FooGestureRecognizer::create()
,возврате true
от eventFilter
сообщает Qt, что мой фейдер заинтересован в получении дальнейших событий касания, и эти события касания доставляются в ожидаемую форму распознавателю жестов.
Это решение похоже на взлом, и оно может не понадобиться в будущих версиях Qt, поэтому я буду следить за этим кодом.
Заметки:
QGestureRecognizer
, create()
вызывается с нулем Target
(ожидая манекена QGesture
быть возвращенным). Следите за этим, если вы устанавливаете фильтры событий на все Target
s.Qt::AA_SynthesizeMouseForUnhandledTouchEvents
, Включение этого параметра может привести к другим соображениям (например, я не уверен, что вам нужно return true
для всех сенсорных событий в eventFilter
, чтобы избежать их дублирования как синтезированных событий мыши).