Qt WidgetsでQTapAndHoldGesture::positionとQGraphicsScene::mousePressEventを使い分ける極意


QTapAndHoldGesture::positionは、Qt WidgetsライブラリにおけるQTapAndHoldGestureクラスの重要なプロパティです。これは、ユーザーがウィジェットを長押ししたときのタッチ位置を表すQPointF型の値を返します。この情報は、長押しジェスチャの処理や、ジェスチャが発生した場所に基づいたアクションの実行に使用できます。

詳細

QTapAndHoldGesture::positionは、長押しジェスチャが開始された時点でのタッチ位置を保持します。この情報は、ジェスチャの開始位置を正確に特定する必要がある場合に役立ちます。

このプロパティは、QTapAndHoldGestureオブジェクトに対して読み取り専用としてアクセスできます。つまり、このプロパティの値を変更することはできません。

QTapAndHoldGesture *gesture = new QTapAndHoldGesture(widget);
connect(gesture, &QTapAndHoldGesture::stateChanged, this, &MyClass::onStateChanged);

void MyClass::onStateChanged(QGesture::State state)
{
    if (state == QGesture::Accepted) {
        QPointF position = gesture->position();
        // 長押しジェスチャが開始された場所に基づいてアクションを実行する
    }
}

この例では、QTapAndHoldGestureオブジェクトが作成され、widgetにインストールされています。stateChangedシグナルは、ジェスチャの状態が変化したときにonStateChangedスロットを呼び出すように接続されています。

onStateChangedスロットでは、ジェスチャの状態がQGesture::Acceptedであるかどうかを確認します。これは、ジェスチャが認識され、長押しジェスチャとして確定したことを意味します。

次に、gesture->position()を使用して、長押しジェスチャが開始された場所を取得します。この情報は、ジェスチャが発生した場所に基づいてアクションを実行するために使用できます。

  • ジェスチャが認識されない場合、QTapAndHoldGesture::positionは未定義の値を返します。


#include <QApplication>
#include <QLabel>
#include <QTapAndHoldGesture>

class MyWidget : public QLabel {
public:
    MyWidget(QWidget *parent = nullptr);

protected:
    void mousePressEvent(QMouseEvent *event) override;
};

MyWidget::MyWidget(QWidget *parent) : QLabel(parent) {
    setText("Click and hold me");
    setAlignment(Qt::AlignCenter);

    QTapAndHoldGesture *gesture = new QTapAndHoldGesture(this);
    connect(gesture, &QTapAndHoldGesture::stateChanged, this, &MyWidget::onStateChanged);
}

void MyWidget::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        event->ignore();
    }
}

void MyWidget::onStateChanged(QGesture::State state)
{
    if (state == QGesture::Accepted) {
        QPointF position = gesture->position();

        // ジェスチャが発生した場所に基づいてウィジェットの色を変更する
        if (position.x() < width() / 2) {
            setStyleSheet("background-color: red;");
        } else {
            setStyleSheet("background-color: green;");
        }
    }
}

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

    MyWidget widget;
    widget.show();

    return app.exec();
}

このコードでは、MyWidgetという名前のラベルを作成しています。このラベルには、"Click and hold me"というテキストが表示されます。

QTapAndHoldGestureオブジェクトがラベルにインストールされ、stateChangedシグナルがonStateChangedスロットに接続されています。

次に、gesture->position()を使用して、長押しジェスチャが開始された場所を取得します。この情報は、ウィジェットの色を赤または緑に変更するために使用されます。

ウィジェットの色は、ジェスチャが発生した場所によって異なります。ジェスチャがウィジェットの左側で開始された場合は、ウィジェットの色は赤になります。ジェスチャがウィジェットの右側で開始された場合は、ウィジェットの色は緑になります。



QGestureEvent::pos()

QGestureEvent::pos()は、ジェスチャイベントが発生した場所を表すQPointF型の値を返します。これは、QTapAndHoldGestureだけでなく、他のジェスチャタイプにも使用できます。

利点

  • さまざまなジェスチャタイプで使用できる
  • 汎用性が高い

欠点

  • ジェスチャが開始された場所を正確に特定できない場合があります。これは、ジェスチャが移動している場合や、複数のタッチポイントがある場合に発生する可能性があります。


connect(gesture, &QTapAndHoldGesture::stateChanged, this, &MyClass::onStateChanged);

void MyClass::onStateChanged(QGesture::State state)
{
    if (state == QGesture::Accepted) {
        QGestureEvent *event = gesture->currentEvent();
        QPointF position = event->pos();

        // ジェスチャが発生した場所に基づいてアクションを実行する
    }
}

QGraphicsScene::mousePressEvent()

QGraphicsScene::mousePressEvent()は、マウスボタンが押されたときに呼び出される仮想関数です。この関数は、イベントが発生した場所を表すQPointF型の値をパラメータとして渡されます。

利点

  • グラフィックスシーン内の長押しジェスチャを検出するのに役立ちます

欠点

  • Qt Widgetsライブラリの一部ではないため、使用するには追加のセットアップが必要になる場合があります。


QGraphicsScene scene;
QGraphicsView view(&scene);

scene.addItem(new QLabel("Click and hold me"));

QTapAndHoldGesture *gesture = new QTapAndHoldGesture(&scene);
connect(gesture, &QTapAndHoldGesture::stateChanged, this, &MyClass::onStateChanged);

view.show();

カスタムジェスチャクラス

独自のジェスチャクラスを作成することもできます。この方法は、特定のニーズに合わせたジェスチャの動作を制御する必要がある場合に役立ちます。

利点

  • 特定のニーズに合わせたジェスチャの動作を制御できる
  • 柔軟性が高い

欠点

  • 複雑で時間のかかる作業になる可能性があります
class MyTapAndHoldGesture : public QGesture
{
public:
    MyTapAndHoldGesture(QObject *parent = nullptr);

    QPointF position() const;

protected:
    void stateChanged(QGesture::State state);

private:
    QPointF m_position;
};

MyTapAndHoldGesture::MyTapAndHoldGesture(QObject *parent) : QGesture(parent)
{
    m_position = QPointF();
}

QPointF MyTapAndHoldGesture::position() const
{
    return m_position;
}

void MyTapAndHoldGesture::stateChanged(QGesture::State state)
{
    if (state == QGesture::Accepted) {
        // ジェスチャが開始された場所を保存する
        m_position = QGestureEvent::pos();
    }
}