Qt Widgets:QGraphicsSceneContextMenuEvent::screenPos() で実現する、自由度の高いコンテキストメニュー


QGraphicsSceneContextMenuEvent::screenPos() は、Qt WidgetsライブラリにおけるQGraphicsSceneContextMenuEventクラスのメソッドの一つであり、コンテキストメニューイベントが発生した時点におけるマウスカーソルのスクリーン座標を返します。この情報は、コンテキストメニューを適切な位置に表示するために使用されます。

使用方法

QPoint screenPos = event->screenPos();

このコードは、QGraphicsSceneContextMenuEventオブジェクトからscreenPos() メソッドを呼び出し、マウスカーソルのスクリーン座標を取得します。返される QPoint オブジェクトには、X座標とY座標が格納されています。

座標系

screenPos() メソッドによって返される座標は、スクリーン座標系と呼ばれる座標系で表現されます。スクリーン座標系は、画面左上隅を原点とし、X軸が右方向、Y軸が下方向に伸びる座標系です。

次のコード例は、QGraphicsSceneContextMenuEvent イベントが発生した際に、マウスカーソルのスクリーン座標をログに出力する例です。

void MyGraphicsView::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QPoint screenPos = event->screenPos();
    qDebug() << "Screen position: " << screenPos;

    // ... コンテキストメニューを表示する処理 ...
}

QGraphicsSceneContextMenuEvent オブジェクトには、他にも以下のメソッドが用意されています。

  • reason(): コンテキストメニューイベントが発生した理由を取得します。
  • modifiers(): キーボード修飾キーを取得します。
  • scenePos(): マウスカーソルのシーン座標を取得します。
  • pos(): マウスカーソルのアイテム座標を取得します。


MyGraphicsView.h

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QContextMenuEvent>

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

protected:
    void contextMenuEvent(QContextMenuEvent *event) override;
};

MyGraphicsView.cpp

#include "MyGraphicsView.h"
#include "MyItem.h"

MyGraphicsView::MyGraphicsView(QWidget *parent) : QGraphicsView(parent)
{
    scene = new QGraphicsScene(this);
    setScene(scene);

    // アイテムを作成してシーンに追加する
    MyItem *item = new MyItem;
    scene->addItem(item);
}

void MyGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint screenPos = event->screenPos();
    qDebug() << "Screen position: " << screenPos;

    // ... コンテキストメニューを表示する処理 ...
}

MyItem.h

#include <QGraphicsItem>

class MyItem : public QGraphicsItem
{
public:
    MyItem();

protected:
    void contextMenuEvent(QContextMenuEvent *event) override;
};
#include "MyItem.h"

MyItem::MyItem()
{
    setRect(0, 0, 100, 100);
}

void MyItem::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint screenPos = event->screenPos();
    qDebug() << "Item context menu: Screen position: " << screenPos;

    // ... アイテム固有のコンテキストメニューを表示する処理 ...
}


しかし、状況によっては、QGraphicsSceneContextMenuEvent::screenPos() メソッド以外の方法でマウスカーソルのスクリーン座標を取得する方が適切な場合があります。以下に、いくつかの代替方法を紹介します。

QMouseEvent::globalPos() を使用する

QGraphicsSceneContextMenuEvent オブジェクトは、QMouseEvent クラスから派生したクラスです。そのため、QMouseEvent::globalPos() メソッドを使用して、マウスカーソルのスクリーン座標を取得することができます。

QPoint screenPos = event->globalPos();

mapToGlobal() メソッドを使用する

QGraphicsSceneContextMenuEvent オブジェクトには、mapToGlobal() メソッドが用意されています。このメソッドを使用して、マウスカーソルのシーン座標をスクリーン座標に変換することができます。

QPoint screenPos = event->scenePos().mapToGlobal(viewport());

QGraphicsView::globalMousePos() メソッドを使用する

QGraphicsView クラスには、globalMousePos() メソッドが用意されています。このメソッドを使用して、マウスカーソルのスクリーン座標を取得することができます。

QPoint screenPos = view->globalMousePos();

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

上記の方法でうまくいかない場合は、カスタムイベントを使用することができます。カスタムイベントは、アプリケーション固有のイベントであり、必要な情報をイベントデータに格納することができます。

使用例

以下のコード例は、QGraphicsSceneContextMenuEvent::screenPos() メソッドの代替方法として、QMouseEvent::globalPos() メソッドを使用する例です。

void MyGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
    QPoint screenPos = event->globalPos();
    qDebug() << "Screen position: " << screenPos;

    // ... コンテキストメニューを表示する処理 ...
}

このコードを実行すると、MyGraphicsView ウィジェット上にマウスカーソルを移動し、右クリックすると、マウスカーソルのスクリーン座標がログに出力されます。