Когда меню обрывается, оно скрывается, и Qt заменяет его копией, созданной из внутреннего подкласса QMenu
. Поэтому, чтобы установить WindowStaysOnTopHint
в оторванном меню, вам сначала нужно найти способ получить ссылку на него. Один из способов сделать это - установить фильтр событий на объект приложения и наблюдать за дочерними событиями правильного типа:
class MenuWatcher(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
QtWidgets.qApp.installEventFilter(self)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.ChildAdded and
event.child().metaObject().className() == 'QTornOffMenu'):
event.child().setWindowFlag(QtCore.Qt.WindowStaysOnTopHint)
return super().eventFilter(source, event)
Этот класс будет работать с всеми оторванными меню, созданными в приложении.
Однако, если фильтрация событий была выполнена классом исходного меню, его собственное оторванное меню можно определить, сравнив пункты меню:
class Menu(QtWidgets.QMenu):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setTearOffEnabled(True)
QtWidgets.qApp.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.ChildAdded:
child = event.child()
if (child.metaObject().className() == 'QTornOffMenu' and
all(a is b for a, b in zip(child.actions(), self.actions()))):
child.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint)
return super().eventFilter(source, event)