PyQtNode Editor 第二篇自定义可视化视图

在这里插入图片描述
在第一篇博客中,我们已经完成了 PyQtNode Editor 的基础环境搭建,并深入解析了自定义图形场景QDMGraphicsScene的实现原理。那个带有网格背景的场景就像一张空白的图纸,现在我们要在这张图纸上开始绘制真正的节点系统。

今天我们将聚焦于节点编辑器的核心数据结构设计,实现 “节点类” 与 “图形节点类” 的分离,并完成第一个可交互节点的创建。这一步是整个编辑器的骨架,就像建造房屋时搭建承重结构一样关键。

一、自定义可视化视图函数

创建一个node_graphic_view.py文件
在 PyQtNode Editor 的开发过程中,图形视图的设置对于用户最终看到的界面效果和操作体验至关重要。接下来,我们深入解析QDMGraphicsView类的代码,看看它是如何定制图形场景的显示与交互的。
导入必要的模块

from PyQt5.QtWidgets import QGraphicsView​
from PyQt5.QtCore import *from PyQt5.QtGui import *

from PyQt5.QtWidgets import QGraphicsView:从PyQt5.QtWidgets模块中导入QGraphicsView类。QGraphicsView是 PyQt5 中用于显示QGraphicsScene(图形场景)的视图类,它就像是一个 “画框”,可以将在场景中绘制的图形、节点等内容展示出来,并且提供了缩放、滚动等与图形交互的功能基础。​
from PyQt5.QtCore import *:导入PyQt5.QtCore模块中的所有内容。这个模块包含了 PyQt5 的核心功能,例如信号与槽机制、定时器、元对象系统等,这些功能为图形视图的事件处理、状态管理等提供底层支持 。​
from PyQt5.QtGui import *:导入PyQt5.QtGui模块中的所有内容。该模块主要用于处理图形相关的操作,比如绘制图形、设置画笔和画刷样式、处理字体等,是实现图形视图美观显示效果的关键。

定义 QDMGraphicsView 类

class QDMGraphicsView(QGraphicsView):

这里定义了一个名为QDMGraphicsView的类,它继承自QGraphicsView。继承的作用在于,QDMGraphicsView类可以复用QGraphicsView类已有的功能,同时在此基础上添加或修改特定的功能,以满足 PyQtNode Editor 项目中对于图形视图的个性化需求。

    def __init__(self, grScene, parent=None):super().__init__(parent)​self.grScene = grScene​
​self.initUI()​
​self.setScene(self.grScene)

super().init(parent):调用父类QGraphicsView的初始化方法,确保父类的属性和行为得到正确的初始化,就像建造房子时先搭建好基本的框架结构。​
self.grScene = grScene:将传入的图形场景对象grScene赋值给当前类的实例属性self.grScene。这样,QDMGraphicsView类的实例就与特定的图形场景建立了关联,后续视图展示的内容就是这个场景中的元素。​
self.initUI():调用自定义的initUI方法,用于对图形视图进行一些个性化的设置,比如渲染效果、滚动条策略等。​
self.setScene(self.grScene):将之前保存的图形场景对象self.grScene设置为当前图形视图要显示的场景。这一步就像是把一幅画放入画框中,图形视图会将场景中的图形、节点等内容展示出来供用户查看和交互。

def initUI(self):self.setRenderHints(QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

self.setRenderHints(QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform):通过setRenderHints方法设置图形渲染的提示选项。这里使用了按位或操作组合了多个渲染提示:​
QPainter.Antialiasing:启用抗锯齿功能,使绘制的图形边缘更加平滑,避免出现锯齿状。​
QPainter.HighQualityAntialiasing:进一步提高抗锯齿的质量,让图形看起来更加精美。​
QPainter.TextAntialiasing:对文本进行抗锯齿处理,保证显示的文字清晰、美观。​
QPainter.SmoothPixmapTransform:使图像在缩放或变换时更加平滑,避免出现模糊或失真的情况。​
self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate):使用setViewportUpdateMode方法设置视图端口的更新模式为QGraphicsView.FullViewportUpdate。这意味着每当场景发生变化时,整个视图端口都会被更新。虽然这种方式在性能上可能不如其他更精细的更新模式,但可以确保视图显示的内容始终是最新和完整的。​
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)和self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff):分别设置水平和垂直滚动条的策略为Qt.ScrollBarAlwaysOff,即始终隐藏滚动条。这表明在当前的设计中,不希望用户通过滚动条来滚动视图,可能是因为场景的尺寸设置以及整体交互设计不需要滚动条,或者后续会通过其他方式(如鼠标滚轮缩放等)来实现对场景的浏览。

