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

    优化的方案是滚动滚动条的时候用截屏的方式代替界面全部刷新,优化完成后,界面在滚动时效率能提升大概一倍,背景介绍完毕。
    用到最主要的是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. java.lang.RuntimeException: Unable to instantiate activity ComponentInfo异常总结

    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo异常总结 做android开发的可能都碰到"j ...

  2. 对象创建型模式------Builder(生成器)

    本文系转载,转载地址http://blog.sina.com.cn/s/blog_59b6af690100zj3l.html,只供自己学习使用. 假设现在有三种产品,是玩具,都是由三部分组成,头,身体 ...

  3. linux 文本编辑器 vim 基本操作

    三种模式之间转换: 一般模式 可用于光标移动.复制粘贴.查找替换 "vim.txt"表示文件名 8L 表示8行 , 80C 表示80个字符 移动光标常用操作: h .j. k. l ...

  4. Flex布局新旧混合写法详解(兼容微信)

    原文链接:https://www.usblog.cc/blog/post/justzhl/Flex布局新旧混合写法详解(兼容微信) flex是个非常好用的属性,如果说有什么可以完全代替 float 和 ...

  5. CruiseControl.NET : svnrevisionlabeller

    How to use svnrevisionlabeller as your labeller type in CC.NET: 1. Download ccnet.SvnRevisionLabelle ...

  6. 九度OJ 1163 素数

    题目地址:http://ac.jobdu.com/problem.php?pid=1163 题目描述: 输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和 ...

  7. Nosql_笔记

    Nosql: http://www.infoq.com/cn/news/2011/01/nosql-why/ Redis: http://www.jb51.net/article/59294.htm ...

  8. 使用webstorm上传代码到github

    使用webstorm上传代码到github 字数681 阅读330 评论0 喜欢5 之前使用过webstorm上传代码到github,过了几个月竟然发现自己忘记了,好记性不如烂笔头啊,今天又重新用了一 ...

  9. mac下如何查看指定端口被谁占用并且杀死该进程

    在本地部署 Web 应用时我有遇到过某网络端口已经被其他程序占用的情况,这时候就需要先退出占用该端口的进程,我们可以通过“终端”来实现结束占用某特定端口的进程 1.打开终端,使用如下命令: lsof ...

  10. js中的referrer返回上一页使用介绍

    js中的referrer的用法举例. js完整代码:  <script language="javascript">  var refer=document.refer ...