Conflict between 2 context menus
-
Hi guys,
I have a QGraphicsView observing a QGraphicsScene, and I have implemented a custom context menu on my QGraphicsView (by calling setContextMenuPolicy(Qt::CustomContextMenu)).Then I have added a simple QWidget to my scene, containing a QPushButton, and I want to implement another custom context menu on this button. But when I set the QPushButton context menu policy to Qt::CustomContextMenu and connect a slot to the customContextMenuRequested() signal, right clicking on the button opens the QGraphicsView context menu (i.e. the button context menu is covered by the QGraphicsView context menu).
Is there any way to avoid this overlapping ?
Thank you for your help. -
Hi,
Can you provide a minimal sample code that shows that behaviour ?
By the way:
- What version of Qt are you using ?
- On what platform ?
-
Yes, Here is GraphicsView consumes the events and hence you are seeing the behaviour. Even though you are placing the widget, for the GraphicsView it is item only. Only option is to customise the scene class and write your own event handler.
-
@SGaist The code is quite big and it involves several classes, but I will try to provide a sample code asap. I am using Qt 4.8 on Windows .
@dheerendra Which event handlers are you talking about ? I have tried an alternative solution which is using the underMouse method on my widget and disabling the GraphicsView context menu if the right click has been done on my widget. I don't know if this is a correct solution but at the moment I couldn't find any other way to do this. -
One possibility to think about: use an event filter. Then check for QContextMenuEvent, if the underlying element is your proxied widget, then forward the event to it, otherwise let it be handled by the scene.
-
One possibility to think about: use an event filter. Then check for QContextMenuEvent, if the underlying element is your proxied widget, then forward the event to it, otherwise let it be handled by the scene.
@SGaist I went through all the docs of event filters (http://doc.qt.io/archives/qt-4.8/eventsandfilters.html and http://doc.qt.io/archives/qt-4.8/qobject.html#installEventFilter) but in the line
monitoredObj->installEventFilter(filterObj);
what is the monitored object, the QGraphicsScene or the QGraphicsView ? And should my widget be the filter object ? -
That depends on you, you can have a separate object that does the filtering.
As for the scene or the view, the scene would make more sense it's it that contains all the items.
-
That depends on you, you can have a separate object that does the filtering.
As for the scene or the view, the scene would make more sense it's it that contains all the items.
@SGaist I have installed an event filter on the scene, but it turns out that QContextMenuEvent is never called, instead QEvent::GraphicsSceneMousePress and QEvent::GraphicsSceneMouseReleased are called when I click on the widget. In addition, in the function
bool FilterObject::eventFilter(QObject *object, QEvent *event)
,object
is always my QGraphicsScene, thus from here I don't know how to forward events to my widget.
However I managed to solve this with a workaround : I open the QGraphicsView (QMenu::exec()
) only whenmyWidget->underMouse()
returns false, and then I reimplementmousePressEvent
andmouseReleaseEvent
to deal with the right click. -
Do you mean in the slot connected to
customContextMenuRequested
? -
@SGaist Yes, I open the QGraphicsView context menu in the slot connected to
customContextMenuRequested
. I don't know if the use ofunderMouse()
is convenient or not.@DMIII
I may be off-base here, but have a look at http://www.qtcentre.org/archive/index.php/t-65353.html:, the graphicsView context menu is beig shown, if I right-click on it, not one of the item.
Look at the example code in QGraphicsView::itemAt(). You will need to implement something like that in your showContextMenu() slot - first check to see if there is an item at the QPoint. If there is, and it is one of your custom items, then you need to display its context menu (maybe send it a QGraphicsSceneContextMenuEvent). If there is nothing at the QPoint, then you display the QGraphicsView's context menu. The problem you are having is that the view's context menu handler is eating the right-clicks and your graphics items never see them.
I have no idea, but don't you need to implement similar principle for the
QWidget
you are adding? In other words, it's yourQGraphicsView
job to recognise the right-click and forward it to the desired object. -
@DMIII
I may be off-base here, but have a look at http://www.qtcentre.org/archive/index.php/t-65353.html:, the graphicsView context menu is beig shown, if I right-click on it, not one of the item.
Look at the example code in QGraphicsView::itemAt(). You will need to implement something like that in your showContextMenu() slot - first check to see if there is an item at the QPoint. If there is, and it is one of your custom items, then you need to display its context menu (maybe send it a QGraphicsSceneContextMenuEvent). If there is nothing at the QPoint, then you display the QGraphicsView's context menu. The problem you are having is that the view's context menu handler is eating the right-clicks and your graphics items never see them.
I have no idea, but don't you need to implement similar principle for the
QWidget
you are adding? In other words, it's yourQGraphicsView
job to recognise the right-click and forward it to the desired object.