Qt 绘图之QGraphicsScene QGraphicsView QGraphicsItem详解

article/2025/11/3 23:10:59

  Graphics View提供了一个界面,它既可以管理大数量的定制2D graphical items,又可与它们交互,有一个view widget可以把这些项绘制出来,并支持旋转与缩放。这个柜架也包含一个事件传播结构,对于在scene中的这些items,它具有双精度的交互能力。Items能处理键盘事件,鼠标的按,移动、释放、双击事件,也可以跟踪鼠标移动。Graphics View使用BSP树来提供对item的快速查找,使用这种技术,它可以实时地绘制大规模场景,甚至以百万items计。Graphics View在Qt 4.2中被引用,它替代了它的前辈QCanvas。

Graphics View的体系结构

Graphics View提供的是一种类似于Qt model-view的编程。多个views可以监视同一个场景,而场景包含多个具有多种几何外形的items。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

场景

  QGraphicsScene 表示Graphics View中的场景,它有以下职责: 为管理大量的items提供一个快速的接口。

传播事件到每个item。 管理item的状态,例如选择,焦点处理。 提供未经变换的渲染功能,主要用于打印。

场景作为QGraphicsItem对象的容器。通过调用QgraphicsScene::addItem()把这些Items加入到场景中。可以使用众多的查找函数来获取特定的items。QGraphicsScene:items()与它的许多重载函数可获取那些与点、矩形,多边形,向量路径等相交或是有包含有关系的items。QGraphicsScene::itemAt()返回特定上最顶端的item。

所有的item查找函数都以出栈序列返回(也就是说,第一个返回的是最顶端的,最后一个返回的是最底端的)。    

QGraphicsScene scene; QGraphicsRectItem *rect=scene.addRect(QRectF(0,0,100,100)); QGraphicsItem *item=scene.itemAt(50,50); //item==rect; QGraphicsScene的事件传播结构会把场景事件投递到items,也管理多个items之间的传递。假如场景收到了鼠标在某个位置press事件,场景会把这个事件投递给处在那个位置的item。

QGraphicsScene也管理某种item状态,像选择与焦点。你可以通过调用QGraphicsScene::setSelectionArea()来选择items,它需要提供一个任意的形状为参数。这个函数也作为在QGraphicsView实现橡皮筋选择功能的一个基础。为得到这些已经被选择的items,调用QGraphicsScene::selectedItem()。另一个状态处理是是否一个item拥有键盘输入焦点。你可以调用QGraphicsScene::setFocusItem()或QGraphics::setFocus()来设定焦点,也可用QGraphicsScene::focusItem()来得到当前拥有焦点的那个item。最后,QGraphicsScene允许你通过调用QGraphicsScene::render()函数把部分场景送到绘图设备进行渲染。

CSDN Qt大纲:Qt开发必备技术栈学习路线和资料

视图

  QGraphicsView提供了视图部件,它可视化场景中的内容。你可以联结多个视图到同一个场景,对这个相同的数据集提供几个视口。视口部件是一个滚动区域,它提供了滚动条以对大场景进行浏览。为了使用OpenGL,你应该调用QGraphicsView::setViewport()来把一个QGLWidget设为视口。视图从键盘,鼠标接收输入事件,在发送这些事件到场景之前,会对这些事件进行适当的翻译(把事件坐标转换成对应的场景坐标)。利用转换矩阵,QGraphicsView::matrix(),视图可变换场景的坐标系统。这允许高级的导航特性,如缩放,旋转。为了方便,QGraphicsView也提供了在视

图与场景之间进行坐标转换的函数:

QGraphicsView::mapToScene(),QGraphicsView::mapForScene()。

  The Item QGraphicsItem 是场景中图形items的基类。Graphics View 提供了一些标准的、用于典型形状的items。像矩形(QGraphicsRectItem),椭圆(QGraphicsEllipseItem),文本(QGraphicsTextItem),当你写定制的item时,那些最有用的一些QGraphicsItem特性也是有效的。除此这外,QGraphicsItem支持以下特性: *鼠标按、移动、释放、双击事件,鼠标悬停事件,滚轮事件,弹出菜单事件。 *键盘输入焦点,键盘事件。 *拖拽 *组,包括父子关系,使用QGraphicsItemGroup *碰撞检测 Items如同QGraphicsView一样,位于本地坐标系,它也为item与场景之间,item与item之间的坐标转换提供许多工具函数。而且,也像QGraphicsView一样,它使用矩阵来变换它的坐标系统:QGraphicsItem::matrix()。它对旋转与缩放单个的Item比较有用。 Items可以包含别的items(孩子)。父items的转换被它的子孙所继承。然而,它的所有函数(也就是,  QGraphicsItem::contains(),QGraphicsItem::boundingRect(),QGraphicsItem::collidesWith()),不会积累这些转换,依然在本地坐标下工作。 QGraphicsItem通过QGraphicsItem::shape(),QGraphicsItem::collideWith())来支持碰撞检测。这两个都是虚函数。从shape()返回你的item的形状(以本地坐标QPainterPath表示),QGraphicsItem会为你处理所有的碰撞检测。假如你想提供自己的碰撞检测,你应该重新实现QGraphicsItem::collideWith()。

