浅谈Qt QGraphics体系及刷新机制介绍

概述

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

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

QGraphics体系的三大元素

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

  • QGraphicsScene :场景。场景用于装载所有item元素,它是一个无限大的空间,但是我们在使用的时候通常会指定一块区域(setSceneRect)用于安放所有的item元素,并且item之间的逻辑,以及消息传递都是从场景中进行统一管理,比如我门要捕捉鼠标消息,或者触控消息,统一在Scene中获取,然后分发给需要的item,可以说Scene就是一个大管家;
  • QGraphicsView:视图。视图就好比一个窗口,用于展示当前Scene中的元素,上面说到,Scene是一个无限大的空间,当view移动到Scene某个位置,就能看到该位置上的Item元素。
  • QGraphicsItem:每一个单独的图元,QGraphicsItem是一个基类,还有很多子类继承于它,也就是这一系列的item行程了整个QGraphics体系中的每一个图元。

看一下这三者的关系:

再用一个非常形象的类比应该就会很明白这三者的关系了:
Scene就好比天空,无限大,而Item就是天空中的云朵,可以有很多云,而view就好比一扇窗户,透过窗户可以看到天空中的云,而一片天空可以通过很多扇窗户去看。所以一个Scene可以同时对应多个View,但是一个View只能对应一个Scene。

刷新机制

OK ,有了以上铺垫,终于可以进入都今天的主题,QGraphics体系中的刷新机制到底是怎样的呢?

我们都知道,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

设置Item的缓存模式,我们来看一下缓存的类型:

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

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

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来进行设置即可。

