Qt的双缓冲技术(double buffering)

Qt的双缓冲技术(double buffering)Qt的双缓冲技术(doublebuffering)是Qt绘画机制的一部分,是一种在Qt4中被全面采用的技术。其核心是:把一个窗口部件渲染到一个脱屏pixmap(off-screenpixmap)中,然后再把这个pixmap复制到显示屏幕上。这样做的目的是用于消除屏幕的闪烁并且因而界面会显得更漂亮。Qt4中,Qt会自动处理这些情况,所以在普通的绘画中,我们不必要关注这些内容。QT取消双

大家好,又见面了,我是你们的朋友全栈君。

      Qt的双缓冲技术(double buffering)是Qt绘画机制的一部分,是一种在Qt4中被全面采用的技术。其核心是:把一个窗口部件渲染到一个脱屏pixmap(off- screen pixmap)中,然后再把这个pixmap复制到显示屏幕上。这样做的目的是用于消除屏幕的闪烁并且因而界面会显得更漂亮。Qt4中,Qt会自动处理这些情况,所以在普通的绘画中,我们不必要关注这些内容。

QT取消双缓冲的方法是setAttribute( Qt::WA_PaintOnScreen)



      在更详细的说明这一技术前,gemfield需要简单介绍一下Qt的绘画机制。Qt的绘画机制本质上是提供了2个工具:QPainter和 QPaintDevice,分别代表人类世界的画笔和画板。Gemfield要完成一次绘画,就必须有个画笔(QPainter),另外,还得解决画笔画在哪儿(画板,QPaintDevice)的问题。Qt中的画板是QPaintDevice,当然,gemfield用到的都是它的子类,也就是具体哪种画板:它们是:QWidget、 QImage、QPicture、 QPixmap等,也就是每一个可见的控件(QWidget的子类)都是画板(在其paintEvent()里绘画)。




      那么gemfield本文开始处提到的双缓冲技术是怎么做到消除屏幕闪烁的呢?其核心原因有2点:




      1、 把核心的绘制工作转到屏幕之外完成,而在屏幕显示的时候,只是简单的内存复制。


      2、 只对窗口部件的一部分进行重绘时,另外一部分就不需要重绘,也变成了简单的内存复制——将当前界面不需要重绘的像素复制到脱屏像素,再在脱屏像素上完成剩余的绘制,再通过内存复制映射到屏幕显示上。




      Gemfield再通过一个叫做GemfieldFuwaArrow的程序(内含一个简单的绘制函数,其运行在SYSZUXpad上)简单介绍一下:




void SYSZUXArrow::syszuxRotate(float angle)


{



this_angle=angle;


refreshPixmap();


update();


}




      1、 当SYSZUXpad通过总线接收到的角度有变化时,就调用refreshPixmap()函数来进行重新绘制,不过这是在脱屏的pixmap上进行绘制。然后再调用update()来执行paintEvent()。




void SYSZUXArrow::refreshPixmap()


{



pixmap->fill(this,0,0);


this_width=width();//控件的宽度


this_height=height();//控件的高度


QColor this_color(127, 0, 127);//颜色


static const QPoint syszux_arrow[3] = {



QPoint(this_width/2, 10),


QPoint(this_width/2+5, 20),


QPoint(this_width/2-5, 20)


};//箭头的坐标


QPainter painter(pixmap);


painter.initFrom(this);


painter.setRenderHint(QPainter::Antialiasing, true);


QPen pen(Qt::white);


painter.setPen(pen);


painter.drawLine(0,this_height/2,this_width,this_height/2);//x


painter.drawLine(this_width/2,0,this_width/2,this_height);//y


QPen syszux_pen(this_color,2);


//QPainter painterArrow(pixmap);


painter.setRenderHint(QPainter::Antialiasing, true);


painter.setPen(syszux_pen);


painter.translate(this_width/2,this_height/2);


painter.setBrush(this_color);


painter.rotate(this_angle);


painter.translate(-this_width/2,-this_height/2);


painter.drawLine(this_width/2,this_height/2,this_width/2,20);


int a=(this_height/2.0-10)-((this_height/2-20)/100.0*gemfield_percent);


painter.drawEllipse(this_width/2-10,a,20,20);


painter.drawConvexPolygon(syszux_arrow, 3);


}




      2、在refreshPixmap()函数中,pixmap->fill(this,0,0);函数使用this控件的背景色或背景图片来填充当前脱屏的这个pixmap,后面两个参数是偏移量,也就是this左上角的点映射到pixmap上的哪里。这里是0,就表明完全重合、一模一样。 painter.initFrom(this);函数可以设置painter所使用的画笔、背景色、字体,让其和this控件一样。




