Finden Sie die Bildschirmposition ein QGraphicsItem
Anwendungsfall: sollte Dies ein Recht häufiges problem. In einem normalen QMainWindow mit QMdiArea Leben ein mdiChild mit QGraphicsView. Diese Ansicht zeigt eine QGraphicsScene mit QGraphicsItems innen. Ein rechts-Klick auf einen dieser Einträge auswählt (konzentriert sich) auf das Element und öffnet ein Kontext-Menü, das bequem auf den Bildschirm-Koordinaten QGraphicsSceneMouseEvent::screenPos()
. Dies funktioniert wie erwartet.
Nun möchte ich zeigen das gleiche Kontext-Menü, wenn der Benutzer eine Taste drückt (z.B. Qt::Key_Menu). Ich weiß, das ausgewählt (fokussiert) posten, ich weiß, die Ansicht, die zeigt die Szene.
Also meine Frage ist:
Was ist der richtige Weg, um die position (in globalen Bildschirmkoordinaten) der sichtbaren Darstellung einer QGraphicsItem innerhalb einer Szene?
Hier ist was nicht funktioniert:
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
Der doc sagt:
Wenn Sie wissen wollen, wo sich im Ansichtsfenster ein Objekt befindet, können Sie rufen Sie QGraphicsItem::mapToScene() auf das Element, dann QGraphicsView::mapFromScene() auf die Ansicht.
Das ist genau das, was ich Tue, richtig?
Stolperte über ein thread in einem deutschen forum, die Hinweise auf:
QGraphicsView *view = item->scene()->views().last();
oder noch schöner:
QGraphicsView *view;
foreach (view, this->scene()->views())
{
if (view->underMouse() || view->hasFocus()) break;
}
//(use case in the forum thread:) //QMenu *menu = new QMenu(view);
Verwenden, die es erlauben würde, eine mehr generalisierte Antwort auf meine Frage...
- Ich war über eine Antwort zu posten, aber aus re-Lektüre des docs-ich glaube, ich Stimme mit Ihrer Analyse: QGraphicsView::mapFromScene geben soll viewport-Koordinaten (lohnt sich). Wäre nur die Frage, ob es eine latente Fehler in mapToGlobal auf widgets innerhalb von MDI-Kinder.
- Also, was wäre Ihre erste Vermutung (die Sie geschrieben haben, in der Antwort)?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fand ich eine funktionierende Lösung.
Die QGraphicsItem muss auf dem Bildschirm sichtbar.
(Wahrscheinlich, wenn es nicht sichtbar ist, weil der Blick zeigt einem anderen Punkt der Szene, der einen zurückhalten konnte, die Stelle zu der Ansicht viewport rect.)
Es ist wichtig, um die Ansicht viewport für die Zuordnung der anzeigen coords, um Globale Koords.
Die Erkennung des Kontext-Menü-Taste (Qt::Key_Menu) geschieht in der
keyPressEvent()
von der "main" - QGraphicsItem (aufgrund der Struktur meiner Programm).QGraphicsSceneEvent::widget()
. Sie könnenQWidget::isAncestorOf(event->widget())
zu finden, die "richtige" Sicht, anstatt einfach nur die erste.QMainWindow
mitsendMenuEventPos = v->viewport()->mapTo(mainWindow, viewP);
anstattmapToGlobal
Der code scheint richtig zu sein. Aber es könnte ein problem mit der Erstellung von Kontext-Menü.
Haben Sie die Eltern der QContextMenu zu MainWindow (oder so etwas in der Art in Ihrer Anwendung)??
Ich denke, dass könnte das problem in Ihrem Fall.
Glück!!
Nur ein stab im Dunkeln, doch haben Sie einen Blick auf diese http://www.qtcentre.org/threads/36992-Keyboard-shortcut-event-not-received.
Auf der Suche durch die Qt-Dokumentation, es scheint die Verwendung von QGraphicsView kann dazu führen, dass einige außergewöhnliche Verhalten mit Bezug auf Verknüpfungen.
Sieht es aus, als ob es möglicherweise einen normativen Weg, das Ergebnis, die Sie wünschen.
Je nachdem, wie Sie die Umsetzung Ihrer Kontext-Menüs, shortcuts und QGraphicsView, die Sie möglicherweise benötigen, um die Qt::ContextMenuPolicy für die QGraphicsView angemessen und bauen, und rufen Sie das Menü anders.
Ich bin ziemlich interessiert in dieser Frage, wie ich werde tun müssen, etwas ziemlich ähnliches in Kürze!
Qt::ActionsContextMenu
sieht glänzend. Ich werde einen Blick hinein, aber ich bin nicht sehr zuversichtlich, dass es helfen wird. Mein problem ist mehr über die Positionierung als über Tastatur-Eingabe (ich kann anrufen, die Funktion von überall).exec
definition einer Funktion in der Dokumentation von Interesse sein: doc.qt.nokia.com/4.7-snapshot/qmenu.html#exec-3. Es scheint wie eine seltsame statische Methode, sondern verweist auf die Möglichkeit, dass ein QPoint ist nicht genug, wenn "...die Eltern ist eingebettet in QGraphicsView". Es ist ein wenig geheimnisvoll.