Android — Почему мой QGestureRecognizer не получает сенсорные события?

Контекст: я пытаюсь создать фейдер-подобный виджет, который может иметь несколько экземпляров в одном представлении, каждый из которых может управляться одновременно разными пальцами.

Я хочу использовать Qt’s система распознавания жестов, но мне также нужна некоторая функциональность сверх стандарта Qt::PanGesture, С этой целью я подкласс QGesture а также QGestureRecognizer, В FooGestureRecognizer::recognize(...)Я перехватываю оба QMouseEventс и QTouchEventс (пока, по крайней мере).

На винде я только получаю QMouseEvents — я справляюсь с ними, и все работает, как и ожидалось (хотя, очевидно, мне не приходится сталкиваться с проблемой мультитача, когда мой ввод осуществляется с физической мыши). События, которые я получаю (по порядку):

  • QEvent::MouseButtonPress
  • Строка QEvent::MouseMoves
  • QEvent::MouseButtonRelease

На Android я получаю странную смесь QMouseEventс и QTouchEvents (по порядку):

  • 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с из TouchEvents, почему я вижу, я вижу QEvent::MouseMove а также QEvent::MouseButtonRelease но нет QEvent::TouchUpdate или же QEvent::TouchRelease?

Код доступен, но в интересах краткости я не включил его здесь. Пожалуйста, спросите, если это необходимо.

3

Решение

От 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) на каждый действительный * Target что приходит через FooGestureRecognizer::create(),

возврате true от eventFilter сообщает Qt, что мой фейдер заинтересован в получении дальнейших событий касания, и эти события касания доставляются в ожидаемую форму распознавателю жестов.

Это решение похоже на взлом, и оно может не понадобиться в будущих версиях Qt, поэтому я буду следить за этим кодом.

Заметки:

  • Во время строительства QGestureRecognizer, create() вызывается с нулем Target (ожидая манекена QGesture быть возвращенным). Следите за этим, если вы устанавливаете фильтры событий на все Targets.
  • Мое приложение должно обрабатывать события мыши на рабочем столе одним способом, а события касания несколькими пальцами — другим, поэтому я отключил Qt::AA_SynthesizeMouseForUnhandledTouchEvents, Включение этого параметра может привести к другим соображениям (например, я не уверен, что вам нужно return true для всех сенсорных событий в eventFilter, чтобы избежать их дублирования как синтезированных событий мыши).
2

Другие решения


По вопросам рекламы [email protected]