到此这篇关于浅谈Qt QGraphics体系及刷新机制介绍的文章就介绍到这了,更多相关Qt QGraphics内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Qt如何设置窗口屏幕居中显示以及设置大小

    Qt如何设置窗口屏幕居中显示以及设置大小 设置窗口居中显示 方法一:在窗口(QWidget类及派生类)的构造函数中添加如下代码: #include <QDesktopWidget> //....... QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以 move((desktop->width() - this->width())/2, (desktop->height()

  • Qt for Android开发实例教程

    本文讲述了使用Qt5.3.0开发Android应用的方法,由于官方资料较少,此处记录开发过程遇到的问题及解决方法.具体步骤如下: 1.Android平台的视频播放,只能使用qml的MediaPlayer 2.qml中控件的路径必须加file://  例如: Image{ source: "file:///mnt/usbhost1/Config/logo.png" } 3.C++与qml中js的方法互调 QQuickView view; view.setSource(QUrl(QStri

  • Qt实现图片移动实例(图文教程)

    这学期实训的时候用MFC做过一个飞机大战,很无聊的东西,一直想用Qt做一个,但是在学校的时候比较颓,回来看了一下. 首先需要解决的问题是图片的移动,怎么说飞机啊子弹啊都是动着的,图片当然要跑起来. 闲话休絮,首先用QtCreator新建一个QtGui程序,命名为PaintWidget,随便起的名字,实验么这不是. 会生成这三个文件,其中呢ui不用管,实验的图片移动需要用的是Event,不是信号槽,所以ui就不管了,放了那就是. 第一步要把图片画出来,参照<Qt学习之路的这段代码>,不难把图画出

  • 深入理解Qt中各种消息框对话框的使用

    最近在学习Qt框架,今天学习了一下消息框的使用, 现整理出来以作记录. 在程序运行时,经常需要提示用户一些信息,比如警告啊,提示啊,建议啊之类的东西.这些东西基本上是通过消息框与用户进行交互的,Qt中主要是用QMessageBox类来加以实现的. 消息框一般分为七种: Question询问消息框:为正常的操作提供一个简单的询问 Information信息消息框:为正常操作提供一个提示 Warning提示消息框:提醒用户发生了一个错误 Critical警告消息框:警告用户发生了一个严重错误 Abo

  • Qt qml中listview 列表视图控件(下拉刷新、上拉分页、滚动轴)

    Qt qml listview下拉刷新和上拉分页主要根据contentY来判断.但要加上顶部下拉指示器.滚动条,并封装成可简单调用的组件,着实花了我不少精力:) 先给大家展示下效果图: [功能] 下拉刷新和上拉分页逻辑 /下拉刷新 /上拉更多 /滚动栏 /工具栏半拉显隐 Author: surfsky.cnblogs.com Lisence: MIT 请保留此文档声明 History: init. surfsky.cnblogs.com, 2015-01 add initPosition pro

  • 在Qt中正确的设置窗体的背景图片的几种方法总结

    Qt中正确的设置窗体的背景图片的方法大致有两种,下面将逐个讲解: 一. 利用styleSheet设置窗体的背景图片 使用stylesheet设置窗体的背景图片的时候,可以直接按照下图的操作去进行即可,如下图所示: 但是,需要注意的是: 1.在QWidget中这种方法是不行的,如果你足够细心的话,你会发现使用同样的设置背景图片的方法,背景图片其实并没有发生真实改变,但是它的子窗体背景图片是会发生改变的. 其实我们可以通过在添加一个i额QWidget来解决这个问题,即在QtDesigner中添加一个

  • Qt实现FTP的上传和下载的实例代码

    为了方便网络编程,Qt 提供了 Network 模块.该模块包含了许多类,本文介绍了Qt实现FTP的上传和下载,分享给大家 本来想简单抄抄书,随便手写个Ftp客户端的,结果发现教材上的是基于Qt4的QFtp类库,而在Qt5中取消了这一个类库(同时也取消了QHttp等的类),取而代之的是QNetworkAccessManager 这个类,把这些杂货全都揽下来了,据说是因为之前的两个类有重复而且效率有问题balabala.于是就百度了一下,发现百度上要么讲的不全,要么就是要去下一个由热心网民重新封装

  • 浅谈Qt QGraphics体系及刷新机制介绍

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

  • 浅谈QT内存泄漏

    目录 01前言 02 QT半自动化内存管理要点 03实验过程详解 Malloc分配的内存空间实践实例 04总结 01前言 前几天,项目开展了一次代码初次评审.会上,领导指出一些可能会带来内存泄漏的代码,如下图所示: 图中的pLayout在new的时候没有指定任何父对象,且MainWindow的析构函数中也没有对pLayout做delete操作,这意味着为pLayout申请的内存空间在程序运行期间是一直没有得到释放的.实际上,项目代码中,还有许多这种"隐患":一个单例类的成员变量在new

  • 浅谈Qt信号与槽的各种连接方式

    目录 简介 连接信号槽 connect 函数的第五个参数 信号与槽的连接方式 简介 信号槽是 Qt 框架引以为豪的机制之一.当用户触发某个事件时,就会发出一个信号(signal),这种发出是没有目的的,类似广播.如果有对象对这个信号感兴趣,它就会连接(connect)绑定一个函数(称为槽slot)来处理这个信号.也就是说当信号发出时,被连接的槽函数会自动被回调.这有点类似与开发模式中的观察者模式,即当发生了感兴趣的事件,某一个操作就会被自动触发 信号和槽是Qt特有的信息传输机制,是Qt设计程序的

  • 浅谈Qt中使用CEF的几个要点(Windows下)

    最近项目中要在Qt中使用CEF(Chromium Embedded Framework),在这里总结下其中的几个要点. 下载合适的CEF版本 关于CEF的简介我们这里就不做介绍了,下载CEF可以有2种选择: 1.源码:强烈不建议下载源代码并编译构建(学习代码除外),下载源码需要你FQ.有良好的网速(要下载)和足够的耐心(据说有4.5个G,真的要下半天). 2.自动构建版本:推荐这个使用这个版本.该版本提供了大部分已经编译完成的动态库及资源,只需要开发者手动编译一个wrapper静态库就可以了.这

  • 浅谈Scrapy框架普通反爬虫机制的应对策略

    简单低级的爬虫速度快,伪装度低,如果没有反爬机制,它们可以很快的抓取大量数据,甚至因为请求过多,造成服务器不能正常工作.而伪装度高的爬虫爬取速度慢,对服务器造成的负担也相对较小. 爬虫与反爬虫,这相爱相杀的一对,简直可以写出一部壮观的斗争史.而在大数据时代,数据就是金钱,很多企业都为自己的网站运用了反爬虫机制,防止网页上的数据被爬虫爬走.然而,如果反爬机制过于严格,可能会误伤到真正的用户请求;如果既要和爬虫死磕,又要保证很低的误伤率,那么又会加大研发的成本. 简单低级的爬虫速度快,伪装度低,如果

  • 浅谈SpringBoot2.4 配置文件加载机制大变化

    前言 Spring Boot 2.4.0.M2刚刚发布,它对 application.properties 和 application.yml 文件的加载方式进行重构.如果应用程序仅使用单个 application.properties 或 application.yml 作为配置文件,那么可能感受不到任何区别.但是如果您的应用程序使用更复杂的配置(例如,Spring Cloud 配置中心等),则需要来了解更改的内容以及原因. 为什么要进行这些更改 随着最新版本 Spring Boot 发布,S

  • 浅谈Servlet的Cookie和Session机制

    一.Servlet Cookies Cookies定义:Cookies是存储在客户端计算机上的文本文件,并保留了用户的各种跟踪信息. Cookies作用:会话保持,如完成用户的登录与状态保持 Cookies的工作原理: 客户端向服务区发起登录请求 服务器脚本(代码)向浏览器发送一组Cookies,例如:姓名,年龄等 浏览器将这些信息存储在本地计算机上,以备将来使用 当下一次浏览器向web服务器发送任何请求时.浏览器会把这些Cookies信息发送到服务器,服务器将使用这些信息来识别账户 1.1 C

  • 浅谈Tomcat如何打破双亲委托机制

    目录 JVM的类加载器 Tomcat的类加载器 findClass loadClass 我们经常会遇到ClassNotFound异常,表明JVM在尝试加载某类时失败了. 要解决这个异常,你得知道 什么是类加载 JVM如何加载类 为什么会出现ClassNotFound 想想Tomcat又是如何加载和管理Web应用下的Servlet呢? Tomcat正是通过Context组件来加载管理Web应用的,所以今天我会详细分析Tomcat的类加载机制.但在这之前,我们有必要预习一下JVM的类加载机制,我会先

  • 浅谈Qt实现HTTP的Get/Post请求

    目录 头文件 Get Post 借助Qt的NetWork模块,可以轻松的实现HTTP的Get/Post请求,而不需要再次引用像libcurl这样的第三方库.当然,Qt的NetWork模块提供的功能远远不只是HTTP方面的. 头文件 #include <QNetworkRequest> #include <QNetworkReply> #include <QNetworkAccessManager> 另外,使用Qt网络模块还需要引用Qt5Network.lib库. Get

  • 浅谈Redis中的自动过期机制

    目录 Redis中的自动过期机制 一.使用Redis Key自动过期机制 二.SpringBoot整合key失效监听 Redis中的自动过期机制 实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态 1.使用Redis Key自动过期出发事件通知2.使用定时任务30分钟后检查3.按照每分钟轮训检查 CREATE TABLE `order_number` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_name` varchar(25

随机推荐