A colleague made a custom QMenu derivative so that one can select multiple entries before the menu closes.
It is triggered via a QToolButton.
The problem is if the menu is large enough it will overlap with the button. The item at the current cursor position then gets selected instantly when clicking the QToolButton.
How does one prevent this?
Code for my menu, I tried to ignore the first event with a Bool flag, but it doesn't work.
class StayOpenMenu(QMenu):
"""
a class that overrides the QMenu mouseReleaseEvent to let the menu stay open when an element is selected
"""
def __init__(self, parent=None):
self.isfirstEvent = True
super().__init__("Stay open Menu", parent=parent)
def mouseReleaseEvent(self, a0: QMouseEvent):
if self.isfirstEvent:
a0.ignore()
self.isfirstEvent = False
return
try:
action = self.actionAt(a0.pos())
action.trigger()
except:
pass
def aboutToShow(self):
self.isfirstEvent = True
return super().aboutToShow()
def aboutToHide(self):
self.isfirstEvent = True
return super().aboutToShow()
Image: Before clicking the button
Image: After clicking the QToolButton
aboutToShow()
and aboutToHide()
are signals, not methods, so they can't be "overridden".
Create a slot for setting the variable to True and connect it to the aboutToShow
signal only.
Also note that you'll have to take care of the mousePressEvent too: if the menu is not activated from a mouse click (most likely by pressing the tool button via keyboard), it will prevent it from receiving a legitimate release event.
class StayOpenMenu(QMenu):
def __init__(self, parent=None):
self.isfirstEvent = False
super().__init__("Stay open Menu", parent=parent)
self.aboutToShow.connect(self.isShowing)
def isShowing(self):
self.isfirstEvent = True
def mousePressEvent(self, a0: QMouseEvent):
self.isfirstEvent = False
super().mousePressEvent(a0)
def mouseReleaseEvent(self, a0: QMouseEvent):
if self.isfirstEvent:
a0.ignore()
self.isfirstEvent = False
return
try:
action = self.actionAt(a0.pos())
action.trigger()
except:
pass