【保存版】Qt Widgets: QGraphicsSceneWheelEvent::phase()でマウスホイールの動きを自由自在に操る


QGraphicsSceneWheelEvent::phase() は、Qt Widgets 6.2 以降で導入された QGraphicsSceneWheelEvent クラスのメソッドで、マウスホイールの回転方向とスクロールフェーズを返します。つまり、ユーザーがマウスホイールをどのように操作したかを判断するために使用できます。



例1: 基本的な使用方法

class MyGraphicsView : public QGraphicsView
{
public:
    void wheelEvent(QWheelEvent* event) override
    {
        if (event->isGraphicsSceneEvent()) {
            QGraphicsSceneWheelEvent* wheelEvent = static_cast<QGraphicsSceneWheelEvent*>(event);

            Qt::ScrollPhase phase = wheelEvent->phase();

            switch (phase) {
            case Qt::ScrollStart:
                qDebug() << "回転開始";
                break;
            case Qt::ScrollUp:
                qDebug() << "上方向に回転";
                break;
            case Qt::ScrollDown:
                qDebug() << "下方向に回転";
                break;
            case Qt::ScrollEnd:
                qDebug() << "回転終了";
                break;
            }
        }
    }
};

例2: 具体的なスクロール量を取得

class MyGraphicsView : public QGraphicsView
{
public:
    void wheelEvent(QWheelEvent* event) override
    {
        if (event->isGraphicsSceneEvent()) {
            QGraphicsSceneWheelEvent* wheelEvent = static_cast<QGraphicsSceneWheelEvent*>(event);

            Qt::ScrollPhase phase = wheelEvent->phase();
            int delta = wheelEvent->delta();

            switch (phase) {
            case Qt::ScrollStart:
                qDebug() << "回転開始";
                break;
            case Qt::ScrollUp:
                qDebug() << "上方向に回転: " << delta;
                break;
            case Qt::ScrollDown:
                qDebug() << "下方向に回転: " << delta;
                break;
            case Qt::ScrollEnd:
                qDebug() << "回転終了";
                break;
            }
        }
    }
};

例3: 複数のホイールを備えたマウスに対応

class MyGraphicsView : public QGraphicsView
{
public:
    void wheelEvent(QWheelEvent* event) override
    {
        if (event->isGraphicsSceneEvent()) {
            QGraphicsSceneWheelEvent* wheelEvent = static_cast<QGraphicsSceneWheelEvent*>(event);

            Qt::ScrollPhase phase = wheelEvent->phase();
            int delta = wheelEvent->delta();
            QInputDevice* device = wheelEvent->device();

            switch (phase) {
            case Qt::ScrollStart:
                qDebug() << "回転開始: デバイス: " << device->description();
                break;
            case Qt::ScrollUp:
                qDebug() << "上方向に回転: デバイス: " << device->description() << ", 量: " << delta;
                break;
            case Qt::ScrollDown:
                qDebug() << "下方向に回転: デバイス: " << device->description() << ", 量: " << delta;
                break;
            case Qt::ScrollEnd:
                qDebug() << "回転終了: デバイス: " << device->description();
                break;
            }
        }
    }
};
  • 各スクロールフェーズに応じて、デバッグメッセージを出力しています。
  • device() メソッドで、イベントが発生したデバイスを取得します。
  • delta() メソッドで、具体的なスクロール量を取得します。
  • phase() メソッドで、スクロールフェーズを取得します。
  • static_cast<QGraphicsSceneWheelEvent*>(event) で、イベントを QGraphicsSceneWheelEvent 型にキャストします。
  • event->isGraphicsSceneEvent() で、イベントが QGraphicsSceneWheelEvent かどうかを確認します。
  • wheelEvent() メソッドは、マウスホイールイベントが発生したときに呼び出されます。
  • 上記の例では、MyGraphicsView クラスを定義しています。
  • 例えば、上方向に回転した場合はビューをズームインし、下方向に回転した場合はビューをズームアウトするなど。
  • 実際のアプリケーションでは、取得した情報に応じて、適切な処理を実行する必要があります。


以下に、いくつかの代替方法を紹介します。

QWheelEvent::delta() を使用する

QGraphicsSceneWheelEventQWheelEvent から派生しているため、delta() メソッドを使用してホイールの回転量を取得できます。ただし、この方法はスクロールフェーズを直接提供しないため、回転方向を判断するには追加の処理が必要になります。

void wheelEvent(QWheelEvent* event) override
{
    if (event->isGraphicsSceneEvent()) {
        QGraphicsSceneWheelEvent* wheelEvent = static_cast<QGraphicsSceneWheelEvent*>(event);

        int delta = wheelEvent->delta();

        // 回転方向を判断する処理
        if (delta > 0) {
            // 上方向に回転
        } else if (delta < 0) {
            // 下方向に回転
        }
    }
}

QMouseEvent::modifiers() を使用する

QMouseEvent::modifiers() メソッドを使用して、ShiftキーやCtrlキーなどの修飾キーの状態を取得できます。この情報を使用して、回転方向を判断できます。ただし、この方法はすべての状況で確実に機能するとは限りません。

void wheelEvent(QWheelEvent* event) override
{
    if (event->isGraphicsSceneEvent()) {
        QGraphicsSceneWheelEvent* wheelEvent = static_cast<QGraphicsSceneWheelEvent*>(event);

        Qt::KeyboardModifiers modifiers = event->modifiers();

        if (modifiers & Qt::ShiftModifier) {
            // Shiftキーが押されている場合は、水平方向にスクロール
        } else {
            // Shiftキーが押されていない場合は、垂直方向にスクロール
            int delta = wheelEvent->delta();

            if (delta > 0) {
                // 上方向に回転
            } else if (delta < 0) {
                // 下方向に回転
            }
        }
    }
}

カスタムイベントを使用する

独自のイベントを作成して、マウスホイールの回転方向とスクロール量を伝達することができます。この方法は、柔軟性が高く、複雑なシナリオにも対応できますが、実装コストが高くなります。

サードパーティのライブラリを使用する

QGraphicsSceneWheelEvent に代わる機能を提供するサードパーティのライブラリが存在する場合があります。これらのライブラリを使用すると、より簡単にスクロール情報を取得できる可能性があります。

最適な代替方法の選択

最適な代替方法は、状況によって異なります。以下の点を考慮する必要があります。

  • 開発者のスキルと経験
  • アプリケーションの要件
  • 使用している Qt のバージョン
  • 具体的な実装は、アプリケーションの要件に合わせて行う必要があります。
  • 上記の代替方法は、あくまでも例であり、すべての状況で適切とは限りません。