首页 > 编程知识 正文

update on,qt的基本使用

时间:2023-05-06 15:37:52 阅读:155430 作者:1258

一直不知道,qt的update和repaint的区别。 虽然文档上好像写得很清楚。 但是,我不看源代码,在使用过程中发呆了。 今天看相关的源代码,记下一点自己的心得。

1、从update到paintEvent的调用

啊,道路好像很曲折呢~

voidqwidget :3360更新(常量) )。

{

if (! isvisible(|! udatesenabled(||rect.isempty ) )

返回;

测试属性(Qt :3360 wa _ wstate _ inpaintevent ) ) }

qapplication :3360 post event (this,newqupdatelaterevent ) rect );

返回;

}

hasbackingstoresupport () (/此函数在windows上总是返回真

QL wextra * TL wextra=window (-d _ func )-maybeTopData );

if(TLWextra! TL wextra-intoplevelresizetlwextra-backing store )

TL wextra-backing store-mark dirty (rect,this ); //这里只是标记了无效区。

} else {

d_func(-repaint_sys ) ) rect;

}

}

如上所述,qt的update函数是markDirty ) )只是将无效区域放入名为QWidgetBackingStore的对象中。 其实,markDirty这个函数中有一篇很大的文章,一看就知道了

voidqwidgetbackingstore :3360标记目录(constqrectrect,q构件*构件,bool updateImmediately,

bool invalidateBuffer )

{

//省略了与代码分析无关的东东

#ifndef QT_NO_GRAPHICSEFFECT

构件- d _ func (-invalidategraphicseffectsrecursively ); //这有什么用? 还没有详细去看。

#endif //QT_NO_GRAPHICSEFFECT

//在特殊情况下,直接更新请求新事件。 注意下q小部件的此属性WA_PaintOnScreen

构件- d _ func (-paint on screen ) ) ) )。

构件- d _ func (-dirty.isempty ) ) )。

构件- d _ func (-dirty=q region (rect ) );

sendupdaterequest (构件,更新immediately;

返回;

} else if (Qt _ region _ strict contains (widget-d _ func )-dirty,rect ) ) ) ) ) ) ) ) ) ) )

更新导入(if )

sendupdaterequest (构件,更新immediately;

返回;//阵列目录。

}

const bool eventAlreadyPosted=! 构件- d _ func (-dirty.isempty );

构件- d _ func (-dirty=rect;

if (! eventalreadyposted|| (更新immediately )

sendupdaterequest (构件,更新immediately;

返回;

}

//如果总是更新整体,就没有必要缓存无效区域了吧。 直接发送了UpdateRequest事件

完全更新{ if }

更新导入(if )

sendupdaterequest(tlw,更新immediately;

返回;

}

if (! window surface-haspartialupdatesupport (

fullUpdatePending=true;

s

endUpdateRequest(tlw, updateImmediately);

return;

}

const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);

const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint())));

if (qt_region_strictContains(dirty, translatedRect)) {

if (updateImmediately)

sendUpdateRequest(tlw, updateImmediately);

return; // Already dirty,已经是无效的了,即刻发UpdateRequest事件的

}

// 隐藏窗口时,此值为true

if (invalidateBuffer) {

const bool eventAlreadyPosted = !dirty.isEmpty();

dirty += translatedRect;

if (!eventAlreadyPosted || updateImmediately)

sendUpdateRequest(tlw, updateImmediately);

return;

}

// 如果之前没有无效窗口,把窗口加上去,并发一个UpdateRequest事件

if (dirtyWidgets.isEmpty()) {

addDirtyWidget(widget, rect);

sendUpdateRequest(tlw, updateImmediately);

return;

}

if (widget->d_func()->inDirtyList) {

if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect))

widget->d_func()->dirty += widgetRect;

} else {

addDirtyWidget(widget, rect);// 加上一个无效窗口

}

// 如果需要立即更新的话,就发UpdateRequest事件的。这里就是update与repaint的区别所在了。再看下面repaint函数, 其传进来的参数是为true的。

if (updateImmediately)

sendUpdateRequest(tlw, updateImmediately);

}

void QWidget::repaint(const QRect &rect)

{

Q_D(QWidget);

if (testAttribute(Qt::WA_WState_ConfigPending)) {

update(rect);

return;

}

if (!isVisible() || !updatesEnabled() || rect.isEmpty())

return;

if (hasBackingStoreSupport()) {

QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();

if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {

tlwExtra->inRepaint = true;

tlwExtra->backingStore->markDirty(rect, this, true);// 第三个参数为真,于是可以立即通过markDirty函数发送一个

//UpdateRequest事件出去的

tlwExtra->inRepaint = false;

}

} else {

d->repaint_sys(rect);

}

}

好吧,看到这里才知道,所谓的更新,也只不过是发个更新事件而已,如下:

static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)

{

if (!widget)

return;

if (updateImmediately) {

QEvent event(QEvent::UpdateRequest);

QApplication::sendEvent(widget, &event);

} else {

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

}

} 至于事件是怎么调到paintEvent的,这个就是事件响应机制的问题了。好吧,先打住的,貌似已经贴了不少代码的。 后面更新,是依次调用 了QWidgetPrivate::syncBackingStore(const QRegion &region) >> QWidgetBackingStore::sync()。于是,把缓存的无效区给绘制出来了。sync()函数里面的东西也不少,累了,以后再细看的。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。