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博客

相关推荐
小灰灰搞电子4 天前
PyQt 实现蜂巢菜单源码分享
pyqt·鱼眼凸起
znnnk4 天前
【Python】GUI 开发从入门到实战(三):PyQt/PySide 进阶之路
开发语言·python·pyqt
民乐团扒谱机9 天前
【超详细】PyQt6 实现 AU 风格波形图编辑器:多级缩放与采样点逐级渲染,附全过程代码
开发语言·python·编辑器·pyqt·audition·时域·频谱图
典典分享指南10 天前
Excel SUMIFS 跨表汇总实战:多表条件求和的完整指南
django·flask·numpy·pyqt·fastapi
狮子雨恋13 天前
【无标题】
pyqt
微小冷15 天前
pyqt+matplotlib多进程图像刷新
pyqt·matplotlib·进程通信·多进程·queue·process
千里码aicood15 天前
PyQt基于卷积神经网络的智慧校园的设计与实现
人工智能·cnn·pyqt
千里码aicood16 天前
基于PyQt心理咨询机器人智能系统的设计与实现
机器人·pyqt
典典分享指南16 天前
Windows 自动化踩坑实录
python·intellij-idea·pyqt·emacs·visual studio
深蓝海拓19 天前
基于QtPy (PySide6) 的PLC-HMI工程实战记录(五)为当前动作画面的信号连接变量
网络·笔记·python·学习·pyqt