QT源码分析-update

update过程

1.刷新事件的异步投递
首先调用QWidget的update:

void QWidgetPrivate::update(T r)
{
    Q_Q(QWidget);

   // 1、 如果控件是隐藏或者刷新被禁止,则直接返回
    if (!q->isVisible() || !q->updatesEnabled())
        return;

   // 2、 参数传递的矩形与控件矩形的交集为空,则直接返回
    T clipped = r & q->rect();
    if (clipped.isEmpty())
        return;

    if (q->testAttribute(Qt::WA_WState_InPaintEvent)) {
        QCoreApplication::postEvent(q, new QUpdateLaterEvent(clipped));
        return;
    }

   // 3、 标脏该控件所属的顶层窗口(TLW:topLevelWidget)
    QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
    if (tlwExtra && tlwExtra->backingStore)
        tlwExtra->repaintManager->markDirty(clipped, q);
}

markDirty里面执行内容如下:

void QWidgetRepaintManager::markDirty(const T &r, QWidget *widget, UpdateTime updateTime, BufferState bufferState)
{
    、、、
    // updateTime默认为UpdateLater
    // 把控件加入到dirtyWidget容器中
    // 通知tlw进行刷新sendUpdateRequest
    if (dirtyWidgets.isEmpty()) {
        addDirtyWidget(widget, r);
        sendUpdateRequest(tlw, updateTime);
        return;
    }
    、、、
}

sendUpdateRequest里面执行内容如下:
其post一个QEvent::UpdateRequest事件,放入事件队列中立即返回;QEvent::UpdateRequest事件的接受者为tlw。

void QWidgetRepaintManager::sendUpdateRequest(QWidget *widget, UpdateTime updateTime)
{
    、、、
    switch (updateTime) {
    case UpdateLater:
        updateRequestSent = true;
        QCoreApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
        break;
    case UpdateNow: {
        QEvent event(QEvent::UpdateRequest);
        QCoreApplication::sendEvent(widget, &event);
        break;
        }
    }
    、、、
}

2.刷新事件处理流程

继续追踪QEvent::UpdateRequest事件处理,进入消息通知流程,即QApplicaion::notify,进一步有QApplicationPrivate::notify_helper函数处理

bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
{
    // 1、send to all application event filters(application的事件过滤器处理)
    if (threadRequiresCoreApplication()
        && receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
        && sendThroughApplicationEventFilters(receiver, e)) {
        filtered = true;
        return filtered;
    }

    // 2、send to all receiver event filters(receiver的事件过滤器处理)
    if (sendThroughObjectEventFilters(receiver, e)) {
        filtered = true;
        return filtered;
    }

    // 3、deliver the event(调用receiver的event函数处理)
    consumed = receiver->event(e);
}

最终调用父类QWidget::event函数进行处理:

bool QWidget::event(QEvent *event)
{
    Q_D(QWidget);
    case QEvent::UpdateRequest:
        d->syncBackingStore();
        break;
}

void QWidgetPrivate::syncBackingStore(const QRegion &region)
{
    if (shouldPaintOnScreen())
        paintOnScreen(region);
    else if (QWidgetRepaintManager *repaintManager = maybeRepaintManager()) {
        repaintManager->sync(q_func(), region);
    }
}


3.绘制到内存

void QWidgetRepaintManager::paintAndFlush()
{

}

void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, DrawWidgetFlags flags,
                                QPainter *sharedPainter, QWidgetRepaintManager *repaintManager)
{

}

void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,
                                            const QPoint &offset, DrawWidgetFlags flags
                                            , QPainter *sharedPainter, QWidgetRepaintManager *repaintManager)
{

}

4.刷新结果输出到屏幕

void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &offset)
{

}

void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
                                 const QPoint &offset)
{
     // 调用BitBlt
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值