PyQT(PySide)的上下文菜单策略设置setContextMenuPolicy()

在 Qt 中,QWidget 类提供了几种不同的上下文菜单策略,这些策略通过 Qt::ContextMenuPolicy 枚举类型来定义,用于控制控件(如按钮、文本框等)在用户右键点击时如何显示上下文菜单。

以下是 Qt::ContextMenuPolicy 枚举中定义的所有上下文菜单策略:

1. Qt::DefaultContextMenu

  • 含义:使用默认的上下文菜单处理方式。对于大多数控件,这通常意味着当用户右键点击时,会根据操作系统和控件的默认行为显示一个上下文菜单。
  • 示例代码
python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QWidget, QLineEdit

app = QApplication(sys.argv)
window = QWidget()

line_edit = QLineEdit("DefaultContextMenu", window)
line_edit.setContextMenuPolicy(Qt.DefaultContextMenu)

window.show()
sys.exit(app.exec())

• 当单击鼠标右键,弹出默认的菜单。

2. Qt::NoContextMenu

  • 含义 :控件不会显示上下文菜单。当用户在该控件上右键点击时,不会触发任何与上下文菜单相关的操作。**注意:**该策略只是简单地让控件自身不显示上下文菜单,但当用户在这个控件上触发上下文菜单事件(通常是右键点击)时,这个事件会继续向其父控件传播。如果父控件有相应的上下文菜单处理逻辑,那么父控件的上下文菜单可能会显示出来。
  • 示例代码
python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QWidget, QLineEdit

app = QApplication(sys.argv)
window = QWidget()

line_edit = QLineEdit("No Context Menu", window)
line_edit.setContextMenuPolicy(Qt.NoContextMenu)

window.show()
sys.exit(app.exec())

3. Qt::PreventContextMenu

  • 含义:阻止上下文菜单的显示,并且不会向父控件传播上下文菜单事件。这意味着即使父控件有上下文菜单处理逻辑,也不会被触发。
  • 示例代码
python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QApplication, QWidget, QLineEdit, QMenu

app = QApplication(sys.argv)

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("上下文菜单")
        self.resize(300, 200)
    
    # 重写上下文菜单事件
    def contextMenuEvent(self, event):
        # 创建一个菜单
        menu = QMenu(self)

        # 创建菜单项
        action1 = QAction("菜单项1", self)
        action2 = QAction("菜单项2", self)

        # 将菜单项添加到菜单中
        menu.addAction(action1)
        menu.addAction(action2)
        # 在鼠标点击的位置显示菜单
        menu.exec(event.globalPos())
        
window = MyWindow()
line_edit = QLineEdit("PreventContextMenu", window)
line_edit.setContextMenuPolicy(Qt.PreventContextMenu)

window.show()
sys.exit(app.exec())

这个范例中,由于line_edit设置了PreventContextMenu策略,虽然它的父容器定义了菜单,但是阻止了向父控件传播上下文菜单事件,所以点击它没有任何菜单显示。

如果将上述代码修改为DefaultContextMenu策略:

python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QApplication, QWidget, QLineEdit, QMenu

app = QApplication(sys.argv)

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("上下文菜单")
        self.resize(300, 200)

    # 重写上下文菜单事件
    def contextMenuEvent(self, event):
        # 创建一个菜单
        menu = QMenu(self)

        # 创建菜单项
        action1 = QAction("菜单项1", self)
        action2 = QAction("菜单项2", self)

        # 将菜单项添加到菜单中
        menu.addAction(action1)
        menu.addAction(action2)
        # 在鼠标点击的位置显示菜单
        menu.exec(event.globalPos())

window = MyWindow()
line_edit = QLineEdit("PreventContextMenu", window)
line_edit.setContextMenuPolicy(Qt.DefaultContextMenu)

window.show()
sys.exit(app.exec())

它就会显示自己的默认菜单。

或者设置为NoContextMenu策略:

python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QApplication, QWidget, QLineEdit, QMenu

app = QApplication(sys.argv)

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("上下文菜单")
        self.resize(300, 200)

    # 重写上下文菜单事件
    def contextMenuEvent(self, event):
        # 创建一个菜单
        menu = QMenu(self)

        # 创建菜单项
        action1 = QAction("菜单项1", self)
        action2 = QAction("菜单项2", self)

        # 将菜单项添加到菜单中
        menu.addAction(action1)
        menu.addAction(action2)
        # 在鼠标点击的位置显示菜单
        menu.exec(event.globalPos())