Graphics View 坐标系统

  Graphics View基于笛卡尔坐标系。item在场景中的位置与几何形状通过x,y坐标表示。当使用未经变形的视图来观察场景时,场景中的一个单位等于屏幕上的一个像素。在Graphics View中有三个有效的坐标系统:Item坐标系,场景坐标系,视图坐标系。为了简化你的实现,Graphics View提供了方便的函数,允许三个坐标系之间相互映射。 当渲染时,Graphics View的场景坐标对应于QPainter的逻辑坐标,视图坐标与设备坐标相同。

Item坐标

  Items位于它们自己的坐标系中。它的坐标都以点(0,0)为中心点,这也是所有变换的中心点。在item坐标系中的几何图元,经常被称为item点,item线,item矩形。当创建一个定制的item,item坐标是所需要考虑的。  QGraphicsScene与QGraphicsView可以为你执行所有转换,这使得实现定制的item变得容易。举例来说,假如你收到鼠标按或是拖进入事件,事件的位置以item坐标的形式给出。QGraphicsItem::contain()虚函数,当某个点的位置在你的item范围内时,返回true,否则返回false。这个点参数使用item坐标,相似地,item的包围矩形与形状也使用item坐标。 Item位置指的是item的中心点在它父亲的坐标系中的坐标。以这种思想来看,场景指的就是那些祖先最少的item的“父亲”。最上级的Item位置就是在场景中的位置。 子坐标与父坐标之间是相关的,假如孩子未经变换,子坐标与父坐标之间的差值等于在父坐标系下,父item与子item之间的距离。例如,假如一个未经变换的子item位置与其父item的中心重合,那么这两个item的坐标系统完全相同。如果孩子的位置是(10,0),那么孩子坐标系中的(0,10)点,对应于父坐标系中的(10,10)点。 因为item的位置与变换是相对于父item的,子item的坐标不会被父亲的变换影响,尽管父item的变换隐含地对子item做了变换。在上面的例子中,即使父item旋转,缩放,子item的(0,10)点依然对应于父item的(10,10)点。然而,相对于场景来讲,子item会遵循父item的变换。假如父item被缩放(2X,2X),子item的位置在场景中的坐标是(20,0),它的(10,0)点则与场景中的(40,0)对应 。除了QGraphicsItem::pos(),QGraphicsItem的函数以Item坐标工作,如一个item’s包围矩形总是以item坐标的形式给出。

场景坐标

  场景坐标系统描述了每个最顶级item的位置,也是从视图向场景投递场景事件的基础。场景中的每个item有场景位置与包围矩形(QGraphicsItem::scenePos(),QGraphicsItem::sceneBoundingRect()), 另外,它有自己本地item位置与包围矩形。场景位置描述了item在场景坐标下的位置,它的场景包围矩形则用于QGraphicsScene决定场景中哪块区域发生了变化。场景中的变化通过QGraphicsScene::changed()信号来通知,它的参数是场景矩形列表。

视图坐标

  视图坐标是widget的坐标,视图坐标中每个单位对应一个像素。这种坐标的特殊之处在于它是相对于widget或是视口的,不会被所观察的场景所影响。QGraphicsView的视口的左上角总是(0,0),右下角总是(视口宽,视口高)。所有的鼠标事件与拖拽事件,最初以视图坐标表示,就应该把这些坐标映射到场景坐标以便与item交互。

坐标映射

  经常,处理场景中item时,在场景与item之间,item与item之间,视图与场景之间进行坐标映射,形状映射是非常有用的。

举例来讲,当你在QGraphicsView的视口中点击鼠标时,你应该通过调用QGraphicsView::mapToScence()与QGraphicsScene::itemAt()来获知光标下是场景中的哪个item。

