Trouver la position de l'écran d'un QGraphicsItem

Cas d'utilisation: Ce doit être un problème assez courant. Dans un QMainWindow avec QMdiArea vit une mdiChild avec un QGraphicsView. Cette vue affiche un QGraphicsScene avec QGraphicsItems à l'intérieur. Un clic droit sur l'un de ces éléments sélectionne (porte) de l'élément et ouvre un menu contextuel, qui est idéalement placé à l'écran les coordonnées QGraphicsSceneMouseEvent::screenPos(). Cela fonctionne comme prévu.

Maintenant, je voudrais montrer le même menu contextuel lorsque l'utilisateur appuie sur une touche (par exemple, Qt::Key_Menu). Je sais sélectionnés (concentré) point, je sais que le point de vue qui affiche la scène.

Donc ma question est:
Quelle est la bonne façon d'obtenir la position (en global, les coordonnées de l'écran) de la représentation visible d'un QGraphicsItem dans une scène?

Ici est ce qui ne marche pas:

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

Le doc a dit:
Si vous voulez savoir d'où dans la fenêtre d'affichage d'un élément se trouve, vous pouvez appeler QGraphicsItem::mapToScene() sur l'élément, puis QGraphicsView::mapFromScene() sur l'affichage.
Ce qui est exactement ce que je fais, non?


Viens de tombé sur un thread dans un forum allemand que les allusions à:

QGraphicsView *view = item->scene()->views().last();

ou même plus agréable:

QGraphicsView *view;
foreach (view,  this->scene()->views())
{
    if (view->underMouse() || view->hasFocus()) break;
}
//(use case in the forum thread:) //QMenu *menu = new QMenu(view);

L'aide qui pourrait permettre à un plus généralisée de réponse à ma question...

J'étais sur le point de poster une réponse, mais de re-lire les docs, je pense que je suis d'accord avec votre analyse: QGraphicsView::mapFromScene devrait donner la fenêtre d'affichage des coordonnées (vaut le détour). Seule question serait si il y a un latente bug dans mapToGlobal sur les widgets à l'intérieur MDI enfants.
Alors, quelle serait votre première hypothèse (que vous avez écrit dans la réponse)?

OriginalL'auteur Martin Hennings | 2012-03-26