完整代码node_graphic_view.py

# 导入PyQt5的QGraphicsView类,用于显示和操作QGraphicsScene中的内容
from PyQt5.QtWidgets import QGraphicsView
# 导入PyQt5的核心模块,包含信号与槽、事件系统等基础功能
from PyQt5.QtCore import *
# 导入PyQt5的GUI模块,包含绘图、字体、颜色等图形相关功能
from PyQt5.QtGui import *# 自定义图形视图类,继承自QGraphicsView,用于显示和操作节点编辑器的图形场景
class QDMGraphicsView(QGraphicsView):# 类的构造函数,接收图形场景对象和可选的父对象def __init__(self, grScene, parent=None):# 调用父类的构造函数完成初始化super().__init__(parent)# 保存传入的图形场景对象的引用self.grScene = grScene# 初始化用户界面设置self.initUI()# 将图形场景设置到视图中,使视图显示该场景的内容self.setScene(self.grScene)# 初始化用户界面的方法,设置视图的各种属性和行为def initUI(self):# 设置渲染提示,启用多项抗锯齿和高质量渲染选项:# - Antialiasing:平滑图形边缘,减少锯齿# - HighQualityAntialiasing:使用更高质量的抗锯齿算法# - TextAntialiasing:平滑文本边缘,提高可读性# - SmoothPixmapTransform:平滑处理缩放和变换后的像素图self.setRenderHints(QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)# 设置视图更新模式为完全更新,每次场景变化时重绘整个视图# 这种模式确保显示效果一致,但可能影响性能self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)# 设置水平滚动条策略为始终关闭,不显示水平滚动条self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)# 设置垂直滚动条策略为始终关闭,不显示垂直滚动条self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

二、调用自定义视图函数

回到node_graphic_wnd.py文件
导入我们自定义的画布样式:

from node_graphics_view import QDMGraphicsView

然后对原来系统的标准视图更改成我们自定义的视图:
这个是原来的

self.view = QGraphicsView(self)
self.view.setScene(self.grScene)

更改后的:

    self.view = QDMGraphicsView(self.grScene, self)

然后添加一个addDebugContent()方法向场景中添加了多种图形元素用于测试:

def addDebugContent(self):# 创建绿色画刷和黑色轮廓画笔greenBrush = QBrush(Qt.green)outlinePen = QPen(Qt.black)outlinePen.setWidth(2)# 添加可移动的矩形rect = self.grScene.addRect(-100, -100, 80, 100, outlinePen, greenBrush)rect.setFlag(QGraphicsItem.ItemIsMovable)# 添加可选择和移动的文本text = self.grScene.addText("This is my Awesome text!", QFont("Ubuntu"))text.setFlag(QGraphicsItem.ItemIsSelectable)text.setFlag(QGraphicsItem.ItemIsMovable)text.setDefaultTextColor(QColor.fromRgbF(1.0, 1.0, 1.0))# 添加可移动的按钮控件widget1 = QPushButton("Hello World")proxy1 = self.grScene.addWidget(widget1)proxy1.setFlag(QGraphicsItem.ItemIsMovable)proxy1.setPos(0, 30)# 添加可选择的文本编辑控件widget2 = QTextEdit()proxy2 = self.grScene.addWidget(widget2)proxy2.setFlag(QGraphicsItem.ItemIsSelectable)proxy2.setPos(0, 60)# 添加可选择和移动的线条line = self.grScene.addLine(-200, -200, 400, -100, outlinePen)line.setFlag(QGraphicsItem.ItemIsMovable)line.setFlag(QGraphicsItem.ItemIsSelectable)

