ユースケース:これはかなり一般的な問題です。QMdiArea を持つ通常の QMainWindow には、QGraphicsView を持つ mdiChild が存在します。このビューは、内部に QGraphicsItems を含む QGraphicsScene を表示します。これらの項目の 1 つを右クリックすると、その項目が選択 (フォーカス) され、コンテキスト メニューが開きます。このメニューは、画面座標に便利に配置されていますQGraphicsSceneMouseEvent::screenPos()
。これは期待どおりに機能しています。
ユーザーがキーを押したときに同じコンテキスト メニューを表示したいと思います (Qt::Key_Menu など)。選択された (フォーカスされた) アイテム、シーンを表示するビューを知っています。
だから私の質問は:
シーン内の QGraphicsItem の可視表現の位置 (グローバル、スクリーン座標) を取得する正しい方法は何ですか?
機能していないものは次のとおりです。
QGraphicsItem *item = ...; // is the currently selected item next to which the context menu shall be opened
QGraphicsScene *scene = ...; // is the scene that hosts the item
QGraphicsView *graphicsView = ...; // is the view displaying the scene, this inherits from QWidget
// get the position relative to the scene
QPointF sp = item->scenePos();
// or use
QPointF sp = item->mapToScene(item->pos());
// find the global (screen) position of the item
QPoint global = graphicsView->mapToGlobal(graphicsView->mapFromScene(sp));
// now
myContextMenu.exec(global);
// should open the context menu at the top left corner of the QGraphicsItem item, but it goes anywhere
ドキュメントには次のように書かれています:
ビューポートのどこにアイテムがあるか知りたい場合は、アイテムで QGraphicsItem::mapToScene() を呼び出してから、ビューで QGraphicsView::mapFromScene() を呼び出すことができます。
まさに私がしていることですよね?
ドイツのフォーラムで、次のことを示唆するスレッドに出くわしました。
QGraphicsView *view = item->scene()->views().last();
またはさらに良い:
QGraphicsView *view;
foreach (view, this->scene()->views())
{
if (view->underMouse() || view->hasFocus()) break;
}
// (use case in the forum thread:) // QMenu *menu = new QMenu(view);
それを使用すると、私の質問に対するより一般的な答えが得られる可能性があります...