假如你想获知一个item位于视口中的什么位置,你应该先在item上调用QGraphicsItem::mapToScene(),然后调用QGraphicsView::mapFromScene()。最后,假如你想在一个视图椭圆中有哪些items,你应该把QPainterPath传递到mapToScene(),然后再把映射后的路径传递到QGraphicsScene::items()。 你可以调用QGraphicsItem::mapToScene()与QGraphicsItem::mapFromScene()在item与场景之间进行坐标与形状的映射。也可以在item与其父item之间通过QGraphicsItem::mapToParent()与QGraphicsItem::mapFromItem()进行映射。所有映射函数可以包括点,矩形,多边形,路径。视图与场景之间的映射也与此类似。对于从视图与item之间的映射,你应该首先映射到场景,然后再从场景向item进行映射。

关键特性

缩放与旋转

  QGraphicsView通过QGraphicsView::setMatrix()支持同QPainter一样的仿射变换,通过对一个视图应用变换,你可以很容易地支持普通的导航特性如缩放与旋转。下面是一个例子: class View:;public QGraphicsView { Q_OBJECT //….. public slots: void zoomIn() {scale(1.2,1.2);} void zoomOut() {scale(1/1.2,1/1.2);} void rotateLeft() {rotate(-10);} void rotateRight() {rotate(10);} }; 这些槽应与QToolButtons联接,并使autoRepeat有效。当对视图变换时,QGraphicsView会对视图中心进行校正。

拖拽

  因为QGraphicsView继承自QWidget,它也提供了像QWidget那样的拖拽功能,另处,为了方便,Graphics View柜架也为场景,每个item提供拖拽支持。当视图接收到拖拽事件,它可翻译为QGraphicsSceneDragDropEvent,再发送到场景。

场景接管这个事件,把它发送到光标下接受拖拽的第一个item。 从一个item开始拖拽时,创建一个QDrag对象,传递开始拖拽的那个widget的指针。Items可以同时被多个视图观察,但只有一个视图可以开始拖拽。拖拽在多数情况下是从按下鼠标或是移动鼠标开始的,因此,在 mousePressEvent()或mouseMoveEvent()中,你可以从事件中得到那个原始的widget指针,例如: void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { QMimeData *data=new QMimeData; data->setColor(Qt::green); QDrag *drag=new QDrag(event->widget()); drag->setMimeData(data); drag->start(); } 为了在场景中载取拖拽事件,你应重新实现QGraphicsScene::dragEnterEvent()和在QGraphicsItem的子类里任何与你特定场景需要的事件处理器。

items也可以通过调用QGraphicsItem::setAcceptDrops()获得拖拽支持,为了处理将要进行的拖拽,你需要重新实现QGraphicsItem::dragEnterEvent(),QGraphicsItem::dragMoveEvent(),QGraphicsItem::dragLeaveEvent()和QGraphicsItem::dropEvent()。

光标与工具提示

  像QWidget一样,QGraphicsItem也支持光标(QgraphicsItem::setCursor)与工具提示(QGraphicsItem::setToolTip())。当光标进入到item的区域,光标与工具提示被QGraphicsView激活(通过调用QGraphicsItem::contains()检测)。你也可以直接在视图上设置一个缺省光标(QGraphicsView::setCursor)。

动画

  Graphics View支持几种级别的动画。你可以很容易地通过把QGraphicsItemAnimatoin与你的item联结来 装配出动画路径,这允许以时间线来控制动画,在所有平台上以稳定的速率运作。QGraphicsItemAnimation允许你为item的位置,旋转,缩放,剪切,变换等产生一条路径,动画可以用QSlider来控制,或更为普遍使用的QTimeLine。 另一种是从QObject和QGraphicsItem继承,item可以设置自己的定时器,以在QObject::timeEvent()中增加步进的方式来控制动画。 第三种,是通过调用QGraphicsScene::advance()来推进场景,它又依次调用QGraphicsItem::advance().

OpenGL渲染

  为了使用OpenGL渲染,你要设置一个新的QGLWidget作为QGraphicsView的视口:QGraphicsView::setViewPort()。假如你让OpenGL提供反锯齿功能,你需要OpenGL采样缓冲支持。 QGraphicsView view(&scene); view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));

Item组

  通过把一个item做为另一个item的孩子,你可以得到item组的大多数本质特性:这些items会一起移动,所有变换 会从父到子传递。QGraphicsItem也可以为它的孩子处理所有的事件,这样就允许以父亲代表它所有的孩子,可以有效地把所有的items看作一个整体。 另外,QGraphicsItemGroup是一个特殊的item,它既对孩子事件进行处理又有一个接口把items从一个组中增加和删除。把一个item加到 QGraphicsItemGroup仍会保留item的原始位置与变换,而给一个item重新指定父item则会让item根据其新的父亲重新定位。可以用QGraphicsScene::createItemGroup()建组。

 1 //myitem.cpp2 //myitem.h3 #ifndef MYITEM_H4 #define MYITEM_H5 #include <QGraphicsItem>6 class MyItem : public QGraphicsItem7 {8 public:9     MyItem();
