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%。

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

Qt的双缓冲技术(double buffering)相关推荐

  1. 双缓冲(double buffering)的原理和使用

    最近在使用C#做项目的时候发现在加载一个具有大量控件和复杂背景图形的窗口时,会出现很影响视觉体验的频闪问题.最后发现使用双缓冲能很好的解决这个问题.下面就介绍一下双缓冲的原理及使用. 一.双缓冲作用 ...

  2. 基于VC6.0的控制台作图--动画和双缓冲技术

    文章目录 让图形动起来 直接向屏幕作图 使用双缓冲技术 双缓冲技术编程原理 让图形动起来 让图形动起来的办法就是不断定时清屏.重绘.像放电影那样.然而,直接向屏幕绘图是耗时的,在屏幕上画很多线,将多次 ...

  3. android 绘图 双缓存,Android开发之用双缓冲技术绘图

    双缓冲技术主要用在画图,动画效果上.其原理就是:将资源先载入到缓冲区,然后再将缓冲区整个载入到View上面去. 双缓冲技术可以有效防止闪烁.提高显示质量. DrawView.java: package ...

  4. [Winodows图形编程]初识双缓冲技术

    2019独角兽企业重金招聘Python工程师标准>>> 为完成PaintBoardDemo(本人设计的一个基于.NET Framework的WinForm的画图程序),过程中遇到的技 ...

  5. java swing双缓冲_java中的双缓冲技术

    毕业设计有个远程协助功能,得到对方的屏幕后,老是会闪,很是不爽,今天用java的双缓冲技术解决了.代码如下,本类重写了Swing中的JLabel,当Label重绘时,会默认的调用它的update方法, ...

  6. java双缓冲绘图_Java双缓冲技术-绘图应用

    1屏幕产生闪烁的原因 由于在显示所绘制的图像时,调用了repaint方法.repaint方法被调用时,需要清除整个背景,然后才调用paint方法显示画面.这样,在清除背景和绘制图像的短暂时间间隔内被用 ...

  7. 《MFC游戏开发》笔记六 图像双缓冲技术:实现一个流畅的动画

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9334121 作者:七十一雾央 新浪微博:http:// ...

  8. java图片双缓存_Java 双缓冲技术消除图片闪动

    一般在使用Canvas组件刷新显示图片或者绘图的时候,会产生闪烁.这是由于机制是先使用背景色对原有内容进行覆盖,再往上面绘制新内容所引起的.我们看到的闪烁就是背景色和新内容之间的交替显示. 下面为Ca ...

  9. 使用双缓冲技术可轻松消除闪烁

    当应用程序中使用多次GDI调用绘制到窗口中时,在窗口清除并被重新绘制时,会出现明显的闪烁.使用双缓冲技术可轻松消除闪烁. 步骤如下: 1.假设当前显示设备上下文为CDC * pDC; 2.使用CDC对 ...

最新文章

  1. python locale模块_使用python2.X的locale模块格式化数字和货币
  2. JAVA关于父亲节的代码_关于父亲节的经典语录
  3. [云炬学英语]每日一句2020.8.28
  4. Ms SQL Server 约束和规则
  5. 购物车的收货地址js php,Javascript实现购物车功能的详细代码
  6. Android内容提供器——运行权限
  7. cisco初级随堂笔记1
  8. selenium webdriver 右键另存为下载文件(结合robot and autoIt)
  9. 拓端tecdat|R语言量化交易RSI策略:使用支持向量机SVM
  10. C/C++ 编码准则,可借鉴的东西还挺多!
  11. xp系统打印机服务器报错,win10系统连接xp系统共享打印机报错0x000004的具体方法...
  12. 修改IDEA缓存文件路径
  13. 世纪光棍节、神棍节快乐!
  14. 使用idea连接阿里云RDS数据库
  15. html 圆环实现多种颜色,Echart饼图实现(圆环图)+状态颜色控制
  16. excel切片器_大部分人都不知道Excel切片器还能这么用,建议收藏
  17. 2019年奥斯卡获奖电影绿皮书经典台词(中英文对照)
  18. 计算机网络期末总复习——第二章 物理层
  19. 09 CentOS7安装MariaDB(MYSQL分支)
  20. (新版)一分钟经理人读后感

热门文章

  1. [转]乔布斯的薄伽梵歌 Steve’s Bhagavat Gita
  2. Citavi 给参考文献添加编号
  3. tengine mysql_tengine全自动安装
  4. vue 监听TcPlayer腾讯云直播结束方法(使用防抖案例)
  5. 文件密使 v3.7 绿色
  6. 合并排序非递归实现总结
  7. [论文翻译]RetinaFace: Single-stage Dense Face Localisation in the Wild
  8. 我出了道面试题,然后差点被打了
  9. 使用gensim实现lda,并计算perplexity( gensim Perplexity Estimates in LDA Model)
  10. IDEA无法打开标有问号的文件