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

news2025/3/29 1:45:03

代码:

# 设置样本图片的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())

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2321175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python自动化测试 之 DrissionPage 的下载、安装、基本使用详解

Python自动化测试 之 DrissionPage 使用详解 🏡前言:一、☀️DrissionPage的基本概述二、 🗺️环境安装2.1 ✅️️运行环境2.2 ✅️️一键安装 三、🗺️快速入门3.1 页面类🛰️ChromiumPage🛫 SessionPage&…

Java替换jar包中class文件

在更新java应用版本的运维工作中,由于一些原因,开发没办法给到完整的jar包,这个时候,就可以只将修改后的某个Java类的class文件替换掉原来iar包中的class文件,重新启动服务即可: 1、将jar包和将要替换的cl…

AI Tokenization

AI Tokenization 人工智能分词初步了解 类似现在这个,一格子 一格子,拼接出来的,一行或者一句,像不像,我们人类思考的时候组装出来的话,并用嘴说出来了呢。

关于大数据的基础知识(四)——大数据的意义与趋势

成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(四&a…

某视频的解密下载

下面讲一下怎么爬取视频,这个还是比小白的稍微有一点绕的 首先打开网址:aHR0cDovL3d3dy5wZWFydmlkZW8uY29tL3BvcHVsYXJfNA 首页 看一下: 有一个标题和一个href,href只是一个片段,待会肯定要拼接, 先找一…

Day20-前端Web案例——部门管理

目录 部门管理1. 前后端分离开发2. 准备工作2.1 创建Vue项目2.2 安装依赖2.3 精简项目 3. 页面布局3.1 介绍3.2 整体布局3.3 左侧菜单 4. Vue Router4.1 介绍4.2 入门4.3 案例4.4 首页制作 5. 部门管理5.1部门列表5.1.1. 基本布局5.1.2 加载数据5.1.3 程序优化 5.2 新增部门5.3…

从切图仔到鸿蒙开发01-文本样式

从切图仔到鸿蒙开发01-文本样式 本系列教程适合 HarmonyOS 初学者,为那些熟悉用 HTML 与 CSS 语法的 Web 前端开发者准备的。 本系列教程会将 HTML/CSS 代码片段替换为等价的 HarmonyOS/ArkUI 代码。 页面结构 HTML 与 ArkUI 在 Web 开发中,HTML 文档结…

菱形虚拟继承的原理

一 :菱形继承的问题 普通的菱形继承存在数据冗余和二义性的问题 ,如下代码: class Person { public:string _name; //姓名 };class Student : public Person { protected:int _num; //学号 };class Teacher : public Person { protected:int…

【数据结构】C语言实现树和森林的遍历

C语言实现树和森林的遍历 导读一、树的遍历二、森林的遍历2.1 为什么森林没有后序遍历?2.2 森林中存不存在层序遍历?三、C语言实现3.1 准备工作3.2 数据结构的选择3.3 树与森林的创建3.4 树与森林的遍历3.4.1 先根遍历3.4.2 后根遍历3.4.3 森林的遍历3.5 树与森林的销毁3.6 算…

第四天 开始Unity Shader的学习之旅之Unity中的基础光照

Unity Shader的学习笔记 第四天 开始Unity Shader的学习之旅之Unity中的基础光照 文章目录 Unity Shader的学习笔记前言一、我们是如何看到这个世界的1. 光源2.吸收和散射3.着色 二、标准光照模型1. 自发光2. 高光反射① Phong模型② Blinn-Phong模型 3.漫反射4.环境光 总结 前…

基于SpringBoot的“社区居民诊疗健康管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“社区居民诊疗健康管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统模块功能结构图 局部E-R图 系统首…

Java-空链基础入门

经过调研和细致观察,我们发现空链对于初次接触或是对Stream和Optional不太熟悉的人来说,确实存在一定的上手难度,宛如开启了“地狱模式”。为了降低这一门槛,我们决定通过一系列由简入深的案例演示,来逐步引导大家掌握…

【江协科技STM32】Unix时间戳BKP备份寄存器RTC实时时钟(学习笔记)

Unix时间戳 Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量世界上所有时区的秒计数器相同,不同时区通过…

3.17-3.23 Web3 游戏周报:Pixudi 双榜领跑,The Forgotten Runiverse 登陆三大主机平台

回顾上周的区块链游戏概况,查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【3.17–3.23】Web3 游戏行业动态 Ronin 将与 Alpha Growth 等合作推出 1300 万美元增长计划,以向 DeFi 扩张Notcoin 开发工作室 Open Builders 宣布推出 Not Games …

AppInventor2生成3位数的水仙花数

生成3位水仙花数(每位数字的立方之和刚好等于这个数字)的代码,如下: 来源:【生成Python】AppInventor2中文网已支持代码块转换Python源码! - App Inventor 2 中文网 - 清泛IT社区,为创新赋能&…

【聚类算法解析系列02】经典聚类算法(上)——K-Means与层次聚类

【聚类算法解析系列02】经典聚类算法(上)——K-Means与层次聚类 引言:算法背后的认知革命 K-Means与层次聚类,这两个诞生于1960年代的算法,至今仍是工业界使用率最高的聚类工具。它们分别代表了两种根本性的世界观&am…

[Effective C++]条款22:将成员变量声明为private

. 在C中,将成员变量声明为private而不是public,主要是为了遵循面向对象编程(OOP)的封装原则。他有助于隐藏对象的内部实现细节,提供更好地控制,安全性和可维护性。 1、数据隐藏与封装 将成员变量声明为pr…

心法利器[132] | 大模型系统性能优化trick

心法利器 本栏目主要和大家一起讨论近期自己学习的心得和体会。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有。 2023年新的文章合集已经发布,获取方式看这里:又添十万字-CS的陋室2023年文章合集来袭,更…

六十天前端强化训练之第三十天之深入解析Vue3电商项目:TechStore全栈实践(文结尾附有源代码)

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗,谢谢大佬! 目录 深入解析Vue3电商项目:TechStore全栈实践 一、项目架构设计 二、核心功能实现 三、组合式API深度实践 四、性能优化实践 五、项目扩展方向 六、开发经验总结…

类与对象(中)(详解)

【本节目标】 1. 类的6个默认成员函数 2. 构造函数 3. 析构函数 4. 拷贝构造函数 5. 赋值运算符重载 6. const成员函数 7. 取地址及const取地址操作符重载 1.类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗&…