Showing a popup menu on QGraphicsScene click or right click
Asked Answered
I

2

9

Is there a way to show a popup when the user right clicks on an empty portion of the scene?

I'm new at Qt and I've tried slots and subclassing, but to no avail.

No such slot and, respectively:

"error: 'QMouseEvent' has not been declared"

when trying to implement the onMouseRelease event.

Invaluable answered 26/5, 2012 at 13:45 Comment(0)
C
12

QGraphicsView is the widget used for displaying the contents of the QGraphicsScene. So the correct place to implement the context menu (popup menu) is the QGraphicsView.

You need to reimplement the contextMenuEvent function is your own class inherited from QGraphicsView:

void YourGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(...);
    menu.addAction(...);
    ...
    menu.exec(event->globalPos());
}

See also the Qt's Menus Example.

Cumae answered 26/5, 2012 at 14:0 Comment(4)
Thanks! It worked, but I needed to do some changes. 1. Firstly, since my project type is Qt GUI Application, I needed to replace the given QGraphicsView with my own. I did this by manually editing the .ui file and replacing the class name for the object. 2. I used the following example for QGraphicsView subclassing: doc.trolltech.com/4.3/graphicsview-elasticnodes.html. I had to modify the constructor to include a parameter for parent widget: GraphWidget(QWidget * parent) [...]. Then simply implementing the context menu event in this class did the trick.Invaluable
Could I have done it differently, perhaps without having to manually modify the .ui file manually?Invaluable
You can change the widget class from QGraphicsView to your own class also in the QtCreator's design view using the "promote to..." action in the widget's context menu.Cumae
The 'Qt's Menus Example' link form the answer is broken (today, September 01, 2016), so here is a link to the Qt 5.7 Menus example: doc.qt.io/qt-5/qtwidgets-mainwindows-menus-example.htmlInunction
M
13

You can re-implement the contextMenuEvent method of the QGraphicsScene class, which will give you access to the scene coordinates as well as the screen coordinates (as opposed to QGraphicsView, which also works but doesn't have this information):

void YourGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    // event->scenePos() is available
    QMenu menu(this);
    menu.addAction(...);
    menu.addAction(...);
    ...
    menu.exec(event->screenPos());
}
Moonshine answered 24/12, 2012 at 2:19 Comment(2)
This is a nice solution. QMenu menu(this); doesn't work. You can use QMenu menu(event->widget()); to get the active widget to serve as QWidget parent of QMenu.Poetize
Actually, it seems there's no need to give the menu a parent. QMenu menu() works just fine, since the context menu is a window in its own right and is being positioned in screen coordinates.Prorate
C
12

QGraphicsView is the widget used for displaying the contents of the QGraphicsScene. So the correct place to implement the context menu (popup menu) is the QGraphicsView.

You need to reimplement the contextMenuEvent function is your own class inherited from QGraphicsView:

void YourGraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(...);
    menu.addAction(...);
    ...
    menu.exec(event->globalPos());
}

See also the Qt's Menus Example.

Cumae answered 26/5, 2012 at 14:0 Comment(4)
Thanks! It worked, but I needed to do some changes. 1. Firstly, since my project type is Qt GUI Application, I needed to replace the given QGraphicsView with my own. I did this by manually editing the .ui file and replacing the class name for the object. 2. I used the following example for QGraphicsView subclassing: doc.trolltech.com/4.3/graphicsview-elasticnodes.html. I had to modify the constructor to include a parameter for parent widget: GraphWidget(QWidget * parent) [...]. Then simply implementing the context menu event in this class did the trick.Invaluable
Could I have done it differently, perhaps without having to manually modify the .ui file manually?Invaluable
You can change the widget class from QGraphicsView to your own class also in the QtCreator's design view using the "promote to..." action in the widget's context menu.Cumae
The 'Qt's Menus Example' link form the answer is broken (today, September 01, 2016), so here is a link to the Qt 5.7 Menus example: doc.qt.io/qt-5/qtwidgets-mainwindows-menus-example.htmlInunction

© 2022 - 2024 — McMap. All rights reserved.