• 1623阅读
  • 3回复

[原创]Qt update刷新之源码分析总结 [复制链接]

上一主题 下一主题
离线it文艺男
 

只看楼主 倒序阅读 楼主  发表于: 2021-03-13

大家好,我是IT文艺男,来自一线大厂的一线程序员
经过前面几次的Qt源码讲解,我相信大家对Qt update刷新机制从底层原理上有了一个深刻的理解;这次做一个收尾总结,来复盘前面几次所讲解的内容;

分析的切入点、思考点::

在做GUI开发时,要让控件刷新,会调用update函数;那么在调用了update函数后,Qt究竟基于什么原理、执行了什么代码使得屏幕上有变化?

分析的过程分解::

一、刷新事件异步投递过程
二、刷新事件的处理流程
三、绘制到内存Image
四、刷新结果输出到屏幕

一、刷新事件异步投递过程

分析void QWidget::update()函数的源码,即调用update没有传递参数,则默认刷新控件的整个区域,调用重载的update函数[list=1]
  • 如果控件是隐藏或者刷新被禁用,则直接返回
  • 参数传递的矩形与控件矩形的交集,如果为空,则直接返回
  • 如果支持BackingStore(默认支持),则标脏该控件所属的顶层窗口(TLW:: topLevelWidget缩写)区域,即调用tlwExtra->backingStoreTracker->markDirty(r, this);函数
    a、把控件加入到dirtyWidgets容器中(addDirtyWidget函数)
    b、通知tlw进行刷新(sendUpdateRequest函数)
    sendUpdateRequest函数Post一个QEvent::UpdateRequest事件,即放入事件队列中,立即返回;QEvent::UpdateRequest事件的接受者为tlw;
    window.open('http://www.qtcn.org/bbs/attachment/Mon_2103/17_208164_ad8e241b7da9724.png?157');" style="max-width:700px;max-height:700px;" onload="if(is_ie6&&this.offsetWidth>700)this.width=700;" >

    二、刷新事件的处理流程

    追踪QEvent::UpdateRequest事件处理,进入消息通知流程,即QApplication::notify(QObject *receiver, QEvent *e)函数(没有对QEvent::UpdateRequest事件进行处理),进一步由QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)函数处理;
    receiver的event函数不做处理,其调用父类的event函数,即bool QWidget::event(QEvent *event)函数,该函数中针对事件类型进行处理(switch case);
    对于QEvent::UpdateRequest事件处理,QWidgetBackingStore::doSync函数中调用tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, 0, this);函数进行绘制,函数的第一个参数是获取绘制设备,对于Windows平台,绘制目的设备为内存Image

    三、绘制到内存Image

    回到QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,QPainter *sharedPainter, QWidgetBackingStore *backingStore)函数

    函数主体内容如下::
    1、绘制背景
    2、绘制前景(send the paint event)
    3、绘制子控件(paintSiblingsRecursive函数调用)
    QWidgetPrivate::paintSiblingsRecursive函数里又会调用QWidgetPrivate::drawWidget函数从而形成树形绘制

    四、刷新结果输出到屏幕

    qtbase\src\plugins\platforms\windows目录中的QWindowsBackingStore::flush函数中会调用BitBlt函数(Windows API函数)


    关注我的微信公众号(itwenyinan)下载完整的讲解视频、PPT、Code;


    下载后包括如下内容::


  • 4条评分好评度+1贡献值+1金钱+10威望+1
    20091001753 好评度 +1 - 2021-03-13
    20091001753 贡献值 +1 - 2021-03-13
    20091001753 威望 +1 - 2021-03-13
    20091001753 金钱 +10 - 2021-03-13
    我的微信公众号itwenyinan,高质量技术平台
    离线liudianwu

    只看该作者 1楼 发表于: 2021-03-14
    大佬开始进军公众号和培训了
    欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
    离线liulin188

    只看该作者 2楼 发表于: 2021-03-14
    回 liudianwu 的帖子
    liudianwu:大佬开始进军公众号和培训了 (2021-03-14 11:40) 

    培训来钱快,一割一大把
    https://wiki.qt.io/Qt_5.12_Release
    https://wiki.qt.io/New_Features_in_Qt_5.12
    https://wiki.qt.io/Qt_5.12.0_Known_Issues
    https://www.qt.io/blog/qt-5.13.2-released
    https://www.qt.io/blog/qt-creator-4.10.2-released
    https://wiki.qt.io/Qt_5.12_Tools_and_Versions
    离线it文艺男

    只看该作者 3楼 发表于: 2021-03-14
    回 liulin188 的帖子
    liulin188:培训来钱快,一割一大把 (2021-03-14 18:24) 

    不割韭菜;例如买本喜欢的书籍,相当于为知识付费
    我的微信公众号itwenyinan,高质量技术平台
    快速回复
    限100 字节
     
    上一个 下一个