ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于backingStore和updateRequest事件

2022-09-01 08:35:14  阅读:160  来源: 互联网

标签:QWidgetPrivate syncBackingStore QWidgetBackingStore UpdateRequest QWidgetWindow 


关于backingStore的同步

QWidgetBackingStore::sync说起, 调用关系如下:

QWidgetPrivate::syncBackingStore
    => QWidgetBackingStore::sync
        => QWidgetBackingStore::markDirtyOnScreen
        => QWidgetBackingStore::doSync
            => QWidgetBackingStore::resetWidget
            => QWidgetPrivate::drawWidget
                => QWidgetPrivate::paintBackground
                => QWidgetPrivate::sendPaintEvent
                    => QWidget::paintEvent
                => QWidgetPrivate::paintSiblingsRecursive
            => QWidgetBackingStore::flush

QWidgtBackingStore只对QWidget可见, 所以QWidgetPrivate::syncBackingStoreQWidgetBackingStore::sync做了进一步封装, 其他地方可以通过widget的D指针调到QWidgetPrivate::syncBackingStore.
QWidgetPrivate::syncBackingStore主要是QWdiget在处理UpdateRequest事件的时候调到:

QWidget::event(QEvent::UpdateRequest)
    => QWidgetPrivate::syncBackingStore

关于updateRequest事件

至于UpdateRequest事件的来源, 搜代码, 找到的就QWidgetBackingStoreQWidgetWindow(QWindow)这两个地方.

  • 先说说QWidgetBackingStore.
    会向widget发UpdateRequest事件的就QWidgetBackingStore::sendUpdateRequest一个地方, 这个sendUpdateRequest又是给WidgetBackingStore::markDirty用的:
QWidgetBackingStore::markDirty (updateNow)
    => QWidgetBackingStore::addDirtyWidget
    => QWidgetBackingStore::sendUpdateRequest
        => QApplication::sendEvent(widget, QEvent::UpdateRequest) (or postEvent)

再上一层就到了QWidget::repaintQWidget::update:

QWidget::repaint(const QRegion &rgn)
    => QWidgetPrivate::repaint
        => QWidgetBackingStore::markDirty (updateNow)


QWidget::update(const QRect &rect)
    => QWidgetPrivate::update
         => QWidgetBackingStore::markDirty (updateLatter)

这两个算是QWidget最终暴露给上层应用的api了. 看实现都是调的QWidgetBackingStore::markDirty, 不同之处仅是传的参数, 前者是立即触发UpdateRequest事件, 后者也会触发UpdateReques事件但是走的是事件循环.

repaint最终会立即触发paintEvent, 多用于动画的绘制.

连续多次调update最终只会触发一次paintEvent. 因为QApplication::compressEvent中对UpdateRequest事件做了压缩. 算是Qt做的一点优化. Qt也是比较建议用update.

按钮hover效果的刷新就是在处理鼠标事件的时候调了QWidget::update.

  • 再看看QWidgetWindow这边的情况.
QWidgetWindow::event(QEvent::Resize)
    => QWidgetWindow::handleResizeEvent
        => QWidgetPrivate::syncBackingStore

QWidgetWindow::event(QEvent::Expose)
    => QWidgetWindow::handleExposeEvent
        => QWidgetPrivate::syncBackingStore

QWidgetWindow::repaintWindow()
    => QWidgetBackingStore::markDirty(updateNow, BufferInvalid)

QWindow::requestUpdate
    => QPlatformWindow::requestUpdate
        => QPlatformWindow::deliverUpdateRequest
             => QCoreApplication::sendEvent(window, QEvent::UpdateRequest);
                => QWidgetWindow::event(QEvent::UpdateRequest)
                    => QWidget::repaint

看了下, QWidgetWindow这边会触发到backingStore更新的有上面四个地方. 前面两个两个很好理解, 窗口大小改变(Resize)和窗口显示(Expose)的时候会触发. 第三个和屏幕相关的, 从QWindow::setScreen触发过来的, 场景未知, 先略过.

至于最后一个, QWidgetWindow在处理UpdateRequest事件的时候会触发widget的重绘. 这个UpdateRequest事件最终来自QWindow::requestUpdate, 是暴露给上层应用的api. 只能说Qt的设计就是如此,QWindow::requestUpdate向本窗口发一个UpdateRequest事件,
然后派生类QWidgetWindow在处理UpdateRequest事件的时候转调widget的重绘.

标签:QWidgetPrivate,syncBackingStore,QWidgetBackingStore,UpdateRequest,QWidgetWindow,
来源: https://www.cnblogs.com/snail-0304/p/16645162.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有