【QT】QGraphics体系及刷新机制介绍

2 篇文章 0 订阅

原博客:Qt QGraphics体系及刷新机制介绍-CSDN博客

一、概述

Qt的三大体系:QWidget、QGraphics、Quick,其中QGraphics图形框架算是这三个中比较高级的一种用法了,并且使用起来相比另外两个体系会更加的复杂一些,不过它能实现的功能却非常强大,主要体现在对图元的管理,它独特的刷新机制可以在众多的图元中都能够很好的管理,保证整个交互的流畅度。

而这里要描述的就是QGraphics体系的刷新机制以及该体系中相关元素的使用方式及特点

二、QGraphics体系的三大元素

QGraphics体系中最重要的三大元素:QGraphicsView、QGraphicsScene、QGraphicsItem,这三者构成了QGraphics体系最基础的模型框架,也是在使用过程中必不可少的元素。

1、QGraphicsScene :场景

场景用于装载所有item元素,它是一个无限大的空间,但是我们在使用的时候通常会指定一块区域(setSceneRect)用于安放所有的item元素,并且item之间的逻辑,以及消息传递都是从场景中进行统一管理,比如我门要捕捉鼠标消息,或者触控消息,统一在Scene中获取,然后分发给需要的item,可以说Scene就是一个大管家;

2、QGraphicsView:视图

视图就好比一个窗口,用于展示当前Scene中的元素,上面说到,Scene是一个无限大的空间,当view移动到Scene某个位置,就能看到该位置上的Item元素。

3、QGraphicsItem:每一个单独的图元

QGraphicsItem是一个基类,还有很多子类继承于它,也就是这一系列的item行程了整个QGraphics体系中的每一个图元。

4、三者的关系

Scene就好比天空,无限大,而Item就是天空中的云朵,可以有很多云,而view就好比一扇窗户,透过窗户可以看到天空中的云,而一片天空可以通过很多扇窗户去看。所以一个Scene可以同时对应多个View,但是一个View只能对应一个Scene。

三、刷新机制

我们都知道,QWidget是以窗口式刷新,每次会渲染整个窗口达到刷新目的,而QGraphics中可以局部刷新,也就是说可以只刷新某一个图元,而其他的元素保持不动,这是二者在刷新机制上很大的不同,以致于QGraphics在渲染大量图元的时候也能很流畅。

这里的itemA在刷新的时候,ItemB是不会刷新的,这是两个独立的Item,但是考虑以下这种情况:

当两个item有交集的时候,这时候如果刷新ItemA,那么ItemB也会相应的刷新,同样,刷新ItemB的时候,ItemA也会触发刷新。
并且要注意的是,上面说到的ItemA和ItemB的交集,并不局限于这两者只是在同一平面上真实的交集,也就是说,即便是二者的ZValue不同, 但是从Z轴俯视的角度看到二者有交集也会触发对方相应的刷新。还有一种情况,如果两个Item是父子关系,也会全部刷新。

所以上面图示,即便ItemA和ItemB的ZValue不同,还是会触发刷新。这是QGraphicsItem默认的行为。

那么,这样会带来什么问题呢,如果我们做的是一个实时性非常高的动作,比如在屏幕上画线,线条要实时刷新,而这时候如果同时触发了其他Item的刷新,并且该Item刷新比较耗时,那么就会直接影响我们画线item的刷新,直观的感觉就是卡顿,线条折线严重,因为刷新界面都是在主线程中执行的,耗时操作将会阻塞。

四、避免重复刷新

我们的目的就是即便是多个Item重叠,那在刷新其中一个的时候不要让其他Item也跟着刷新,OK,QGraphicsItem中提供了一个枚举:

enum QGraphicsItem::CacheMode

 

 

默认就是不做缓存,然后每次都会重新绘制。

1、QGraphicsItem::ItemCoordinateCache模式

 QGraphicsItem会创建一个具有可配置大小/分辨率的屏幕外像素缓冲区,但是渲染质量通常会降低,具体取决于缓存的分辨率和项目转换。 第一次重绘项时,它会将自身渲染到缓存中,然后缓存将在每次后续曝光中重复使用。

2、QGraphicsItem::DeviceCoordinateCache模式

此模式适用于可以移动但不旋转,缩放或剪切的项目。 如果直接或间接转换项目,将自动重新生成缓存。 与ItemCoordinateCacheMode不同,DeviceCoordinateCache始终以最高质量呈现。

可以根据实际需要选择使用哪种缓存模式,然后通过调用函数setCacheMode来设置。

函数原型为:

void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize = QSize())

 

可选的logicalCacheSize参数仅由ItemCoordinateCache模式使用,并描述缓存缓冲区的分辨率,如果logicalCacheSize是(100,100),QGraphicsItem将使项目适合图形内存中的100x100像素,而不管项目本身的逻辑大小。

默认情况下,QGraphicsItem使用boundingRect()的大小。对于除ItemCoordinateCache之外的所有其他缓存模式,将忽略logicalCacheSize。
如果项目花费大量时间重绘自身,则缓存可以加快渲染速度。在某些情况下,缓存也会降低渲染速度,特别是当项目花费的时间少于重绘时间时,QGraphicsItem会从缓存中重新绘制。

启用缓存后,项目的paint()函数通常会绘制到屏幕外的pixmap缓存中,对于任何后续重绘请求,Graphics View框架将从缓存中重绘。这种方法特别适用于QGLWidget,它将所有缓存存储为OpenGL纹理。

注意:启用缓存并不意味着只有在响应显式update()调用时才会调用item的paint()函数。例如,在内存压力下,Qt可能决定丢弃一些缓存信息;在这种情况下,即使没有update()调用(也就是说,没有启用缓存),也会调用item的paint()函数。

