当前位置: 首页 > news >正文

pyside6的QGraphicsView体系,当鼠标位于不同的物体,显示不同的右键菜单

代码:

# 设置样本图片的QGraphicsView模型
from PySide6.QtCore import Qt, QRectF, QObject
from PySide6.QtGui import QPainter, QPen, QColor, QAction, QMouseEvent
from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QGraphicsRectItem, QMenu, QWidget, \
    QVBoxLayout, QFrame, QSizePolicy


# 矩形方框(QGraphicsRectItem)模型
class MyRectItem(QGraphicsRectItem, QObject):
    def __init__(self, *args):
        QGraphicsRectItem.__init__(self, *args)
        QObject.__init__(self)  # 使用父辈的QObject的构造函数,利用它的信号槽机制
        self.menu = QMenu()  # 创建菜单对象

        # 启用鼠标跟踪,以便在没有按下鼠标按钮时也能接收鼠标移动事件
        self.setAcceptHoverEvents(True)

        self.setMenu()  # 设置菜单

    def setMenu(self):
        """设置菜单"""
        action = QAction("方框菜单", self)  # 创建菜单项
        self.menu.addAction(action)  # 将菜单项添加到菜单中

    # def contextMenuEvent(self, event):   # 它也可以拥有自己的右键事件响应
    #     """鼠标右键菜单"""
    #     self.menu.exec(event.screenPos())  # 在鼠标位置显示菜单


# 设置QGraphicsView模型
class MyView(QGraphicsView):
    def __init__(self, parent=None, autoScale=True):
        super().__init__(parent)
        self.autoScale = autoScale  # 自动缩放标志,是否全画幅显示
        self.image_item = QGraphicsPixmapItem()  # 创建图片对象
        self.set_scene()  # 设置场景
        self.set_menu()  # 设置菜单

    def set_scene(self):
        """设置场景"""
        self.scene = QGraphicsScene()  # 创建窗口场景
        # 设置渲染提示
        self.setRenderHint(QPainter.Antialiasing)  # 开启抗锯齿
        self.setRenderHint(QPainter.SmoothPixmapTransform)  # 开启平滑缩放
        # 设置缩放锚点
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)  # 转换时以鼠标为中心
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)  # 缩放时以鼠标为中心
        self.setScene(self.scene)  # 将场景应用到视窗中


    # 处理滚轮事件以实现缩放
    def wheelEvent(self, event):
        """处理滚轮事件以实现缩放"""
        factor = 1.001 ** event.angleDelta().y()  # 滚轮每滚动一格,缩放比例变化
        self.scale(factor, factor)

   

    def set_menu(self):
        """设置菜单"""
        self.menu = QMenu(self)  # 创建菜单对象
        action = QAction("视图菜单", self)  # 创建菜单项
        self.menu.addAction(action)  # 将菜单项添加到菜单中

        self.image_item.menu = QMenu(self)  # 创建菜单对象
        action = QAction("图片菜单", self)  # 创建菜单项
        self.image_item.menu.addAction(action)  # 将菜单项添加到菜单中

    # 设置图像文件
    def set_image(self, pixmap):
        self.scene.clear()  # 清空场景
        self.scene_rect = QRectF(0, 0, pixmap.width(), pixmap.height())  # 设置场景范围
        self.image_item.setPixmap(pixmap)  # 创建图片对象
        self.scene.addItem(self.image_item)  # 将图片对象添加到场景中
        self.setAlignment(Qt.AlignmentFlag.AlignCenter)  # 设置视图对齐方式
        if self.autoScale:
            self.fitInView(self.image_item, Qt.AspectRatioMode.KeepAspectRatio)  # 设置视图适应图片,全幅显示

    def contextMenuEvent(self, event):
        """鼠标右键菜单"""
        item = self.itemAt(event.pos())  # 获取鼠标位置处的图形项
        if item is None:  # 如果鼠标位置没有图形项
            self.menu.exec(event.globalPos())  # 在鼠标位置显示菜单

        else:
            try:
                item.menu.exec(event.globalPos())  # 在鼠标位置显示菜单
            except AttributeError:
                pass


