前段时间做过一个界面刷新的优化,遇到的坑比较多,在这里做一点点总结吧。

    优化的方案是滚动滚动条的时候用截屏的方式代替界面全部刷新,优化完成后,界面在滚动时效率能提升大概一倍,背景介绍完毕。
    用到最主要的是QT的截屏功能
    window原生api会提供截屏滚动的功能。可以用这个ScrollWindowEx这个api。它会根据相应的参数在屏幕中进行滚动相应的区域。是不是很容易?但是结果却是不理想,因为用的是Qt,控件重写过PaintEvent的方法。调用api实时能看到效果,但是触发一次PaintEvent之后,界面又恢复原样了。看了Qt源码里后发现Qt内部画的时候是相当于画在后台一个对象里,然后在刷新的时候调用bitblt统一画,调用window的api并不会影响到后面的那个对象,后台刷新的代码在:qwindowsbackingstore.cpp中的flush方法(Qt5.1.1是这个名,但在Qt5.5.1里叫flushDP)。
    这个或许应该是Qt的特点,把操作系统隔离开,有好的地方,在这里又觉得不好。
    Qt里截屏的方式有以下两个,功能如下:
    1:QScreen的grabWindow:不会触发paintEvent消息
    2:QWidget的grab:会触发paintEvent消息,相当于是调用paintEvent在一张图上画。
其它还可以调用QPixmap的两个静态方法(grabWidget跟grabWindow),但看源代码发现不推荐用这两个,应该用上面那两个替代,实现的效果应该是一样的。
    基于业务的需要,很明显得采用1,实现的代码也很简单
    QScreen *pScreen = QGuiApplication::primaryScreen();
    pImage = pScreen->grabWindow(pWidget->winId());

如果需要实现滚动的话,需要调用QPixmap的scroll的方法就可以实现了。然后在PaintEvent里先把截出来的图画上去,然后再画剩下的部分就可以了。

    现在理解的Qwidget的刷新机制是这样的。刷新界面一般都会调用widget的update方法。这个方法在文档里有这么一句
    calling update() several times normally results in just one paintEvent() call。
跟了一下这里的源码,也发现,多次调用的活,它会在里面记录一个dirtyRegion,多次调用的话,会把区域合并在一块,在触发paint消息里统一处理。
画的时候,会根据dirtyRegion的区域只处理那部分。如果你贴图贴了整个窗口的大小,后面重绘了部分区域,很可能会画重,导致显示重叠,这点注意。
    由于业务上比较复杂,截屏的区域需要去算,但原理上应该是上面提到的那样,本人思路有限,如果有更好的实现方法,也可以一块交流,在此表示感谢。

http://blog.csdn.net/hpjx1987/article/details/50634194

Qt刷新机制的一些总结(Qt内部画的时候是相当于画在后台一个对象里,然后在刷新的时候调用bitblt统一画,调用window的api并不会影响到后面的那个对象)的更多相关文章

  1. Qt事件机制(是动作发生后,一种通知对象的消息,是被动与主动的总和。先处理自己队列中的消息,然后再处理系统消息队列中的消息)

    Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...

  2. Qt源码分析之信号和槽机制(QMetaObject是一个内部struct)

    Qt的信号和槽机制是Qt的一大特点,实际上这是和MFC中的消息映射机制相似的东西,要完成的事情也差不多,就是发送一个消息然后让其它窗口响应,当然,这里的消息是广义的说法,简单点说就是如何在一个类的一个 ...

  3. QT内省机制、自定义Model、数据库

    本文将介绍自定义Model过程中数据库数据源的获取方法,我使用过以下三种方式获取数据库数据源: 创建 存储对应数据库所有字段的 结构体,将结构体置于容器中返回,然后根据索引值(QModelIndex) ...

  4. Qt消息机制和事件(二)

    三,事件过滤器 有时候,对象需要查看.甚至要拦截发送到另外对象的事件.例如,对话框可能想要拦截按键事件,不让别的组件接收到:或者要修改回车键的默认处理. 通过前面的章节,我们已经知道,Qt 创建了QE ...

  5. Qt消息机制和事件(一)

    一,事件 事件(event)是由系统或者 Qt 本身在不同的时刻发出的.当用户按下鼠标.敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件.一些事件在对用户操作做出响应时发出,如键盘事件等 ...

  6. Qt事件处理机制

    研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 先给出原文 ...

  7. 【转】Qt 事件处理机制 (下篇)

    转自:http://mobile.51cto.com/symbian-272816.htm 在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent. 接下来依次谈谈Qt中有谁来产生.分 ...

  8. 【转】解读Qt 事件处理机制(上篇)

    [转自]:http://mobile.51cto.com/symbian-272812.htm 在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent. 接下来依次谈谈Qt中有谁来产生 ...

  9. Qt事件机制浅析(定义,产生,异步事件循环,转发,与信号的区别。感觉QT事件与Delphi的事件一致,而信号则与Windows消息一致)

    Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...

随机推荐

  1. 40个Java集合面试问题和答案【中】【转载】

    接上文:http://www.cnblogs.com/xujianbo/p/5148075.html   16.UnsupportedOperationException是什么? Unsupporte ...

  2. ajax.abort 终止AJAX请求

                               $(document).ready(function () { var ajax; $('#choice').change(function() ...

  3. 仿战旗tv

    模仿战旗tv做的一个小项目,还需继续完善. 以下为链接地址: https://github.com/NearMilk/ZhanqiTV

  4. android API文档查询---context、toast、SharedPreferences

    /*查阅api ---context1.abstract AssetManager     getAssets() Returns an AssetManager instance for the a ...

  5. [可拖动DIV]刚开通博客顺便就写了点东西!

    说说我自己的思路 首先需要一个初始div div { border: 1px #333 solid; width: 200px; height: 50px; } <div id="od ...

  6. WPF中实现根据拼音查找汉字

    1.WPF的一个触摸屏项目,需要输入姓名,但是屏幕不支持汉字输入,使用虚拟键盘不稳定,为了解决该问题特此进行处理. 2.新建一个类转换类,里面初始化一个数组,数组包含拼音,以及拼音下的常用的汉字. 3 ...

  7. Delphi IDE下载全地址

    Delphi IDE下载全地址: http://pan.baidu.com/share/home?uk=1060104307#category/type=0 还是网友伟大呀.当然有钱的公司还是应该多多 ...

  8. Style 的优先级

    Dependency Property(简称DP)是WPF的核心,Style就是基于Dependency Property的,关于DP的内幕,请参见深入WPF--依赖属性.Style中的Setter就 ...

  9. WPF中的一些常用类型转换

    1.string和Color的转换: //string转Color (Color)ColorConverter.ConvertFromString((string)str); //Color转stri ...

  10. Mysql,Oracle,Java数据类型对应

    Mysql Oracle Java BIGINT NUMBER(19,0) java.lang.Long BIT RAW byte[] BLOB BLOB RAW byte[] CHAR CHAR j ...