10     QRectF boundingRect() const;
11     void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget);
12 };
13 #endif // MYITEM_H
 1 //myitem.cpp2 #include "myitem.h"3 #include4 5 MyItem::MyItem()6 {7 8 }9 
10 QRectF MyItem::boundingRect() const
11 {
12     qreal adjust=0.5;
13     return QRectF(-18-adjust,-22-adjust,36+adjust,60+adjust);
14 }
15 
16 void MyItem::paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget)
17 {
18     painter->drawRect(0,0,200,200);
19 }
 1 //main.cpp2 23 #include <QtGui/QApplication>4 #include 5 #include 6 #include 7 #include 8 #include"myitem.h"9 
10 int main(int argc, char *argv[])
11 {
12     QApplication a(argc, argv);
13     QGraphicsScene scene;
14     scene.setSceneRect(-300,-300,600,600);
15     scene.setItemIndexMethod(QGraphicsScene::NoIndex);
16     MyItem *item=new MyItem;
17     scene.addItem(item);
18     QGraphicsView view(&scene);
19     view.setRenderHint(QPainter::Antialiasing);
20     view.setCacheMode(QGraphicsView::CacheBackground);
21     view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
22     view.setDragMode(QGraphicsView::ScrollHandDrag);
23     view.resize(400,300);
24     view.show();
25     return a.exec();
26 }

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓


http://chatgpt.dhexx.cn/article/u76rfgjD.shtml

相关文章

PyQt5:QGraphicsScene入门一:基本介绍、场景定义、添加元素

为什么80%的码农都做不了架构师?>>> 简介说明: 这个QGraphicsScene类用于在场景中操作大量的2D图形元素,这个类是作为一个容器QGraphicsItems存在的,它是连同QGraphicsView用于可视化的二维表面的图形项目,如直线,矩形,文本,甚至定制物品;还可以有效地…

QGraphicsView,QGraphicsScene和QGraphicsItem

图形视图框架提供了一个基于图形项的模型视图编程方法&#xff0c;主要由场景、视图和图形项三部分组成&#xff0c;这三部分分别由QGraphicsScene、QGraphicsView和QGraphicsItem这三个类来表示。 场景QGraphicsScene QGraphicsScene类提供绘图场景&#xff08;Scene&#…

Qt图形视图框架:QGraphicsScene详解

一、描述 1、场景提供了一个用于管理大量2D图形项的平面。该类充当图形项的容器。 它与视图一起用于可视化2D曲面上的图形图形项。 2、场景没有自己的视觉外观&#xff0c;只负责管理图形项。 3、场景的最大优势之一就是其快速有效地定位图形项的能力。即使场景中有数百万个…

Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/117660217 长期持续带来更多项目与技术分享&#xff0c;咨询请加QQ:21497936、微信&#xff1a;yangsir198808 红胖子(红模仿)的博文大全&#xff1…

TLS、SSL原理解析

TLS、SSL https协议就是建立在TLS、SSL之上的。

SSL证书原理讲解

SSL证书原理讲解 - 2240930501 - 博客园一直以来都对数字证书的签发&#xff0c;以及信任等事情一知半解。总算有个闲适的周末来总结和深入一下相关的知识。 CA: CA(Certificate Authority)是证书的签发机构&#xff0c;它是负责管理和签发证书的https://www.cnblogs.com/dingl…

浅谈SSL/TLS工作原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 浅谈SSL/TLS工作原理 SSL对称加密非对称加密定义工作过程特点及性能分析非对称加密常用算法举例 非对称加密和对称加密各自有啥优缺点&#xff1f;CA&#xff08;Certificate…

SSL工作原理介绍以及java实现

SSL工作原理介绍以及java实现 目录 SSL工作原理介绍以及java实现 SSL简介SSL工作原理 握手协议Handshake protocol 1握手阶段使用RSA加密算法2握手阶段使用Diffie-Hellman加密算法记录协议Record protocol警报协议Alert protocolWireshark抓包图解java实现Secure Sockets Laye…

SSL证书原理是什么?ssl证书工作流程是什么

