如何将上下文菜单添加到 PyQt5 中的上下文菜单?
How to add a context menu to a context menu in PyQt5?
我正在使用 PyQt5 在 python 中构建一个 GUI,我需要当我右键单击上下文菜单中的一个选项时,它会显示另一个上下文菜单,如图所示...
(我知道我可以在其中一个选项中嵌套菜单,但这不是我想要的)
上下文菜单不区分右击和左击。
我认为要实现这一点有两个问题...
- 我不知道如何防止右键单击触发
PyQt5.QtWidgets.QAction
。
- 第二个问题是,通常创建上下文菜单的步骤之一是在小部件上使用
.installEventFilter()
方法,但在这种情况下,您应该在类型为 PyQt5.QtWidgets.QAction
我知道我所要求的实现起来很复杂,但如果您能给我一些信息以帮助我实现它,我将不胜感激。
在这里我给你留下了一个 GUI 的代码,它带有一个安装了上下文菜单的小部件...
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu
import sys
from PyQt5.QtCore import QEvent
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.createWidgets()
def createWidgets(self):
self.my_button = QtWidgets.QPushButton(self)
self.my_button.setText("My Widget")
self.my_button.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.ContextMenu and source is self.my_button:
menu = QMenu()
action1 = menu.addAction("Option 1")
action2 = menu.addAction("Option 2")
action3 = menu.addAction("Option 3")
selected_action = menu.exec_(event.globalPos())
if selected_action == action1:
print("You have selected the first option")
if selected_action == action2:
print("You have selected the second option")
if selected_action == action3:
print("You have selected the third option")
return super().eventFilter(source, event)
def showWindow():
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
showWindow()
在按钮上安装事件过滤器是不够的,你当然不能在QAction上安装它,它永远不会触发鼠标事件,因为它没有继承自QWidget。您必须在菜单本身上安装过滤器。
为了允许正确跟踪菜单(并对它们的事件做出正确反应),最好也保留更多对菜单的静态引用。
显然,您可以创建 QMenu 的子类,这可能会使事情变得更容易。
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.createWidgets()
def createWidgets(self):
self.my_button = QtWidgets.QPushButton(self)
self.my_button.setText("My Widget")
self.buttonMenu = QMenu(self.my_button)
self.buttonMenu.addAction("Option 1")
self.buttonMenu.addAction("Option 2")
self.buttonMenu.addAction("Option 3")
self.subMenu = QMenu(self.buttonMenu)
self.subMenu.addAction("Sub Option 1")
self.subMenu.addAction("Sub Option 2")
self.subMenu.addAction("Sub Option 3")
self.my_button.installEventFilter(self)
self.buttonMenu.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.ContextMenu:
if source == self.my_button:
self.buttonMenu.exec_(event.globalPos())
return True
elif source == self.buttonMenu:
self.subMenu.exec_(event.globalPos())
return True
return super().eventFilter(source, event)
我正在使用 PyQt5 在 python 中构建一个 GUI,我需要当我右键单击上下文菜单中的一个选项时,它会显示另一个上下文菜单,如图所示...
(我知道我可以在其中一个选项中嵌套菜单,但这不是我想要的)
上下文菜单不区分右击和左击。
我认为要实现这一点有两个问题...
- 我不知道如何防止右键单击触发
PyQt5.QtWidgets.QAction
。 - 第二个问题是,通常创建上下文菜单的步骤之一是在小部件上使用
.installEventFilter()
方法,但在这种情况下,您应该在类型为PyQt5.QtWidgets.QAction
我知道我所要求的实现起来很复杂,但如果您能给我一些信息以帮助我实现它,我将不胜感激。
在这里我给你留下了一个 GUI 的代码,它带有一个安装了上下文菜单的小部件...
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu
import sys
from PyQt5.QtCore import QEvent
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.createWidgets()
def createWidgets(self):
self.my_button = QtWidgets.QPushButton(self)
self.my_button.setText("My Widget")
self.my_button.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.ContextMenu and source is self.my_button:
menu = QMenu()
action1 = menu.addAction("Option 1")
action2 = menu.addAction("Option 2")
action3 = menu.addAction("Option 3")
selected_action = menu.exec_(event.globalPos())
if selected_action == action1:
print("You have selected the first option")
if selected_action == action2:
print("You have selected the second option")
if selected_action == action3:
print("You have selected the third option")
return super().eventFilter(source, event)
def showWindow():
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
showWindow()
在按钮上安装事件过滤器是不够的,你当然不能在QAction上安装它,它永远不会触发鼠标事件,因为它没有继承自QWidget。您必须在菜单本身上安装过滤器。
为了允许正确跟踪菜单(并对它们的事件做出正确反应),最好也保留更多对菜单的静态引用。
显然,您可以创建 QMenu 的子类,这可能会使事情变得更容易。
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.createWidgets()
def createWidgets(self):
self.my_button = QtWidgets.QPushButton(self)
self.my_button.setText("My Widget")
self.buttonMenu = QMenu(self.my_button)
self.buttonMenu.addAction("Option 1")
self.buttonMenu.addAction("Option 2")
self.buttonMenu.addAction("Option 3")
self.subMenu = QMenu(self.buttonMenu)
self.subMenu.addAction("Sub Option 1")
self.subMenu.addAction("Sub Option 2")
self.subMenu.addAction("Sub Option 3")
self.my_button.installEventFilter(self)
self.buttonMenu.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.ContextMenu:
if source == self.my_button:
self.buttonMenu.exec_(event.globalPos())
return True
elif source == self.buttonMenu:
self.subMenu.exec_(event.globalPos())
return True
return super().eventFilter(source, event)