Спонсор: Intel
Санкт-Петербургский государственный университет
Опубликован: 14.07.2013 | Доступ: свободный | Студентов: 464 / 172 | Длительность: 06:03:00
Специальности: Программист
Лекция 5:

Разработка приложений для планшетных компьютеров

9.9. Сенсорный экран (touchscreen)

Сенсорный экран - универсальное устройство ввода, которое заменило в планшете и клавиатуру, и "мышь". По принципу действия он очень схож с мышью - пользователь прикосновением пальца к экрану указывает на нем точку и задает вид действия. Для ввода текста применяются разного рода экранные клавиатуры, которые являются самостоятельными программными решениями, мы не будем их рассматривать.

Сенсорный экран может быть использован различными способами. Самый простой и частый способ - использовать стандартные виджеты Qt, которые уже адаптированы для работы с сенсорным экраном и программисту не надо ничего специально делать для этого. Этот метод плохо подходит в ситуации, когда пользовательский интерфейс сложный или нестандартный - например, в играх. В этом случае целесообразно перехватывать системные события Qt, относящиеся к сенсорному экрану, и самостоятельно их обрабатывать.

Эти события бывают двух видов - события собственно от сенсорного экрана и события gestures. Gesture (буквально "жест") - это комбинация действий с сенсорным экраном, которые обозначают определенное событие для пользовательского интерфейса. Например, если человек установил два пальца на мультисенсорный экран и развел их в стороны - это соответствует gesture для увеличения масштаба содержимого виджета. Gesture могут быть как встроенные в систему, так и задаваемые программистом. Встроенные gesture служат для унификации опыта пользователя при работе с сенсорным экраном.

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

Наконец, в исключительных случаях возможно работа с сенсорным экраном на уровне его драйвера в ядре MeeGo. Это наиболее сложный и трудоемкий способ и он имеет смысл только в том случае, если у конкретной модели сенсорного экрана есть какие-то необходимые нам возможности, которые не поддерживаются Qt. Необходимо также учитывать проблемы с переносимостью созданной таким образом программы.

Далее мы будем говорить о событиях сенсорного экрана. Для перехвата событий необходимо применить традиционную для Qt схему - создать свой собственный виджет, унаследовав его от какого-нибудь стандартного, и в нем переопределить метод event():

bool MyWidget::event(QEvent *event) {
    if (event->type() == QEvent::SomeEvent) {
        QSomeEvent *e = static_cast<QSomeEvent*>(event);
	     // ...
        e->accept();
        return true;
    }
    return BaseWidget::event(event);
}

В этом фрагменте кода важны четыре момента. Во-первых, нужно выделить только те события, которые нам интересны, не нужно пытаться обработать все события, которые получает виджет. Для этого в начале мы проверяем тип события, в данном случае QEvent::SomeEvent.

Во-вторых, сам по себе базовый класс событий QEvent малоинформативен, после того, как мы определились с типом события, надо привести его к соответствующему типу (в примере QSomeEvent). В Qt для этого рекомендуется использовать static_cast.

В-третьих, после обработки события его следует пометить как обработанное с помощью метода accept() и возврата true.

В-четвертых, все события, которые не были обработаны в новом обработчике, должны быть переданы обработчику базового класса.

Для сенсорного экрана выделены следующие типы событий: QEvent::TouchBegin (начало прикосновения), QEvent::TouchUpdate (продолжение прикосновения), QEvent::TouchEnd (завершение прикосновения). Класс QTouchEvent появился недавно, в Qt 4.6, для поддержки сенсорных экранов и сенсорных площадок (touchpad). Вложенный класс QTouchEvent::TouchPoint описывает точку прикосновения к сенсорному экрану. В QTouchEvent имеется список таких точек - например, если пользователь касается экрана четырьмя пальцами, то в списке будут четыре точки. В простейшем случае достаточно рассматривать первую точку списка. Кроме координат, с каждой точкой ассоциировано ее состояние, для простейшего анализа оно также не важно.

Таким образом, можно выстроить несколько стратегий обработки событий сенсорного экрана. В простейшем случае (клик) достаточно реагировать только на TouchBegin или TouchEnd, в более сложных случаях необходимо анализировать данные в TouchUpdate на лету или накапливать их для последующего анализа при завершении прикосновения.

По умолчанию виджет не получает события от сенсорного экрана. Чтобы начать их получать, необходимо выполнить вызов setAcceptTouchEvents(true). Другая проблема, которая может возникнуть с сенсорным экраном - обработка событий gesture других виджетов может приводить к нежелательным эффектам. В этом случае необходимо также начать получать события желаемых gestures в своем виджете, выполнив, например, grabGesture(Qt::PanGesture), после чего в обработчике событий отмечать эти события как обработанные. Другие виджеты перестанут получать события и нежелательные эффекты прекратятся.

9.10. Выводы

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

Аппаратные особенности рассмотрены с точки зрения их API в Qt, обсуждены типовые способы их использования. Из интересных смежных тем, не отраженных в этом тексте, можно выделить использование и создание gestures, разного рода экранные клавиатуры и их заменители, пользовательские интерфейсы, ориентированные на сенсорные экраны, а также API для подключения новых датчиков.