用例:这应该是一个相当普遍的问题。在带有 QMdiArea 的普通 QMainWindow 中,有一个带有 QGraphicsView 的 mdiChild。这个视图显示了一个 QGraphicsScene,里面有 QGraphicsItems。右键单击这些项目之一选择(聚焦)该项目并打开上下文菜单,该菜单方便地放置在屏幕坐标处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);
使用它可能会更普遍地回答我的问题......