ウィジェットとグラフィックス・ビューでのジェスチャ

Qtにはジェスチャー・プログラミングのためのフレームワークがあり、使用される入力メソッドとは別に、一連のイベントからジェスチャーを形成する機能があります。ジェスチャは、マウスの特定の動き、タッチスクリーンの操作、または他のソースからの一連のイベントです。入力の性質、ジェスチャーの解釈、および実行されるアクションは、開発者の自由です。

概要

QGesture は Qt のジェスチャフレームワークの中心的なクラスで、ユーザーによって実行されるジェスチャに関する情報のコンテナを提供します。 は、すべてのジェスチャに共通する一般的な情報を提供するプロパティを公開しており、これらを拡張してジェスチャ固有の情報を追加できます。一般的なパン、ピンチ、スワイプのジェスチャは、専用のクラスで表されます: および 。QGesture QPanGesture QPinchGesture QSwipeGesture

開発者は、QGestureRecognizer クラスをサブクラス化して拡張することで、新しいジェスチャを実装することもできます。新しいジェスチャのサポートを追加するには、入力イベントからジェスチャを認識するコードを実装します。これについては、「独自のジェスチャー認識機能を作成する」のセクションで説明します。

ウィジェットで標準ジェスチャーを使用する

ジェスチャーは、QWidgetQGraphicsObject のサブクラスのインスタンスに対して有効にすることができます。ジェスチャ入力を受け付けるオブジェクトは、このドキュメント全体を通してターゲットオブジェクトと呼ばれます。

ターゲット・オブジェクトのジェスチャを有効にするには、必要なジェスチャ・タイプを記述する引数を指定してQWidget::grabGesture() またはQGraphicsObject::grabGesture() 関数を呼び出します。標準のタイプはQt::GestureType enum で定義され、一般的に使用されるジェスチャが多く含まれています。

for (Qt::GestureType gesture : gestures)
    grabGesture(gesture);

上記のコードでは、ジェスチャはターゲット・オブジェクト自体のコンストラクタで設定されます。

イベントの処理

ユーザがジェスチャを実行すると、QGestureEvent イベントがターゲット・オブジェクトに配信されます。これらのイベントは、ウィジェット用のQWidget::event() ハンドラ関数、またはグラフィック・オブジェクト用のQGraphicsItem::sceneEvent() ハンドラ関数を再実装することで処理できます。

1つのターゲット・オブジェクトが複数のジェスチャ・タイプをサブスクライブできるため、QGestureEvent は複数のQGesture を含むことができます。その場合、これらの複数のジェスチャをどのように処理するかはウィジェット次第であり、あるジェスチャをキャンセルして他のジェスチャを優先するかどうかを選択します。

QGestureEvent オブジェクトに含まれる各QGesture は、個別に accept()または ignore()することも、まとめてすることもできます。さらに、いくつかのゲッターを使用して、個々のQGesture データ・オブジェクト(ステート)を照会できます。

イベント処理の標準手順

QGesture がウィジェットに到着すると、デフォルトで受け付けられます。しかし、常に明示的にジェスチャを受け入れるか拒否することは良い習慣です。一般的なルールは、ジェスチャを受け入れると、それを使用していることになります。無視する場合は、そのジェスチャに興味がありません。ジェスチャーを無視すると、他のターゲットにジェスチャーが提供されたり、ジェスチャーがキャンセルされたりします。

QGesture には、それを通過するいくつかの状態があります。状態を変更する方法は明確に定義されており、通常はユーザー入力が状態変更の原因ですが(たとえば、インタラクションの開始と停止によって)、ウィジェットも状態変更を引き起こすことができます。

特定のQGesture が初めてウィジェットまたはグラフィックアイテムに配信されると、Qt::GestureStarted 状態になります。この時点でのジェスチャの処理方法は、後でそのジェスチャと対話できるかどうかに影響します。

  • ジェスチャを受け入れることは、ウィジェットがジェスチャに対応し、Qt::GestureUpdatedstate を持つジェスチャが続くことを意味します。
  • ジェスチャを無視すると、ジェスチャは二度と提供されません。ジェスチャは、親ウィジェットやアイテムにも提供されます。
  • ジェスチャが開始状態にあり、かつ受け入れられているときに、ジェスチャに対して setGestureCancelPolicy() を呼び出すと、他のジェスチャがキャンセルされることがあります。

QGesture::CancelAllInContext を使用してジェスチャをキャンセルすると、明示的に受け入れられていない限り、どの状態でもすべてのジェスチャがキャンセルされます。これは、子に対するアクティブなジェスチャがキャンセルされることを意味します。また、同じQGestureEvent で配信されたジェスチャも、ウィジェットが無視するとキャンセルされます。これは、興味のあるジェスチャ以外のすべてのジェスチャをフィルタリングする便利な方法です。

イベント処理の例

