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.

mtb
  • 1,350
  • 16
  • 32
TudorT
  • 441
  • 1
  • 6
  • 18

2 Answers2

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.

  • 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: http://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. – TudorT May 26 '12 at 15:10
  • Could I have done it differently, perhaps without having to manually modify the .ui file manually? – TudorT May 26 '12 at 15:16
  • 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. –  May 26 '12 at 15:21
  • 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: http://doc.qt.io/qt-5/qtwidgets-mainwindows-menus-example.html – mtb Sep 01 '16 at 11:04
12

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());
}
Sydius
  • 13,567
  • 17
  • 59
  • 76
  • 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. – gamecreature Jul 24 '13 at 21:16
  • 2
    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. – Jesse Crossen Sep 17 '14 at 01:38