Найти позицию QGraphicsItem на экране

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

Использование этого может позволить более общий ответ на мой вопрос...

12
задан Martin Hennings 2 April 2012 в 14:07
поделиться