if __name__ == "__main__":
    import sys
    from PySide6.QtWidgets import QApplication
    from PySide6.QtGui import QPixmap

    app = QApplication(sys.argv)
    widget = QWidget()  # 创建窗口对象
    widget.resize(800, 600)  # 设置窗口大小
    widget.layout = QVBoxLayout(widget)  # 创建垂直布局对象
    widget.view = MyView(widget)  # 创建MyView对象
    widget.layout.addWidget(widget.view)  # 将视图添加到布局中

    pixmap = QPixmap("flower.jpg")  # 创建QPixmap对象

    widget.show()  # 显示窗口
    widget.view.set_image(pixmap)  # 设置图像文件
    widget.view.scene.addItem(MyRectItem(100,100,100,100))  # 添加矩形框
    widget.view.scene.addItem(MyRectItem(300, 300, 100, 100))  # 添加矩形框

    sys.exit(app.exec())  # 进入程序的主循环,并通过exit()函数确保主循环安全结束

或者:

import sys
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QGraphicsPixmapItem, QMenu
from PySide6.QtGui import QPixmap, QAction


class CustomGraphicsView(QGraphicsView):
    def __init__(self):
        super().__init__()
        scene = QGraphicsScene()
        # 添加图片
        pixmap = QPixmap("flower.jpg")
        pixmap_item = QGraphicsPixmapItem(pixmap)
        scene.addItem(pixmap_item)
        # 添加两个方框
        rect_item1 = QGraphicsRectItem(100, 100, 50, 50)
        rect_item2 = QGraphicsRectItem(200, 200, 50, 50)
        scene.addItem(rect_item1)
        scene.addItem(rect_item2)
        self.setScene(scene)

    def contextMenuEvent(self, event):
        item = self.itemAt(event.pos())
        if item:
            menu = QMenu(self)
            if isinstance(item, QGraphicsPixmapItem):
                action = QAction("图片右键菜单选项", self)
                menu.addAction(action)
            elif isinstance(item, QGraphicsRectItem):
                action = QAction("方框右键菜单选项", self)
                menu.addAction(action)
            menu.exec(event.globalPos())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    view = CustomGraphicsView()
    view.show()
    sys.exit(app.exec())

 

相关文章:

  • 【自学笔记】Spark基础知识点总览-持续更新
  • 解决PowerShell下Git中文乱码问题
  • vmwaretools解压失败|vmware tools distrib cannot mkdir read only file system|bug汇总
  • OpenResty(Lua)+Redis实现动态封禁IP
  • 朴素贝叶斯:文本处理中的分类利器
  • 3. 轴指令(omron 机器自动化控制器)——>MC_ResetFollowingError
  • 计算机网络的分类——按照按拓扑结构分类
  • django定时任务方案比对
  • PCL—voxel点云网格化
  • 软件功能性测试工具有哪些?专业软件测试服务推荐
  • 深入解析嵌入式内核:从架构到实践
  • 2025红明谷writeup
  • 【零基础学python】python基础语法(二)
  • UE4学习笔记 FPS游戏制作15修正可以换枪中可以继续换枪和开火的Bug
  • 大数据Trino面试题及参考答案
  • SQL Server行转列操作及PIVOT运算符
  • react 大屏根据屏幕分辨率缩放
  • Qt 重入和线程安全
  • 【线程安全问题的原因和方法】【java形式】【图片详解】
  • 深入理解 tree 命令行工具:目录结构可视化的利器
  • 金融创新破局记:中小微企业转型背后的金融力量
  • 巴防长称中俄可参与克什米尔恐袭事件国际调查,外交部回应
  • “中国游”带火“中国购”,“即买即退”让外国游客购物更丝滑
  • 财政部下达农业生产防灾救灾资金3.76亿元,支持黄淮海等地抗旱保春播
  • 第一集丨《无尽的尽头》值得关注,《榜上佳婿》平平无奇
  • 持续更新丨伊朗官员:港口爆炸事件已致5人死亡