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...
Alors, quelle serait votre première hypothèse (que vous avez écrit dans la réponse)?
OriginalL'auteur Martin Hennings | 2012-03-26
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé une solution de travail.
Le QGraphicsItem doit être visible sur l'écran.
(Probablement, si elle n'est pas visible, parce que la vue montre un autre point de la scène, on pourrait retenir le point de la vue de la fenêtre d'affichage du rect.)
Il est important d'utiliser la vue de la fenêtre d'affichage pour la cartographie de la vue coords mondial coords.
La détection du contexte de la touche de menu (Qt::Key_Menu) arrive dans la
keyPressEvent()
de la "main" QGraphicsItem (en raison de la structure de mon programme).QGraphicsSceneEvent::widget()
. Vous pouvez utiliserQWidget::isAncestorOf(event->widget())
de trouver le "bon", au lieu de simplement prendre la première.À moins que l'application à toujours exécuter en plein écran, il serait préférable de carte de
QMainWindow
avecsendMenuEventPos = v->viewport()->mapTo(mainWindow, viewP);
au lieu d'utilisermapToGlobal
OriginalL'auteur Martin Hennings
Le code semble correct. Mais il pourrait y avoir un problème avec la création du menu contextuel.
Avez-vous mis le parent de l'QContextMenu à MainWindow (ou quelque chose de ce genre dans votre demande)??
Je pense que cela pourrait être le problème dans votre cas.
Bonne Chance!!
OriginalL'auteur EngineeredBrain
Juste un coup de poignard dans le noir, mais jetez un oeil à cette http://www.qtcentre.org/threads/36992-Keyboard-shortcut-event-not-received.
En regardant à travers la documentation de Qt, il semble que l'utilisation de QGraphicsView peut causer certains exceptionnelles comportement en ce qui concerne les raccourcis.
Il semble que si il peut y avoir une manière normative à atteindre le résultat que vous désirez.
Selon la façon dont vous êtes à la mise en œuvre de votre contexte, menu, raccourcis et QGraphicsView, vous pourriez avoir besoin pour définir l'intervalle Qt::ContextMenuPolicy pour le QGraphicsView de façon appropriée et de créer et appeler le menu différemment.
Je suis très intéressé par cette question que j'ai besoin de faire quelque chose d'assez similaire peu de temps!
Qt::ActionsContextMenu
regarde brillant. Je vais regarder, mais je ne suis pas très convaincu qu'il pourra vous aider. Mon problème général est plus sur le positionnement que sur l'entrée de clavier (je peux appeler cette fonction à partir de n'importe où).Je suppose que cela dépend de comment vous l'avez mis en œuvre afin de savoir si c'est pertinent ou pas. J'ai aussi constaté ce qui suit surchargé
exec
définition de la fonction dans la documentation de l'intéresser: doc.qt.nokia.com/4.7-snapshot/qmenu.html#exec-3. Il semble comme une étrange méthode statique, mais fait allusion à la possibilité qu'un QPoint n'est pas assez quand "...le parent est incorporé dans QGraphicsView". C'est un peu mystérieux.OriginalL'auteur Mike G