Caso de uso: Esto debería ser un problema bastante común. En un QMainWindow normal con QMdiArea vive un mdiChild con un QGraphicsView. Esta vista muestra un QGraphicsScene con QGraphicsItems dentro. Al hacer clic con el botón derecho en uno de estos elementos, se selecciona (enfoca) el elemento y se abre un menú contextual, que se coloca convenientemente en las coordenadas de la pantalla QGraphicsSceneMouseEvent::screenPos()
. Esto está funcionando como se esperaba.Buscar posición de pantalla de un QGraphicsItem
Ahora me gustaría mostrar el mismo menú contextual cuando el usuario presiona una tecla (por ejemplo, Qt :: Key_Menu). Conozco el elemento seleccionado (enfocado), conozco la vista que muestra la escena.
Así que mi pregunta es:
Cuál es la forma correcta para obtener la posición (en global, las coordenadas de pantalla) de la representación visible de un QGraphicsItem dentro de una escena?
Aquí es lo que no funciona:
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: Si quieren saber en qué parte del puerto de vista un elemento se encuentra, puede llamar QGraphicsItem :: mapToScene() en el elemento y luego QGraphicsView: : mapFromScene() en la vista.
¿Qué es exactamente lo que estoy haciendo, verdad?
tropecé con a thread in a german forum que hace alusión a:
QGraphicsView *view = item->scene()->views().last();
o aún mejor:
QGraphicsView *view;
foreach (view, this->scene()->views())
{
if (view->underMouse() || view->hasFocus()) break;
}
// (use case in the forum thread:) // QMenu *menu = new QMenu(view);
El uso que podrían permitir una respuesta más generalizada a mi pregunta ...
Estaba a punto de publicar una respuesta, pero al volver a leer los documentos creo que estoy de acuerdo con su análisis: QGraphicsView :: mapFromScene debería dar coordenadas de la ventana gráfica (que vale la pena verificar). La única pregunta sería si hay un error latente en mapToGlobal en los widgets dentro de los hijos con MDI. –
@JamesTurner Entonces, ¿cuál sería su primera suposición (que usted habría escrito en respuesta)? –