Use case: This should be a fairly common problem. In a normal QMainWindow with QMdiArea lives an mdiChild with a QGraphicsView. This view displays a QGraphicsScene with QGraphicsItems inside. A right-click at one of these items selects (focusses) the item and opens a context menu, which is conveniently placed at the screen coordinates QGraphicsSceneMouseEvent::screenPos()
. This is working as expected.
Now I'd like to show the same context menu when the user presses a key (e.g. Qt::Key_Menu). I know the selected (focussed) item, I know the view which displays the scene.
So my question is:
What is the correct way to get the position (in global, screen coordinates) of the visible representation of a QGraphicsItem within a scene?
Here is what's not working:
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
The doc says:
If you want to know where in the viewport an item is located, you can call QGraphicsItem::mapToScene() on the item, then QGraphicsView::mapFromScene() on the view.
Which is exactly what I'm doing, right?
Just stumbled upon a thread in a german forum that hints to:
QGraphicsView *view = item->scene()->views().last();
or even nicer:
QGraphicsView *view;
foreach (view, this->scene()->views())
{
if (view->underMouse() || view->hasFocus()) break;
}
// (use case in the forum thread:) // QMenu *menu = new QMenu(view);
Using that might allow a more generalized answer to my question...