Использование: Это должна быть довольно распространенная проблема. В обычном QMainWindow с QMdiArea живет mdiChild с QGraphicsView. В этом представлении отображается QGraphicsScene с QGraphicsItems внутри. Щелчок правой кнопкой мыши по одному из этих элементов выбирает (фокусирует) элемент и открывает контекстное меню, которое удобно размещается на координатах экрана QGraphicsSceneMouseEvent::screenPos()
. Это работает как ожидалось.Найти положение экрана QGraphicsItem
Теперь я хотел бы показать одно и то же контекстное меню, когда пользователь нажимает клавишу (например, 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
The doc says: Если вы хотите знать, где в окне просмотра располагается элемент, вы можете вызвать QGraphicsItem :: mapToScene() по этому вопросу, то QGraphicsView: : mapFromScene() в представлении.
Это именно то, что я делаю, так?
Просто наткнулся на a thread in a german forum что намекает на:
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);
Используя это может позволить более обобщенный ответ на мой вопрос ...
Я собирался опубликовать ответ, но, перечитав документы, я думаю, что согласен с вашим анализом: QGraphicsView :: mapFromScene должен указывать координаты видового экрана (стоит проверить). Вопрос только в том случае, если в mapToGlobal есть скрытая ошибка в виджетах внутри детей MDI. –
@JamesTurner Итак, какова была бы ваша первая догадка (которую вы бы написали в ответ)? –