你們好,我是IT文藝男,來自一線大廠的一線程序員程序員
通過前面幾回的Qt源碼講解,我相信你們對Qt update刷新機制從底層原理上有了一個深入的理解;此次作一個收尾總結,來複盤前面幾回所講解的內容;windows
在作GUI開發時,要讓控件刷新,會調用update函數;那麼在調用了update函數後,Qt究竟基於什麼原理、執行了什麼代碼使得屏幕上有變化?微信
1、刷新事件異步投遞過程
2、刷新事件的處理流程
3、繪製到內存Image
4、刷新結果輸出到屏幕異步
分析void QWidget::update()
函數的源碼,即調用update沒有傳遞參數,則默認刷新控件的整個區域,調用重載的update函數函數
tlwExtra->backingStoreTracker->markDirty(r, this);
函數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)
函數處理;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
回到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函數從而造成樹形繪製。
qtbase\src\plugins\platforms\windows目錄中的QWindowsBackingStore::flush
函數中會調用BitBlt函數(Windows API函數)