大家好,我是IT文藝男,來自一線大廠的一執行緒式員
經過前面幾次的Qt原始碼講解,我相信大家對Qt update重繪機制從底層原理上有了一個深刻的理解;這次做一個收尾總結,來復盤前面幾次所講解的內容;
分析的切入點、思考點::
在做GUI開發時,要讓控制元件重繪,會呼叫update函式;那么在呼叫了update函式后,Qt究竟基于什么原理、執行了什么代碼使得螢屏上有變化?
分析的程序分解::
一、重繪事件異步投遞程序
二、重繪事件的處理流程
三、繪制到記憶體Image
四、重繪結果輸出到螢屏
一、重繪事件異步投遞程序
分析void QWidget::update()函式的原始碼,即呼叫update沒有傳遞引數,則默認重繪控制元件的整個區域,呼叫多載的update函式
- 如果控制元件是隱藏或者重繪被禁用,則直接回傳
- 引數傳遞的矩形與控制元件矩形的交集,如果為空,則直接回傳
- 如果支持BackingStore(默認支持),則標臟該控制元件所屬的頂層視窗(TLW:: topLevelWidget縮寫)區域,即呼叫
tlwExtra->backingStoreTracker->markDirty(r, this);函式
a、把控制元件加入到dirtyWidgets容器中(addDirtyWidget函式)
b、通知tlw進行重繪(sendUpdateRequest函式)
sendUpdateRequest函式Post一個QEvent::UpdateRequest事件,即放入事件佇列中,立即回傳;QEvent::UpdateRequest事件的接受者為tlw;

二、重繪事件的處理流程
追蹤QEvent::UpdateRequest事件處理,進入訊息通知流程,即QApplication::notify(QObject *receiver, QEvent *e)函式(沒有對QEvent::UpdateRequest事件進行處理),進一步由QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)函式處理;
receiver的event函式不做處理,其呼叫父類的event函式,即bool QWidget::event(QEvent *event)函式,該函式中針對事件型別進行處理(switch case);
對于QEvent::UpdateRequest事件處理,QWidgetBackingStore::doSync函式中呼叫tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, 0, this);函式進行繪制,函式的第一個引數是獲取繪制設備,對于Windows平臺,繪制目的設備為記憶體Image

三、繪制到記憶體Image
回到QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,QPainter *sharedPainter, QWidgetBackingStore *backingStore)函式

函式主體內容如下::
1、繪制背景
2、繪制前景(send the paint event)
3、繪制子控制元件(paintSiblingsRecursive函式呼叫)
QWidgetPrivate::paintSiblingsRecursive函式里又會呼叫QWidgetPrivate::drawWidget函式從而形成樹形繪制,
四、重繪結果輸出到螢屏
qtbase\src\plugins\platforms\windows目錄中的QWindowsBackingStore::flush函式中會呼叫BitBlt函式(Windows API函式)

關注我的微信公眾號(itwenyinan)下載完整的講解視頻、PPT、Code;

下載后包括如下內容::

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/270549.html
標籤:C++
