Caso di utilizzo: Questo dovrebbe essere un problema abbastanza comune. In una normale QMainWindow con QMdiArea vive un mdiChild con un QGraphicsView. Questa vista mostra una QGraphicsScene con QGraphicsItems all'interno. Un clic con il pulsante destro del mouse su uno di questi elementi seleziona (mette a fuoco) l'elemento e apre un menu di scelta rapida, posizionato opportunamente sulle coordinate dello schermo QGraphicsSceneMouseEvent::screenPos()
. Funziona come previsto.Posizione dello schermo di una QGraphicsItem
Ora mi piacerebbe mostrare lo stesso menu contestuale quando l'utente preme un tasto (ad esempio Qt :: Key_Menu). Conosco l'oggetto selezionato (focalizzato), conosco la vista che mostra la scena.
Quindi la mia domanda è:
Qual è il modo corretto per ottenere la posizione (in globale, le coordinate dello schermo) della rappresentazione visibile di un QGraphicsItem all'interno di una scena?
Ecco ciò che non funziona:
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: Se volete sapere dove nel viewport un elemento si trova, è possibile chiamare QGraphicsItem :: mapToScene() sulla voce, quindi QGraphicsView: : mapFromScene() sulla vista.
Quale è esattamente quello che sto facendo, giusto?
appena imbattuto a thread in a german forum che allude a:
QGraphicsView *view = item->scene()->views().last();
o ancora più bello:
QGraphicsView *view;
foreach (view, this->scene()->views())
{
if (view->underMouse() || view->hasFocus()) break;
}
// (use case in the forum thread:) // QMenu *menu = new QMenu(view);
Utilizzando che potrebbe consentire una risposta più generalizzato alla mia domanda ...
Stavo per inviare una risposta, ma rileggendo i documenti penso di essere d'accordo con la tua analisi: QGraphicsView :: mapFromScene dovrebbe fornire le coordinate del viewport (vale la pena controllare). L'unica domanda sarebbe se c'è un bug latente in mapToGlobal sui widget all'interno dei bambini MDI. –
@JamesTurner Quindi quale sarebbe la tua prima ipotesi (che avresti scritto in risposta)? –