那么,既然会绘制到pixmap缓存中,如果数据量特别多,导致pixmap缓存不够怎么办,这时候就需要通过更改QPixmapCache的缓存限制以获得最佳性能。

五、QPixmapCache

QPixmapCache类为pixmaps提供应用程序范围的缓存。
此类是使用QPixmap优化绘图的工具。

QPixmapCache不包含任何成员数据,只包含访问全局像素图缓存的静态函数。它创建了一个内部QCache对象来缓存pixmaps。

默认的pixmap缓存空间为10MB,如果我们需要缓存的数据量很大,那么就需要修改这个值,通过调用静态函数setCacheLimit来进行设置即可。

  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 关于Qt QGraphicsView绘制折线的问题,以下是解答: Qt QGraphicsView是一个高级的2D图形控件,是基于MVC架构设计的。QGraphicsView可以用来展示绘制出来的图形,包括图像、文本、图表等等。 要在Qt QGraphicsView中绘制折线,可以使用QGraphicsScene和QGraphicsLineItem等相关类。具体操作可以分为几个步骤: 1.创建QGraphicsScene对象,用来存放绘制的图元。 2.根据需要创建QGraphicsLineItem对象,用来绘制折线。 3.将QGraphicsLineItem对象添加到QGraphicsScene中。 4.创建QGraphicsView对象,将QGraphicsScene设置为其场景。 5.将QGraphicsView对象添加到需要展示的窗口中。 以上就是在Qt QGraphicsView中绘制折线的基本步骤,具体实现可以参考Qt官方文档和示例代码。 ### 回答2: Qt是一个高效、跨平台的C++图形界面开发框架,支持多种绘图和绘制工具,其中包括了QT QGraphicsView。在QT QGraphicsView中,绘制折线可以通过以下步骤实现: 1.创建一个QGraphicsScene对象,该对象将显示在QGraphicsView中 2.在QGraphicsScene中添加一个折线 3.使用QGraphicsView来显示QGraphicsScene中的折线 下面我们将详细说明如何通过步骤来实现。 1.创建QGraphicsScene 在Qt中创建QGraphicsScene对象可使用以下代码: ``` QGraphicsScene *scene = new QGraphicsScene(this); ``` 这个代码创建了一个新的QGraphicsScene对象,应用程序中视图的大小将用于Scene的大小,this指针表示这个画布和QTUI相关。 2.添加折线 接下来,我们将在上一步中创建的画布中添加一条折线。 创建一个QGraphicsLineItem对象 ``` QGraphicsLineItem *line = new QGraphicsLineItem(x1, y1, x2, y2); ``` x1和y1是折线的起点,x2和y2是折线的终点。 将创建的QGraphicsLineItem对象添加到QGraphicsScene中 ``` scene->addItem(line); ``` 3.创建QGraphicsView 创建QGraphicsView对象是将折线显示在屏幕上。以下代码创建了QGraphicsView对象: ``` QGraphicsView *view = new QGraphicsView(scene); ``` scene是指先前创建的QGraphicsScene对象。 完整示例代码: ``` //创建QGraphicsScene对象 QGraphicsScene *scene = new QGraphicsScene(this); //创建折线 QGraphicsLineItem *line = new QGraphicsLineItem(x1, y1, x2, y2); //将折线添加到QGraphicsScene scene->addItem(line); //创建QGraphicsView QGraphicsView *view = new QGraphicsView(scene); //将QGraphicsView视图添加到QtUI界面中 ui->widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); ui->widget->setScene(scene); ``` 通过上面的步骤,可以轻松在Qt中绘制折线,为了更好的用户交互体验,可以增加一些代码来设置折线颜色、线宽度等等。到这里绘制折线已经完成了,现在用户可以在QGraphicsView中与折线进行交互,并进行一些操作,例如缩放、拖拽等等。 ### 回答3: Qt QGraphicsView 是一个强大的图形视图框架,提供了绘制各种图形的方法,包括绘制折线。下面我将介绍如何使用 QGraphicsView 进行折线绘制。 首先,我们需要创建一个 QGraphicsView 对象和一个 QGraphicsScene 对象,并将 QGraphicsScene 对象设置为 QGraphicsView 的场景。接下来,我们需要创建一个 QGraphicsLineItem 对象来表示折线。代码如下: ```cpp QGraphicsView *view = new QGraphicsView(this); QGraphicsScene *scene = new QGraphicsScene(this); view->setScene(scene); QGraphicsLineItem *lineItem = new QGraphicsLineItem(); ``` 然后,我们需要设置线条的起始点和结束点,以及线条的样式。这可以通过 QGraphicsLineItem 的 setLine() 方法来实现。我们还可以通过 QGraphicsLineItem 的 setPen() 方法设置线条的颜色和宽度。示例代码如下: ```cpp lineItem->setLine(0, 0, 100, 100); // 设置起始点和结束点 QPen pen(Qt::red); // 创建颜色为红色的笔 pen.setWidth(2); // 设置线条宽度为 2 lineItem->setPen(pen); // 设置线条样式 ``` 最后,我们需要将 QGraphicsLineItem 对象添加到 QGraphicsScene 中,以便它能够在 QGraphicsView 中进行显示。示例代码如下: ```cpp scene->addItem(lineItem); ``` 综上所述,以上代码展示了如何使用 QGraphicsView 绘制折线。当然,还有很多其他的绘制方法和属性可以应用于 QGraphicsView 和 QGraphicsLineItem 对象,根据实际需求进行选择和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hiOoo.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值