window = MyWindow()
line_edit = QLineEdit("PreventContextMenu", window)
line_edit.setContextMenuPolicy(Qt.NoContextMenu)

window.show()
sys.exit(app.exec())

点击后自己的菜单不显示,但是将点击事件传递给了父容器,所以会显示父容器的菜单:

4. Qt::ActionsContextMenu

  • 含义 :控件的上下文菜单由其 actions() 方法返回的动作列表组成。可以通过向控件添加动作(QAction)来定义上下文菜单的选项。
  • 示例代码
python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit

app = QApplication(sys.argv)
window = QWidget()

class MyLineEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

    def setupUi(self, parent):
        self.setText("PreventContextMenu")
        self.setContextMenuPolicy(Qt.ActionsContextMenu)     # 设置上下文菜单策略
        action = QAction("Action 1", self)
        self.addAction(action)   # 创建的时候已经有了Action 1菜单项

line_edit = MyLineEdit(window)

action = QAction("Action 2", line_edit)
line_edit.addAction(action)   # 再添加一个Action 2菜单项

window.show()
sys.exit(app.exec())

进一步的,我们可以读取控件的系统内置默认菜单,并且再后面加上自定义的菜单项:

python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit

app = QApplication(sys.argv)
window = QWidget()

class MyLineEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

    def setupUi(self, parent):
        self.setText("ActionsContextMenu")
        self.setContextMenuPolicy(Qt.ActionsContextMenu)     # 设置上下文菜单策略
        default_actions = self.createStandardContextMenu().actions()   # 获取系统默认的上下文菜单
        self.addActions(default_actions)   # 添加系统默认的上下文菜单

        action = QAction("Action 1", self)   # 创建一个Action 1菜单项
        self.addAction(action)   # 添加Action 1菜单项

line_edit = MyLineEdit(window)

action = QAction("Action 2", line_edit)
line_edit.addAction(action)   # 再添加一个Action 2菜单项

window.show()
sys.exit(app.exec())

5. Qt::CustomContextMenu

  • 含义 :自定义上下文菜单。
    当用户在控件上右键点击时,会发出 customContextMenuRequested 信号,开发者可以连接这个信号到自定义的槽函数,在槽函数中创建并显示自定义的上下文菜单。
  • 示例代码
python 复制代码
import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QWidget, QMenu, QLineEdit

app = QApplication(sys.argv)
window = QWidget()

line_edit = QLineEdit("PreventContextMenu", window)
line_edit.setContextMenuPolicy(Qt.CustomContextMenu)   # 设置上下文菜单策略


# 槽函数
def show_context_menu(pos):
    menu = QMenu(line_edit)
    menu.addAction("Custom Action")
    menu.exec(line_edit.mapToGlobal(pos))

line_edit.customContextMenuRequested.connect(show_context_menu)   # 连接信号和槽

window.show()
sys.exit(app.exec())

除了策略设置setContextMenuPolicy()的方法,还可以使用另一种方法:

通过重新定义contextMenuEvent() 的方法来定义右键菜单

PySide(PyQT)重新定义contextMenuEvent()实现鼠标右键弹出菜单-CSDN博客

相关推荐
深蓝海拓1 小时前
PySide6从0开始学习的笔记(二) 控件(Widget)之容器类控件
笔记·qt·学习·pyqt
叶子丶苏2 小时前
第十七节_PySide6基本窗口控件深度补充_窗口绘图类(QPicture类) 下篇
python·pyqt
深蓝海拓3 小时前
PySide6从0开始学习的笔记(六) 控件(Widget)之按钮类
笔记·python·qt·学习·pyqt
深蓝海拓5 小时前
PySide6从0开始学习的笔记(七) 控件(Widget)之文字输入类控件
笔记·python·qt·学习·pyqt
python开发笔记6 小时前
PyQt(12)TreeWidget与TreeView对比
pyqt
Java Fans14 小时前
PyQt多页面切换教程
pyqt
深蓝海拓1 天前
PySide6从0开始学习的笔记(五) 信号与槽
笔记·qt·学习·pyqt
深蓝海拓2 天前
PySide6从0开始学习的笔记(四)QMainWindow
笔记·python·学习·pyqt
深蓝海拓2 天前
PySide6 的 QSettings简单应用学习笔记
python·学习·pyqt
深蓝海拓3 天前
PySide6从0开始学习的笔记(三) 布局管理器与尺寸策略
笔记·python·qt·学习·pyqt