SSL证书的运用促使网址更加安全性&#xff0c;做为一种加密传输协议书技术性。SSL的挥手协议书让顾客和集群服务器进行彼此之间的身份验证。为了让各位能进一步了解ssl证书&#xff0c;小编来向各位介绍SSL证书原理。 SSL证书原理如下&#xff1a; ①手机客户端向网络服务器恳…

SSL 工作原理

博客引用处&#xff08;以下内容在原有博客基础上进行补充或更改&#xff0c;谢谢这些大牛的博客指导&#xff09;&#xff1a; SSL工作原理 首先说明下SSL工作原理&#xff1a; 1.1 产生背景 基于万维网的电子商务和网上银行等新兴应用&#xff0c;极大地方便了人们的日常生活…

SSL原理介绍

SSL原理介绍 SSL——安全套接字层&#xff08;Secure Sockers Layer&#xff09;协议由著名的Netscape公司开发。为了保证通信双方建立安全可靠的传输隧道&#xff0c;SSL使用PKI中的数字证书技术对通信双方进行身份认证&#xff1b;使用对称加密来保证数据保密性&#xff1b;使…

ssl 原理和建立连接过程

ssl 与http关系 ssl (“Secure Sockets Layer”)加密原理 和https的关系 https http ssl ssl 位置&#xff1a; SSL握手 证书主要作用是在SSL握手中&#xff0c;我们来看一下SSL的握手过程 客户端提交https请求服务器响应客户&#xff0c;并把证书公钥发给客户端客户端验…

SSL/TLS 的工作原理

HTTPS 之所以能达到较高的安全性要求,就是结合了 SSL/TLS 和 TCP 协议,对通信数据进行加密,解决了 HTTP 数据透明的问题。接下来重点介绍一下 SSL/TLS 的工作原理。 SSL 和 TLS 的区别? SSL 和 TLS 没有太大的区别。 SSL 指安全套接字协议(Secure Sockets Layer),首次…

SSL工作原理

公钥和私钥 一直以来对公钥和私钥都理解得不是很透彻&#xff0c;感觉到模棱两可。今天在网上找了半天&#xff0c;通过查看对这个密钥对的理解&#xff0c;总算弄清楚了。 公钥和私钥就是俗称的不对称加密方式&#xff0c;是从以前的对称加密&#xff08;使用用户名与…

SSL技术原理

SSL详解 建议直接看这&#xff1a;https://cshihong.github.io/2019/05/11/SSL-VPN%E6%8A%80%E6%9C%AF%E5%8E%9F%E7%90%86/ SSL [虚拟专用网络]的技术主要用到了SSL技术。有关SSL具体技术&#xff0c;可以参考&#xff1a; SSL/TLS协议详解 SSL [虚拟专用网络]简介 SSL [虚拟专…

SSL协议原理详解

SSL 可参考&#xff1a;SSL技术原理 SSL简介 SSL和TLS&#xff1a; SSL (Secure Sockets Layer&#xff09;安全套接层。是由Netscape公司于1990年开发&#xff0c;用于保障Word Wide Web&#xff08;WWW&#xff09;通讯的安全。主要任务是提供私密性&#xff0c;信息完整性…

SSL协议原理

文章目录 SSL协议原理SSL协议结构SSL原理&#xff08;握手协议&#xff09;SSL握手协议第一阶段客户端Client Hello数据包服务端server Hello数据包 SSL握手协议第二阶段**Certificate消息数据包**Server Key Exchange消息数据包ServerHello Done数据包 SSL握手协议第三阶段Cli…

关于SSL原理的详解

关于SSL原理的详解 SSL原理详解一、SSL是什么&#xff1f;二、建立SSL通道过程1.简化篇2.具体建立过程 总结 SSL原理详解 其实SSL从网上看到的资料很多了&#xff0c;但是发现还是没有将原理讲得特别清楚&#xff0c;尤其是对CA&#xff0c;433端口与80端口的数据传输原理&…

ExpandableListView--基本使用介绍

1 什么是ExpandableListView&#xff1f;有啥作用? 首先看一张ExpandableListView 的继承关系图&#xff1a; ExpandableListView的继承关系 根据上图可知&#xff0c;ExpandableListView是ListView的子类。而expandable 在英文中的意思是可扩展的&#xff0c;所以ExpandableL…

ExpandListview

土鳖程序员 【深入篇】自定义ExpandableListView&#xff0c;实现二级列表效果 先看效果图&#xff1a; 上图是我们要实现的效果&#xff0c;那么现在我们开始着手去做&#xff0c;主要分为以下几步&#xff1a; 一丶我们需要根据效果图去思考该如何动手&#xff0c;从上图分析…