ワンランク上のQt GUIプログラミング:QEventPoint::pressPositionで実現する高度なユーザーインタラクション


QEventPoint::pressPositionは、Qt GUIライブラリにおいて、マウスやタッチスクリーンなどの入力デバイスが押されたときの位置をピクセル単位で示すプロパティです。これは、ユーザーインタラクションを処理する際に重要な情報となります。

詳細

QEventPoint::pressPositionQPointF 型の値を返し、その x()y() メソッドを使用して、それぞれ水平方向と垂直方向における位置を取得することができます。この情報は、ボタンクリックやドラッグ操作などのイベントを処理するために使用できます。

以下のコードは、ボタンがクリックされたときに、クリック位置をコンソールに出力する例です。

void MyWidget::mousePressEvent(QMouseEvent *event) {
  QEventPoint point(event);
  QPointF pressPosition = point.pressPosition();
  qDebug() << "Clicked at: " << pressPosition.x() << "," << pressPosition.y();
}

このコードでは、mousePressEvent() メソッド内で QEventPoint オブジェクトを作成し、イベントオブジェクトから情報を取得しています。その後、pressPosition() メソッドを使用してクリック位置を取得し、コンソールに出力しています。

QEventPoint::pressPosition は、以下のような様々な用途で使用できます。

  • 独自の入力処理を行う
  • ジェスチャ認識を行う
  • ドラッグ操作の開始位置を記録する
  • QEventPoint オブジェクトは、複数のプロパティを持ち、イベントに関する様々な情報を提供します。
  • QEventPoint オブジェクトは、イベントオブジェクトから生成されます。
  • QEventPoint は、QEvent クラスから派生したクラスです。


ボタンクリック位置の取得と表示

#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QPushButton button("Click Me");
  button.connect(&button, &QPushButton::clicked,
                  [](bool checked) {
                    QEventPoint point(QCursor::pos());
                    QPointF pressPosition = point.pressPosition();
                    qDebug() << "Clicked at: " << pressPosition.x() << "," << pressPosition.y();
                  });

  button.show();
  return app.exec();
}

このコードでは、以下の処理が行われています。

  1. QApplication オブジェクトを作成します。
  2. QPushButton オブジェクトを作成し、"Click Me" というテキストを設定します。
  3. clicked シグナルをスロットに接続します。
  4. スロット内で、QEventPoint オブジェクトを作成し、現在のマウスカーソルの位置を取得します。
  5. pressPosition() メソッドを使用して、クリック位置を取得します。
  6. クリック位置をコンソールに出力します。
  7. QPushButton オブジェクトを表示します。
  8. アプリケーションを実行します。

ドラッグ操作の開始位置の記録

以下のコードは、ドラッグ操作の開始位置を記録する例です。

#include <QApplication>
#include <QLabel>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QLabel label("Drag Me");
  label.setAcceptDrops(true);

  label.installEventFilter([](QObject *obj, QEvent *event) {
    if (event->type() == QEvent::DragEnter) {
      QDragEnterEvent *enterEvent = static_cast<QDragEnterEvent *>(event);
      QEventPoint point(enterEvent->pos());
      QPointF startPosition = point.pressPosition();
      qDebug() << "Drag started at: " << startPosition.x() << "," << startPosition.y();
      return true;
    }
    return QObject::eventFilter(obj, event);
  });

  label.show();
  return app.exec();
}
  1. QApplication オブジェクトを作成します。
  2. QLabel オブジェクトを作成し、"Drag Me" というテキストを設定します。
  3. setAcceptDrops() メソッドを使用して、ドラッグドロップを受け入れるように設定します。
  4. installEventFilter() メソッドを使用して、イベントフィルタをインストールします。
  5. イベントフィルタ内で、QDragEnterEvent を処理します。
  6. pressPosition() メソッドを使用して、ドラッグ開始位置を取得します。
  7. ドラッグ開始位置をコンソールに出力します。
  8. QLabel オブジェクトを表示します。
  9. アプリケーションを実行します。

以下のコードは、ジェスチャ認識を行う例です。

#include <QApplication>
#include <QGestureEvent>
#include <QLabel>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QLabel label("Swipe Me");
  label.setGestureTrackingEnabled(true);

  label.installEventFilter([](QObject *obj, QEvent *event) {
    if (event->type() == QEvent::Gesture) {
      QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
      if (gestureEvent->gestureType() == Qt::TapGesture) {
        qDebug() << "Tap gesture detected!";
      } else if (gestureEvent->gestureType() == Qt::SwipeGesture) {
        QSwipeGesture *swipeGesture = static_cast<QSwipeGesture *>(gestureEvent);
        QGesture::SwipeDirection direction = swipeGesture->swipeDirection();
        switch (direction) {
          case QGesture::Up:
            qDebug() << "Swipe up detected!";
            break;
          case QGesture::Down:
            qDebug() << "Swipe down detected!";
            break;
          case QGesture::Left:
            qDebug() << "Swipe left detected!";
            break;
          case QGesture::Right:
            qDebug() << "Swipe right detected!";
            break;
        }
      }
      return true;
    }
    return QObject::eventFilter(obj, event);
  });

  label.


代替方法

  • globalPos(): この関数は、スクリーン上の絶対的な位置をピクセル単位で返します。複数のウィジェットにまたがるドラッグ操作や、スクリーン上の特定の位置に関連する処理に適しています.
  • localPos(): この関数は、ウィジェット内の相対的な位置をピクセル単位で返します。ドラッグ操作やジェスチャ認識など、ウィジェット内の位置に関連する処理に適しています。
  • QCursor::pos(): この関数は、現在のマウスカーソルの位置をピクセル単位で返します。QEventPoint::pressPositionと同様に、ボタンクリックやドラッグ操作などのイベントを処理するために使用できます。

以下のコードは、QCursor::pos() を使用して、ボタンクリック位置をコンソールに出力する例です。

#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QPushButton button("Click Me");
  button.connect(&button, &QPushButton::clicked,
                  [](bool checked) {
                    QPointF pressPosition = QCursor::pos();
                    qDebug() << "Clicked at: " << pressPosition.x() << "," << pressPosition.y();
                  });

  button.show();
  return app.exec();
}

このコードは、QEventPoint::pressPosition を使用した例とほぼ同じですが、QCursor::pos() を使用してクリック位置を取得しています。

QEventPoint::pressPosition は、マウスやタッチスクリーンなどの入力デバイスが押されたときの位置をピクセル単位で示す便利なプロパティですが、状況によっては代替方法の方が適切な場合があります。上記で紹介した代替方法は、それぞれ異なる用途に適しています。

  • どの方法を使用するかは、具体的な状況によって異なります。
  • localPos()globalPos() は、ウィジェットやスクリーンの座標系に依存するため、QEventPoint::pressPosition とは座標系の解釈が異なる場合があります。
  • QCursor::pos() は、QEventPoint オブジェクトを作成する必要がないため、より軽量な方法です。