gregseth
gregseth

Reputation: 13438

Qt: open context menu on mouse press

I'm trying to change the default behavior of context menus: Instead of opening on the release event of the right mouse button, I want it to open on the press event, and it's actions to be triggered on the release event). On one widget I could overload the mousePressEvent() and fire a custom contextmenu event, but I want it to be global to all the context menus of my program...

Any ideas?

Thanks.

Upvotes: 1

Views: 4435

Answers (2)

Thomas Vincent
Thomas Vincent

Reputation: 2224

I was trying to implement a widget base on top of QWidget with a custom way to handle context menu to suit your needs when I realize that using ActionsContextMenu policy with actions directly own by the widget does exactly the behavior you are expecting. (Qt 4.6.2 & 4.7 on linux, didn't try on windows yet but I don't know why the behavior should be different).

Is that a policy you can use ? If you don't really need external menus, I'll suggest to go with this solution.

Otherwise you will have to create your own widget base with a custom QMenu member. You should use the Qt::PreventContextMenu policy to guarantee the right click to end in the void mousePressEvent(QMouseEvent *event) of your widget. In this event handler make sure to show your menu. In your menu re-implement the void mouseReleaseEvent( QMouseEvent *event) if it don't trigger the current action do it your-self with the mouse position (in the event) and the QAction* actionAt( const QPoint & pt) const. But be careful the void mouseReleaseEvent( QMouseEvent *event) of the QMenu is already re-implemented from QWidget and may do some stuff you want to preserve !


EDIT It's kind of sad but this behavior seems to be different by design on windows the void QMenu::mouseReleaseEvent(QMouseEvent *e) does the following:

Extracted form qmenu.cpp, Qt 4.6.2 sdk

#if defined(Q_WS_WIN)
        //On Windows only context menus can be activated with the right button
        if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
#endif
            d->activateAction(action, QAction::Trigger);

I don't know what the topCausedWidget() does in life but it's kind of explicit that only left button release will trigger the current action ...

One simple solution for you will be to re-implement your QMenu with this line commented ...

Upvotes: 1

Andrejs Cainikovs
Andrejs Cainikovs

Reputation: 28474

Sounds like you need to create your own class based on QMenu, and use it for every context menu in your program.

Check here for a reference.

Upvotes: 1

Related Questions