在做GUI開發時,要讓控件刷新,會調用update函數;那么在調用了update函數后,Qt究竟基於什么原理、執行了什么代碼使得屏幕上有變化?本文就帶大家來探究探究其內部源碼。
Qt手冊中關於QWidget::update()解釋如下::
Updates the widget unless updates are disabled or the widget is hidden.
This function does not cause an immediate repaint; instead it schedules a paint event for processing when Qt returns to the main event loop. This permits Qt to optimize for more speed and less flicker than a call to repaint() does.
Calling update() several times normally results in just one paintEvent() call.
Qt normally erases the widget's area before the paintEvent() call. If the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is responsible for painting all its pixels with an opaque color
對於如上英文,解釋如下::
刷新控件,除非刷新被禁用或者控件是隱藏的。
此函數不會導致立即重繪; 相反,它調度一個paint事件,在Qt返回主事件循環時處理。這允許Qt進行優化,以獲得比調用repaint()更快的速度和更少的閃爍。
多次調用update()通常只會導致一次paintEvent()調用。
Qt通常在調用paintEvent()之前擦除控件區域。如果設置了Qt::WA_OpaquePaintEvent屬性,控件用不透明的顏色繪制其所有像素。
void QWidget::update()源碼如下
void QWidget::update()
{
update(rect());
}
即調用update沒有傳遞參數,則默認刷新控件的整個區域,調用如下重載的update函數
1、如果控件是隱藏或者刷新被禁用,則直接返回
2、參數傳遞的矩形與控件矩形的交集,如果為空,則直接返回
3、如果支持BackingStore(默認支持),則標臟該控件所屬的頂層窗口(TLW:: topLevelWidget縮寫)區域,即調用tlwExtra->backingStoreTracker->markDirty(r, this);函數
其中入參updateTime的值為UpdateLater,而非UpdateNow;
函數主體內容如下::
1、把控件加入到dirtyWidgets容器中(addDirtyWidget函數)
2、通知tlw進行刷新(sendUpdateRequest函數)
sendUpdateRequest函數如下圖所示,其Post一個QEvent::UpdateRequest事件,即放入事件隊列中,立即返回;QEvent::UpdateRequest事件的接受者為tlw;
看到這里,也就明白為什么update是異步刷新了,源碼面前了無秘密
Qt update刷新之源碼分析系列會分拆為多個具體的文章,后續我會一一講解並發布
由於這里不能發布視頻,所以我在這發布了文章,在我的微信公眾號里同步發布了詳細的PPT以及視頻進行詳細解說