便宜上、Image Gestures Exampleでは、一般的なevent() ハンドラ関数を再実装し、ジェスチャ・イベントを専用の gestureEvent() 関数に委譲しています:

bool ImageWidget::event(QEvent *event)
{
    if (event->type() == QEvent::Gesture)
        return gestureEvent(static_cast<QGestureEvent*>(event));
    return QWidget::event(event);
}

ターゲット・オブジェクトに配信されたジェスチャ・イベントは、個別に調べて適切に処理できます:

bool ImageWidget::gestureEvent(QGestureEvent *event)
{
    qCDebug(lcExample) << "gestureEvent():" << event;
    if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
        swipeTriggered(static_cast<QSwipeGesture *>(swipe));
    else if (QGesture *pan = event->gesture(Qt::PanGesture))
        panTriggered(static_cast<QPanGesture *>(pan));
    if (QGesture *pinch = event->gesture(Qt::PinchGesture))
        pinchTriggered(static_cast<QPinchGesture *>(pinch));
    return true;
}

ジェスチャーに応答するには、ターゲット・オブジェクトに送信されたQGestureEvent で配信されたQGesture オブジェクトを取得し、そのオブジェクトに含まれる情報を調べるだけです。

void ImageWidget::swipeTriggered(QSwipeGesture *gesture)
{
    if (gesture->state() == Qt::GestureFinished) {
        if (gesture->horizontalDirection() == QSwipeGesture::Left
            || gesture->verticalDirection() == QSwipeGesture::Up) {
            qCDebug(lcExample) << "swipeTriggered(): swipe to previous";
            goPrevImage();
        } else {
            qCDebug(lcExample) << "swipeTriggered(): swipe to next";
            goNextImage();
        }
        update();
    }
}

ここでは、ユーザーがウィジェットをスワイプした方向を調べ、それに応じてウィジェットの内容を変更します。

独自のジェスチャー・レコグナイザを作成する

新しいジェスチャのサポートを追加するには、新しいジェスチャ・レコグナイザを作成して登録します。ジェスチャの認識プロセスによっては、新しいジェスチャ・オブジェクトの作成も必要になります。

新しいレコグナイザを作成するには、QGestureRecognizer をサブクラス化してカスタムレコグナイザクラスを作成する必要があります。再実装が必要な仮想関数が1つと、必要に応じて再実装できる他の関数が2つあります。

入力イベントのフィルタリング

recognize() 関数を再実装する必要があります。この関数は、ターゲット・オブジェクトの入力イベントを処理し、フィルタリングして、レコグナイザが探しているジェスチャーに対応しているかどうかを判断します。

QGesture ジェスチャー認識のロジックはこの関数に実装されていますが、おそらくQt::GestureState enums に基づいたステートマシンを使用しています。

recognize() 関数は、指定されたジェスチャとターゲット オブジェクトの認識状態を示すQGestureRecognizer::Result の値を返す必要があります。これにより、ジェスチャ・イベントがターゲット・オブジェクトに配信されるかどうかが決まります。

カスタム・ジェスチャ

カスタムのQGesture サブクラスでジェスチャを表現する場合は、標準のQGesture インスタンスではなく、create() 関数を再実装してジェスチャ・クラスのインスタンスを作成する必要があります。あるいは、標準のQGesture インスタンスを使用することもできますが、処理したいジェスチャの特定の詳細を表現するために、インスタンスに追加の動的プロパティを追加します。

ジェスチャのリセット

ジェスチャがキャンセルされたときにリセットまたはその他の特別な処理が必要なカスタム・ジェスチャ・オブジェクトを使用する場合は、これらの特別なタスクを実行するためにreset() 関数を再実装する必要があります。

QGesture オブジェクトは、ターゲット・オブジェクトとジェスチャ・タイプの組み合わせごとに 1 回だけ作成され、ユーザがターゲット・オブジェクトに対して同じジェスチャ・タイプを実行しようとするたびに再使用される可能性があることに注意してください。そのため、reset ()関数を再実装して、以前にジェスチャを認識しようとしたたびにクリーンアップすると便利です。

新しいジェスチャ認識機能の使用

ジェスチャー認識機能を使用するには、QGestureRecognizer サブクラスのインスタンスを作成し、QGestureRecognizer::registerRecognizer() でアプリケーションに登録します。指定したタイプのジェスチャの認識機能は、QGestureRecognizer::unregisterRecognizer() で削除できます。

その他の情報

画像ジェスチャの例では、簡単な画像ビューアアプリケーションでウィジェットのジェスチャを有効にする方法を示しています。

Qt Quick におけるジェスチャ

Qt Quick には、一般的なグローバル・ジェスチャー認識機能はありません。たとえば、PinchArea は 2 本指のジェスチャを処理し、Flickable は 1 本指でコンテンツをフリックします。MultiPointTouchArea は任意の数のタッチポイントを処理でき、アプリケーション開発者はカスタムのジェスチャ認識コードを記述できます。

©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。