Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
[SOLVED] How to keep a context menu open
I realize this may be a simple question for some of you, but I have searched far and wide (but maybe in the wrong places ...) for a solution for this:
I want to enable a user to select several values in a context menu (right click/list of values pops up) - so I would like the menu to stay open once an item is selected. But default, the menus close on every selection. What is the best way to override this behavior?
I am using Qt 4.7 from PySide (Python binding).
goetz last edited by
You can call setCheckable(true) on the actions, that makes the menu actions selectable. The usual way a menu works is that it closes once one entry is clicked, though. I don't see a direct solution for this.
One option that comes into mind, is to use a QListView or QListWidget, that you show on a context menu request. That would stay open as long as you want and allows you to select multiple entries. You will have to take care of closing the view yourself - e.g. if someone clicks outside the view.
The setCheckable is nicer (more standard) than a custom icon that I was planning on using.
I am worried about coding a new context menu from scratch (mine have to have a three level deep hierarchy) ... but there might be no way to avoid it!
I was hoping that alternatively, maybe mouseEvents can be intercepted and filtered such that a click on an action will not call a slot to close the menu or some such things - but the mouse leaving the area of the menu will.
goetz last edited by
Intercepting the mouse events with an eventFilter() could be an option. I recommend studying the qmenu.cpp sources to not brick something :)
Here is the solution - works like a charm. I install the following eventFilter on all QMenus
def eventFilter(self, obj, event):
if event.type() in [QtCore.QEvent.MouseButtonRelease]:
if isinstance(obj, QtGui.QMenu):
if not obj.activeAction().menu(): #if the selected action does not have a submenu
#eat the event, but trigger the function
return super(<my_class_name>, self).eventFilter(obj, event)