最终完整的node_graphic_wnd.py文件

# 从PyQt5的QtWidgets模块导入所有的类和函数,该模块包含各种用于创建用户界面的组件,如窗口、按钮、布局等
from PyQt5.QtWidgets import *
# 从PyQt5的QtGui模块导入所有的类和函数,此模块用于处理图形相关操作,如画笔、画刷、字体、绘图等功能
from PyQt5.QtGui import *
# 从PyQt5的QtCore模块导入所有的类和函数,该模块提供了PyQt5的核心功能,包括信号与槽机制、事件循环、定时器等
from PyQt5.QtCore import *# 从自定义模块node_graphics_scene中导入QDMGraphicsScene类,该类用于创建自定义的图形场景
from node_graphics_scene import QDMGraphicsScene

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

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

相关文章

【扩欧应用】同余方程

与扩欧的联系 在同余方程的求解过程中,我们通常需要将方程转化为线性不定方程(Diophantine 方程)的形式,然后使用扩展欧几里得算法(Extended Euclidean Algorithm, EEA)求解。 同余方程是怎么转化为线性不…

结构化数据:NumPy 的结构化数组

文章目录 结构化数据:NumPy 的结构化数组探索结构化数组的创建更高级的复合类型记录数组:结构化数组的变体走向 Pandas 结构化数据:NumPy 的结构化数组 虽然我们的数据通常可以用同质数组很好地表示,但有时情况并非如此。本文将演…

phpcms 更换新域名更新栏目url和内容页url无法更新解决方法

更换域名后更新栏目url和内容页url还是无法更新为新的域名,手动把cache文件夹下能清除的缓存文件清除了还是不行,把数据库的缓存表内容清空了还是不行,问题在于栏目缓存并没有清除。 解决办法: (1)、找到文件:/caches/configs/sys…

玛哈特七辊矫平机:板材平整的精密卫士

在金属板材加工领域,表面平整度是衡量产品质量的核心指标之一。无论是汽车覆盖件、精密仪器外壳,还是建筑装饰板材,任何弯曲、波浪或翘曲都将严重影响后续加工精度、产品强度及美观度。七辊矫平机,凭借其独特的辊系结构设计&#…

融合聚类与分类的退役锂电智能分选技术:助力新能源汽车产业可持续发展

融合聚类与分类的退役锂电智能分选技术:助力新能源汽车产业可持续发展 关键词:退役锂离子电池分选 | 聚类分类融合 | 电化学阻抗谱(EIS) | 动态时间规整(DTW) | 多模态分类模型 新能源汽车 | 电池梯次利用 | 增量学习 | 数字孪生 | 联邦学习 | 双流特征…

jenkins中执行python脚本导入路径错误

🧾 问题一:ModuleNotFoundError: No module named jenkins 🔍 现象: 在本地运行正常,但在 Jenkins 中运行脚本时报错,提示找不到 jenkins 模块。 ❓ 原因分析: Python 默认只从当前目录或已…

华为云Flexus+DeepSeek征文 | 华为云ModelArts Studio实战指南:创建高效的AingDesk知识库问答助手

华为云FlexusDeepSeek征文 | 华为云ModelArts Studio实战指南:创建高效的AingDesk知识库问答助手 前言一、ModelArts Studio介绍1. 华为云ModelArts Studio简介2. 华为云ModelArts Studio主要特点3. 华为云ModelArts Studio主要使用场景 二、AingDesk介绍1. AingDes…

NLP基础1_word-embedding

基于github项目:https://github.com/shibing624/nlp-tutorial/tree/main 自然语言处理任务 1) 简单任务 拼写检查 Spell Checking 关键词检索 Keyword Search 同义词查找 Finding Synonyms 2) 中级任务 解析来自网站、文档等的信息 3) 复杂任务 机器翻译 Ma…

ClickHouse系列--BalancedClickhouseDataSource实现

clickhouse-jdbc中负载均衡数据源的实现。 基本逻辑如下: 1.通过配置的url串,来切分构造url列表; 2.通过一个定时线程任务,来不断的去ping url列表,来更新可用的url列表; 3.在可用列表中随机返回一个可用ur…

