Qt的绘制是如何发生的

QEvent::WindowDeactivate

当用户鼠标在应用之外时,会触发QEvent::WindowDeactivate事件,

     Qt5Widgetsd.dll!QApplication::setActiveWindow(QWidget * act) Line 2072    C++
     Qt5Widgetsd.dll!QApplicationPrivate::notifyActiveWindowChange(QWindow * previous) Line 2133    C++

对应的父类QWidget的响应事件方法,会先调用自己的update,再遍历所有儿子,并传播该事件给可见儿子

    case QEvent::WindowDeactivate: {
        if (isVisible() && !palette().isEqual(QPalette::Active, QPalette::Inactive))
            update();
        QList<QObject*> childList = d->children;
        for (int i = 0; i < childList.size(); ++i) {
            QWidget *w = qobject_cast<QWidget *>(childList.at(i));
            if (w && w->isVisible() && !w->isWindow())
                QApplication::sendEvent(w, event);
        }
        break; }

而update函数会把自己加到QWidgetBackingStore的dirtyWidgets列表中去

QEvent::UpdateRequest

QEvent::UpdateRequest会调用d->syncBackingStore();

QWidgetBackingStore::sendUpdateRequest函数会调用这个函数

QApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);

这是一个异步函数

而UpdateRequest很多时候是通过

     Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1825    C++

调过来的

syncBackingStore会调用doSync

     Qt5Widgetsd.dll!QWidgetBackingStore::doSync() Line 1426    C++
>    Qt5Widgetsd.dll!QWidgetBackingStore::sync() Line 1210    C++
     Qt5Widgetsd.dll!QWidgetPrivate::syncBackingStore() Line 1953    C++

doSync里会调用

QWidgetPrivate::drawWidget函数

Layout::Resize会调用

     Qt5Widgetsd.dll!QToolBarAreaLayout::apply(bool animate) Line 936    C++

调用栈如下:

     Qt5Widgetsd.dll!QWidgetBackingStore::sendUpdateRequest(QWidget * widget, QWidgetBackingStore::UpdateTime updateTime) Line 502    C++
     Qt5Widgetsd.dll!QWidgetBackingStore::markDirty(const QRect & rect, QWidget * widget, QWidgetBackingStore::UpdateTime updateTime, QWidgetBackingStore::BufferState bufferState) Line 675    C++
     Qt5Widgetsd.dll!QWidgetPrivate::invalidateBuffer(const QRect & rect) Line 1635    C++
     Qt5Widgetsd.dll!QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint & oldPos, const QSize & oldSize) Line 1529    C++
     Qt5Widgetsd.dll!QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) Line 7363    C++
     Qt5Widgetsd.dll!QWidget::setGeometry(const QRect & r) Line 7261    C++
     Qt5Widgetsd.dll!QWidget::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 514    C++
     Qt5Widgetsd.dll!QWidget::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 611    C++
     Qt5Widgetsd.dll!QToolBar::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 297    C++
     VkWidgets.dll!ToolbarWidget::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 103    C++
     Qt5Cored.dll!QMetaObject::metacall(QObject * object, QMetaObject::Call cl, int idx, void * * argv) Line 317    C++
     Qt5Cored.dll!QPropertyAnimationPrivate::updateProperty(const QVariant & newValue) Line 133    C++
     Qt5Cored.dll!QPropertyAnimation::updateCurrentValue(const QVariant & value) Line 240    C++
     Qt5Cored.dll!QVariantAnimationPrivate::setCurrentValueForProgress(const double progress) Line 285    C++
     Qt5Cored.dll!QVariantAnimationPrivate::recalculateCurrentInterval(bool force) Line 270    C++
     Qt5Cored.dll!QVariantAnimationPrivate::setDefaultStartEndValue(const QVariant & value) Line 332    C++
     Qt5Cored.dll!QPropertyAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState) Line 278    C++
     Qt5Cored.dll!QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) Line 989    C++
     Qt5Cored.dll!QAbstractAnimation::start(QAbstractAnimation::DeletionPolicy policy) Line 1358    C++
     Qt5Widgetsd.dll!QWidgetAnimator::animate(QWidget * widget, const QRect & _final_geometry, bool animate) Line 114    C++
     Qt5Widgetsd.dll!QToolBarAreaLayout::apply(bool animate) Line 936    C++

markDirty会调用QWidgetBackingStore::sendUpdateRequest

该方法会判断updateNow还是updateLater

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值