Qt Widgets: マウスホイールでインタラクティブなシーンを実現 - QGraphicsSceneWheelEvent::delta() を使って


QGraphicsSceneWheelEvent::delta()は、Qt Widgetsライブラリにおける重要な関数の一つです。この関数は、グラフィックシーン内でマウスホイールの回転量を取得するために使用されます。具体的には、ホイールが回転された距離を1/8度単位で返します。

詳細

  • 戻り値: 整数型 (1/8度単位のホイール回転量)
    • 正の値: ホイールがユーザーから離れる方向に回転
    • 負の値: ホイールがユーザーに向かって回転
  • 引数: なし
void MyGraphicsView::wheelEvent(QWheelEvent *event)
{
    QGraphicsSceneWheelEvent *sceneWheelEvent = new QGraphicsSceneWheelEvent(*event);
    sceneWheelEvent->applyModifiers(event->modifiers());
    sceneWheelEvent->setPos(event->pos());

    // ホイール回転量を取得
    int delta = sceneWheelEvent->delta();

    // 回転量に基づいて処理を行う
    if (delta > 0) {
        // ホイールがユーザーから離れる方向に回転
        // シーンを拡大する
        scene()->scale(1.1, 1.1);
    } else if (delta < 0) {
        // ホイールがユーザーに向かって回転
        // シーンを縮小する
        scene()->scale(0.9, 0.9);
    }

    delete sceneWheelEvent;
}
  • Qt Widgets 6.2以降では、QGraphicsSceneWheelEvent::pixelDelta()関数を使用して、ホイール回転量をピクセル単位で取得することもできます。これは、高解像度ディスプレイでの使用に適しています。
  • QGraphicsSceneWheelEvent::delta()関数は、ホイール回転の向きだけでなく、回転量も取得できます。これは、シーンの拡大縮小やスクロールなどの操作に役立ちます。


#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>

class MyGraphicsView : public QGraphicsView
{
public:
    MyGraphicsView(QWidget *parent = nullptr) : QGraphicsView(parent) {}

protected:
    void wheelEvent(QWheelEvent *event) override
    {
        QGraphicsSceneWheelEvent *sceneWheelEvent = new QGraphicsSceneWheelEvent(*event);
        sceneWheelEvent->applyModifiers(event->modifiers());
        sceneWheelEvent->setPos(event->pos());

        // ホイール回転量を取得
        int delta = sceneWheelEvent->delta();

        // 回転量に基づいて処理を行う
        if (delta > 0) {
            // ホイールがユーザーから離れる方向に回転
            // シーンを拡大する
            scale(1.1, 1.1);
        } else if (delta < 0) {
            // ホイールがユーザーに向かって回転
            // シーンを縮小する
            scale(0.9, 0.9);
        }

        delete sceneWheelEvent;
    }
};

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

    // シーンを作成
    QGraphicsScene scene;

    // アイテムをシーンに追加
    QGraphicsRect *item = new QGraphicsRect(0, 0, 100, 100);
    scene.addItem(item);

    // ビューを作成
    MyGraphicsView view;
    view.setScene(&scene);
    view.show();

    return app.exec();
}

このコードの説明

  1. MyGraphicsViewクラスを定義します。このクラスは、QGraphicsViewを継承し、wheelEvent()メソッドをオーバーライドします。
  2. wheelEvent()メソッド内で、QGraphicsSceneWheelEventオブジェクトを作成し、イベント情報を受け取ります。
  3. delta()関数を使用して、ホイール回転量を取得します。
  4. 回転量に基づいて、scale()関数を使用してシーンを拡大縮小します。
  1. 上記のコードをQt Creatorなどの開発環境で保存します。
  2. コードをコンパイルして実行します。
  3. グラフィックシーン内でマウスホイールを回転させると、シーンが拡大縮小されます。
  • シーンを拡大縮小する代わりに、他の処理を行うこともできます。
  • このコードはあくまでも一例であり、必要に応じて変更することができます。


QWheelEvent::delta()関数を使用する

QGraphicsSceneWheelEvent::delta()関数は、QGraphicsScene内のマウスホイールイベントを処理する際に使用されますが、QWheelEvent::delta()関数を使用して、より一般的な方法でマウスホイールイベントを処理することもできます。

void MyGraphicsView::wheelEvent(QWheelEvent *event)
{
    // ホイール回転量を取得
    int delta = event->delta();

    // 回転量に基づいて処理を行う
    if (delta > 0) {
        // ホイールがユーザーから離れる方向に回転
        // シーンを拡大する
        scale(1.1, 1.1);
    } else if (delta < 0) {
        // ホイールがユーザーに向かって回転
        // シーンを縮小する
        scale(0.9, 0.9);
    }
}

QGraphicsItem::wheelEvent()メソッドをオーバーライドする

QGraphicsItem::wheelEvent()メソッドをオーバーライドして、マウスホイールイベントを個別に処理することもできます。

class MyItem : public QGraphicsItem
{
public:
    MyItem(QWidget *parent = nullptr) : QGraphicsItem(parent) {}

protected:
    void wheelEvent(QGraphicsSceneWheelEvent *event) override
    {
        // ホイール回転量を取得
        int delta = event->delta();

        // 回転量に基づいて処理を行う
        if (delta > 0) {
            // ホイールがユーザーから離れる方向に回転
            // アイテムを拡大する
            setScale(scale().x() * 1.1, scale().y() * 1.1);
        } else if (delta < 0) {
            // ホイールがユーザーに向かって回転
            // アイテムを縮小する
            setScale(scale().x() * 0.9, scale().y() * 0.9);
        }
    }
};

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

QGraphicsScene::wheelEvent()メソッドをオーバーライドして、カスタムイベントを発行し、そのイベントを処理する別のオブジェクトで処理することもできます。

class MyGraphicsScene : public QGraphicsScene
{
public:
    MyGraphicsScene(QWidget *parent = nullptr) : QGraphicsScene(parent) {}

protected:
    void wheelEvent(QWheelEvent *event) override
    {
        // カスタムイベントを作成
        QGraphicsSceneWheelEvent *sceneWheelEvent = new QGraphicsSceneWheelEvent(*event);
        sceneWheelEvent->applyModifiers(event->modifiers());
        sceneWheelEvent->setPos(event->pos());

        // カスタムイベントを発行
        QCoreApplication::instance()->postEvent(this, sceneWheelEvent);
    }
};

class MyEventListener : public QObject
{
public:
    MyEventListener(QObject *parent = nullptr) : QObject(parent) {}

protected:
    void customEvent(QEvent *event) override
    {
        if (event->type() == QEvent::GraphicsSceneWheel) {
            QGraphicsSceneWheelEvent *sceneWheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);

            // ホイール回転量を取得
            int delta = sceneWheelEvent->delta();

            // 回転量に基づいて処理を行う
            // ...
        }
    }
};
方法メリットデメリット
QWheelEvent::delta()関数シンプルでわかりやすいシーン全体を処理する
QGraphicsItem::wheelEvent()メソッド個別のアイテムを処理できるすべてのアイテムに対してオーバーライドする必要がある
カスタムイベントより柔軟な処理が可能コードが複雑になる