Вариант использования: Это должно быть довольно распространенной проблемой. В обычном QMainWindow с QMdiArea живет mdiChild с QGraphicsView. Это представление отображает 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);
Использование этого может позволить более общий ответ на мой вопрос...