void SYSZUXArrow::paintEvent(QPaintEvent *)


{



QPainter painter(this);


painter.drawPixmap(0,0,*pixmap);


}




      3、 通过把pixmap复制到窗口部件的(0,0)位置来完成整个图形的绘制工作。




      其实,在这样一个简单的绘图工作中,这样的技术大可不必。而且随着半导体技术的进步,双缓冲所能发挥出的功能相对减少。




      另外一个不容忽视的问题是,使用双缓冲技术会增加系统的负载。因为相比普通的绘制,它多出了一些工作。比如在SYSZUXpad上运行  GemfieldFuwaArrow程序时,双缓冲时cpu的利用率是50%,而没有采用双缓冲时,cpu的利用率是37%。




      其实这也说明了一个本质的问题,界面的绚烂总是靠硬件性能的提升获得的

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143445.html原文链接:https://javaforall.net

(0)
上一篇 2022年5月21日 下午5:20
下一篇 2022年5月21日 下午5:20


相关推荐

  • js合并数组与合并对象的区别_js将对象转为数组

    js合并数组与合并对象的区别_js将对象转为数组一、数组合并1、for循环会改变原数组,如果不想改变原数组需要生成一个新数组leta=[1,2,3];letb=[4,5];//1for循环for(variinb){a.push(b[i]);}console.log(a);//[1,2,3,4,5]2、concat()concat()方法用于连接两个或多个数组,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本

    2025年7月23日
    3
  • pycharm设置固定默认开头文字

    pycharm设置固定默认开头文字具体设置路径 File gt settings gt Editor gt FileandCodeT gt PythonScript

    2026年3月19日
    2
  • DB9串口定义及含义(全)

    DB9串口定义及含义(全)RS232接口是1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。  它的全名是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”该标准规定采用一个25个脚的DB25连接器,对连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。DB25的串口

    2022年4月8日
    526
  • java 实现MQTT客户端

    java 实现MQTT客户端简介 MQTT MessageQueui 消息队列遥测传输协议 是一种基于发布 订阅 publish subscribe 模式的 轻量级 通讯协议 该协议构建于 TCP IP 协议上 可以以极少的代码和有限的带宽 为连接远程设备提供实时可靠的消息服务 三种消息发布服务质量 至多一次 消息发布完全依赖底层 TCP IP 网络 会发生消息丢失或重复 至少一次 确保消息到达 但消息重复可能会发生 只有一次 确保消息到达一次 在一些要求比较严格的计费系统中

    2025年7月27日
    5
  • spring整合log4j_spring连接数据库的配置

    spring整合log4j_spring连接数据库的配置常用日志框架log4j、log4j2(log4j的升级版,最常用的)、logback(spring boot默认)、Jboss-logging…等slf4 是日志接口规范,代码对接slf4,实现和具体日志框架解耦,无需修改编码即可切换日志框架。修改pom依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-st

    2022年8月8日
    4
  • Vue进阶(四十三):Vuex之Mutations详解

    Vue进阶(四十三):Vuex之Mutations详解通俗的理解 mutations 里面装着一些改变数据方法的集合 这是 Veux 设计很重要的一点 就是把处理数据逻辑方法全部放在 mutations 里面 使得数据和视图分离 2 怎么用 mutations mutation 结构 每一个 mutation 都有一个字符串类型的事件类型 type 和回调函数 handler 也可以理解为 type handler 这和订阅发布有点类似 先注册事件 当触发

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号