Qt update刷新之源碼分析總結

你們好,我是IT文藝男,來自一線大廠的一線程序員程序員

通過前面幾回的Qt源碼講解,我相信你們對Qt update刷新機制從底層原理上有了一個深入的理解;此次作一個收尾總結,來複盤前面幾回所講解的內容;windows

分析的切入點、思考點::

在作GUI開發時,要讓控件刷新,會調用update函數;那麼在調用了update函數後,Qt究竟基於什麼原理、執行了什麼代碼使得屏幕上有變化?微信

分析的過程分解::

1、刷新事件異步投遞過程
2、刷新事件的處理流程
3、繪製到內存Image
4、刷新結果輸出到屏幕異步

1、刷新事件異步投遞過程

分析void QWidget::update()函數的源碼,即調用update沒有傳遞參數,則默認刷新控件的整個區域,調用重載的update函數函數

  1. 若是控件是隱藏或者刷新被禁用,則直接返回
  2. 參數傳遞的矩形與控件矩形的交集,若是爲空,則直接返回
  3. 若是支持BackingStore(默認支持),則標髒該控件所屬的頂層窗口(TLW:: topLevelWidget縮寫)區域,即調用tlwExtra->backingStoreTracker->markDirty(r, this);函數
    a、把控件加入到dirtyWidgets容器中(addDirtyWidget函數)
    b、通知tlw進行刷新(sendUpdateRequest函數)
    sendUpdateRequest函數Post一個QEvent::UpdateRequest事件,即放入事件隊列中,當即返回;QEvent::UpdateRequest事件的接受者爲tlw;

2、刷新事件的處理流程

追蹤QEvent::UpdateRequest事件處理,進入消息通知流程,即QApplication::notify(QObject *receiver, QEvent *e)函數(沒有對QEvent::UpdateRequest事件進行處理),進一步由QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)函數處理;this

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
code

3、繪製到內存Image

回到QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,QPainter *sharedPainter, QWidgetBackingStore *backingStore)函數orm

函數主體內容以下::
一、繪製背景
二、繪製前景(send the paint event)
三、繪製子控件(paintSiblingsRecursive函數調用)視頻

QWidgetPrivate::paintSiblingsRecursive函數裏又會調用QWidgetPrivate::drawWidget函數從而造成樹形繪製

4、刷新結果輸出到屏幕

qtbase\src\plugins\platforms\windows目錄中的QWindowsBackingStore::flush函數中會調用BitBlt函數(Windows API函數)

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

下載後包括以下內容::

相關文章
相關標籤/搜索