Linux目录说明

Linux Filesystem Hierarchy Standard(FHS) 1. /bin 全称:Binary(二进制文件)功能:存放系统最基础的可执行命令,所有用户(包括普通用户)都能使用,用于系统启…

鸿蒙 Grid 与 GridItem 深度解析:二维网格布局解决方案

一、引言:网格布局 —— 多维度数据展示的黄金方案 在鸿蒙应用开发体系中,网格布局作为处理多元素有序排列的核心方案,广泛应用于电商商品陈列、图片画廊、功能矩阵等场景。鸿蒙提供的 Grid 与 GridItem 组件通过声明式语法构建灵活的二维布…

​​Vue 开发环境配置:使用 devServer.proxy 解决跨域问题​-vue中文件vue.config,js中配置devserver做反向代理到后端

​​Vue 开发环境配置:使用 devServer.proxy 解决跨域问题​​ ​​引言​​ 在现代 Web 开发中,前端和后端通常独立开发,前端运行在 http://localhost:8080,而后端可能运行在 http://localhost:8000 或其他端口。由于浏览器的 …

JVM 中的 GC 算法演进之路!(Serial、CMS、G1 到 ZGC)

引言 想象一下,Java 程序运行就像在一个巨大的图书馆里借书还书。这个图书馆(JVM 的内存堆区)为了高效运转,需要一个聪明的“图书管理员”来清理失效的书籍(垃圾对象)。这,就是垃圾回收器&#…

(9)python+playwright自动化测试-页面(page)

1.简介 通过前边的讲解和学习,细心认真地你可能发现在Playwright中,没有Element这个概念,只有Page的概念,Page不仅仅指的是某个页面,例如页面间的跳转等,还包含了所有元素、事件的概念,所以我们…

《自动控制原理 》- 第 1 章 自动控制的基本原理与方式

1-1 自动控制的基本原理与方式 自动控制是指在没有人直接参与的情况下,利用外加的设备或装置,使机器、设备或生产过程的某个工作状态或参数按照预定的规律运行。自动控制的核心原理是反馈控制,即通过将系统的输出量回送到输入端,与…

DL00715-基于YOLOv11的水面漂浮物目标检测含数据集

【论文必备】基于YOLOv11的水面漂浮物目标检测——让你的研究走在科技前沿! 在环境监测、海洋保护和水质管理领域,水面漂浮物的检测一直是一个亟待解决的难题。传统的人工巡检方式不仅耗时费力,还无法覆盖广泛的水域范围。如今,基…

权电阻网络DAC实现电压输出型数模转换Multisim电路仿真——硬件工程师笔记

目录 1 基础知识 1.1 运算放大器在DAC中的作用 1.2 常见的基于运算放大器的DAC电路 1.2.1 倒T形电阻网络DAC 1.2.2 权电阻网络DAC 1.2.3 开关电容DAC 1.3 运算放大器的选择 1.4 设计注意事项 2 仿真实验 2.1 权电阻网络DAC实现数字0对应电压输出 2.2 权电阻网络DAC实…

Redis主从集群

✅ 一、什么是 Redis 主从集群? Redis 主从(Master-Slave)集群是一种最基础的集群方式: 一台 Redis 作为主节点(Master),负责写操作; 一到多台 Redis 作为从节点(Slave&…

【水印论文阅读1】将水印规则的定义域从离散的符号空间转移到连续的语义空间

【水印论文阅读1】将水印规则的定义域从离散的符号空间转移到连续的语义空间 写在最前面**为什么“token序列空间”有根本缺陷?****为什么“语义向量空间”能破局?****1. 连续性(抗攻击的核心)****2. 高维复杂性(防破解…

Glide缓存机制

一、缓存层级与设计目标 双级缓存: 内存缓存:弱引用 LruCache 磁盘缓存:DiskLruCache 设计目标: 减少网络流量消耗 避免Bitmap频繁创建/销毁引发的GC 提升图片加载速度 二、内存缓存机制 1. 双缓存结构 缓存类型存储对象…