首页 > 其他分享 >关于backingStore和updateRequest事件

关于backingStore和updateRequest事件

时间:2022-09-01 08:11:06浏览次数:70  
标签:QWidgetPrivate QWidgetBackingStore UpdateRequest QWidgetWindow 事件 QWidget update

关于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,QWidgetBackingStore,UpdateRequest,QWidgetWindow,事件,QWidget,update
From: https://www.cnblogs.com/snail-0304/p/16645162.html

相关文章

  • Windows事件ID大全
    51Windows无法找到网络路径。请确认网络路径正确并且目标计算机不忙或已关闭。如果Windows仍然无法找到网络路径,请与网络管理员联系。52由于网络上有重名,没有连接。......
  • xamarinform框架里Clicked事件取消任务,调用接口,
    xamarinform框架里Clicked事件取消任务,调用接口,如何写方法 ......
  • 事件委托
    事件委托是利用冒泡的原理,把事件加到父级上,触发执行效果。优点:给父级元素加事件(可以提高性能)只在内存中开辟了一块空间,节省资源同时减少了dom操作,提高性能对于新添加的......
  • js两种注册事件的区别
    传统on注册(L0)同一个对象,后面注册的事件会覆盖前面注册(同一个事件)直接使用null覆盖偶就可以实现事件的解绑都是冒泡阶段执行的事件监听注册(L2)语法:addEventListene......
  • 实例:事件绑定、样式绑定、class绑定、style绑定、条件渲染、循环渲染
     <!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title><scriptsrc="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14......
  • 方法和事件绑定;vue的核心思想?(面试题)
    事件1.方法的写法在methods中写方法,供事件或者别的方法内部调用2.事件绑定v-on:和@都是绑定事件的指令v-on:click -->@click指令后面跟事件类型,值就是methds......
  • vue3 基础-事件绑定 & 修饰符
    无非就是js的一些事件,按键,鼠标等的一些绑定在vue的实现而已,很好理解.先来看一个基础例子.事件初体验<!DOCTYPEhtml><htmllang="en"><head><title>事......
  • vue 监听事件addEventListener
    vue添加监听事件addEventListener//vue添加监听事件,addEventListener第二个参数要绑在this上,即需要在methods中声明,否则销毁的时候会报错//在mounted中监听,在beforeD......
  • 事件轮询Event loop
    事件轮询(eventloop)含义eventloop即事件轮询,这个是js里面为了解决单线程阻塞问题提出的解决方案,也是js异步执行机制的原理单线程众所周知,js执行是单线程的,什么是......
  • 等待事件统计视图
    在上一篇《内存分配统计视图|全方位认识sys系统库》中,我们介绍了sys系统库如何查询内存事件统计信息和bufferpool统计信息,本期的内容先给大家介绍按照等待事件统计相......