国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

劉琪 找誰做網(wǎng)站靠譜東莞網(wǎng)絡(luò)營銷全網(wǎng)推廣

劉琪 找誰做網(wǎng)站靠譜,東莞網(wǎng)絡(luò)營銷全網(wǎng)推廣,鎮(zhèn)江還有什么網(wǎng)站嗎,找公司做網(wǎng)站運營怎么樣(本文續(xù)上一篇《Qt底層原理:深入解析QWidget的繪制技術(shù)細(xì)節(jié)(1)》) QWidget繪制體系為什么這么設(shè)計【重點】 在傳統(tǒng)的C圖形界面框架中,例如DUILib等,控件的繪制邏輯往往直接在控件的類的內(nèi)部,例如PushButt…

(本文續(xù)上一篇《Qt底層原理:深入解析QWidget的繪制技術(shù)細(xì)節(jié)(1)》)

QWidget繪制體系為什么這么設(shè)計【重點】

在傳統(tǒng)的C++圖形界面框架中,例如DUILib等,控件的繪制邏輯往往直接在控件的類的內(nèi)部,例如PushButton的draw/paint的函數(shù)內(nèi)部,Qt的QWidget費了老大勁,定義了一堆枚舉和基類,把大部分的繪制邏輯都抽離了具體的類,轉(zhuǎn)到了QStyle上。這種做法說實話,是有弊有利的。
下面是對利弊的詳細(xì)討論:

有利之處:

  1. 提高繪制邏輯的復(fù)用性

    • 在Qt中,繪制邏輯不是硬編碼在每個控件中的,而是通過QStyle這個中心化的類來處理的。這意味著,像在QListView中繪制按鈕這樣的任務(wù),不需要創(chuàng)建QPushButton實例,而是通過QStyle來繪制具有按鈕視覺效果的元素。這樣,任何需要具有按鈕風(fēng)格的控件都可以復(fù)用這一段繪制代碼,大大提高了代碼的復(fù)用性。
  2. 提高繪制邏輯的風(fēng)格化能力

    • 由于QStyle負(fù)責(zé)所有控件的繪制細(xì)節(jié),這使得統(tǒng)一應(yīng)用程序的風(fēng)格變得容易。開發(fā)者可以通過改變QStyle或者使用QStyleSheets來快速地修改應(yīng)用程序的風(fēng)格,而無需修改每個控件。這種能力使得開發(fā)者能夠更快地響應(yīng)設(shè)計的改變,并且為用戶提供一致的視覺體驗。
  3. 實現(xiàn)繪制邏輯和具體的控件類的解耦

    • 在傳統(tǒng)的GUI框架中,繪制代碼通常與控件邏輯緊密耦合。Qt通過將繪制邏輯抽象到QStyle中,實現(xiàn)了繪制邏輯與控件類的分離。這樣的解耦使得開發(fā)者可以在不改變控件邏輯的情況下,通過修改QStyle或QStyleSheets來定制控件的外觀。這也為實現(xiàn)像QSS這樣的高級樣式特性奠定了基礎(chǔ)。

弊處:

  1. 增加了繪制邏輯的復(fù)雜度

    • Qt的這種抽象方式確實增加了學(xué)習(xí)和實現(xiàn)自定義繪制邏輯的復(fù)雜度。新加入的Qt開發(fā)者需要理解QStyle的工作原理以及如何與QStyleOption等類配合使用,這對于初學(xué)者而言可能是一個挑戰(zhàn)。
  2. 給繪制體系新增控件增加了難度

    • 在Qt中,控件的繪制細(xì)節(jié)往往被封裝成枚舉類型,這些枚舉在整個QStyle體系中都有明確的定義。當(dāng)需要增加新的控件或者擴(kuò)展控件的功能時,可能需要在QStyle中添加新的枚舉值,并要求所有的QStyle實現(xiàn)都支持這個新的枚舉。這不僅增加了開發(fā)的難度,也可能導(dǎo)致現(xiàn)有的風(fēng)格類需要進(jìn)行大量的更新來適應(yīng)新的枚舉。

總結(jié)來說,Qt選擇這種設(shè)計,核心是2個考慮,第一個是性能,就如前面提到的,當(dāng)我們需要繪制一個按鈕的時候是不需要實例化按鈕類的,這給QListView的性能天花板打到比其他任何圖形界面框架都要高。另一個方面是實現(xiàn)非常接近原生的界面風(fēng)格元素,這也是Qt界面框架和其他界面框架獨特之處。Qt界面默認(rèn)情況下是可以達(dá)到以假亂真的原生效果,要實現(xiàn)如此高度的還原,還要保障繪制的性能,那么把所有繪制邏輯針對不同平臺提供高度的定制化是必然的做法,因此QStyle這套體系就形成了。

繪制雙緩沖細(xì)節(jié)

在Qt中,為了在繪制時不在屏幕出現(xiàn)繪制過程導(dǎo)致畫面閃爍,會采用雙緩沖機(jī)制。與此相關(guān)的一些類和組件包括:

  1. QPixmap:
    QPixmap是一個用于處理圖像的類,通常用于離屏繪制(off-screen drawing)。它可以作為雙緩沖的后臺緩沖區(qū)使用,在這個緩沖區(qū)上進(jìn)行繪制操作,然后將其內(nèi)容一次性繪制到屏幕上。

  2. QWidget:
    QWidget類有一個屬性,決定是否使用雙緩沖。默認(rèn)情決定了Qt是否為QWidget啟用雙緩沖。大多數(shù)情況下,Qt會自動為所有的QWidget及其子類使用雙緩沖策略,但是開發(fā)者可以通過setAttribute(Qt::WA_PaintOnScreen)來修改這個行為。

  3. QBackingStore:
    QBackingStore是Qt中負(fù)責(zé)管理窗口內(nèi)容的后臺存儲的類。它是Qt雙緩沖機(jī)制的核心組件之一,在窗口系統(tǒng)層面處理緩沖區(qū)。當(dāng)窗口或部件的內(nèi)容需要更新時,QBackingStore負(fù)責(zé)將緩沖區(qū)的內(nèi)容復(fù)制到屏幕上。

  4. QPaintEngine:
    QPaintEngine是一個抽象基類,它定義了Qt繪圖操作的底層接口。具體的實現(xiàn)類,如QRasterPaintEngine,會使用雙緩沖技術(shù)來提高繪制效果和性能。

  5. QWindow:
    在Qt中,QWindow代表了一個系統(tǒng)窗口。它可以使用QBackingStore來管理其內(nèi)容的雙緩沖,尤其是在Qt Quick中,QWindow是與平臺窗口系統(tǒng)交互的主要接口。

  6. QScreen:
    QScreen類代表了應(yīng)用程序可以使用的顯示器。雖然它不直接參與雙緩沖,但是它提供了與屏幕相關(guān)的功能,包括分辨率、顏色深度等信息,這些信息可能會影響雙緩沖策略的選擇和優(yōu)化。

在Qt的繪制過程中,當(dāng)你在QWidget的paintEvent()方法中使用QPainter進(jìn)行繪圖時,你實際上是在繪制到一個離屏緩沖區(qū)。然后,該緩沖區(qū)的內(nèi)容會被復(fù)制到屏幕上。這個過程對于開發(fā)者來說是透明的,因為Qt框架在底層處理了所有的細(xì)節(jié)。

如果需要控制雙緩沖的行為,或者需要更深入地理解其實現(xiàn),可以查看以上提到的類的文檔和源代碼。

需要注意的是,Qt Quick(基于QML的高級UI框架)與傳統(tǒng)的QWidget系統(tǒng)在渲染上有所不同。Qt Quick使用場景圖(scene graph)和通?;贠penGL的渲染器進(jìn)行繪制,而不是使用傳統(tǒng)的QWidget繪制流程。盡管如此,QWindowQBackingStore仍然在Qt Quick的窗口管理和屏幕渲染中發(fā)揮作用。

如何提高應(yīng)用程序的繪制性能

提高繪制性能通常涉及減少不必要的繪制工作和優(yōu)化繪制路徑。以下是一些策略來提高Qt控件的繪制性能:

  1. 避免半透明和透明度

    • 避免半透明的控件,因為它需要額外的合成步驟。
    • 使用不透明的控件,設(shè)置屬性Qt::WA_OpaquePaintEvent
  2. 減少重繪區(qū)域

    • 只重繪變化的部分,而不是整個控件。
    • 使用QWidget::update(const QRect&)來指定只重繪控件的一個子區(qū)域。
    • 避免不必要的update()調(diào)用。
  3. 優(yōu)化繪制代碼

    • paintEvent中避免復(fù)雜計算。
    • 使用簡單的幾何圖形和操作,避免繪制復(fù)雜的圖形。
    • 避免在paintEvent中創(chuàng)建臨時對象。
  4. 延遲更新

    • 使用QWidget::update()而不是QWidget::repaint(),因為update()會合并多個重繪請求,延遲到下一個事件循環(huán)中。
  5. 使用雙緩沖

    • Qt默認(rèn)使用雙緩沖來避免閃爍,確保此功能未被禁用。
  6. 緩存繪制結(jié)果

    • 對于不經(jīng)常變化的內(nèi)容,可以將其緩存到QPixmapQImage中,然后在paintEvent中直接繪制這些緩存。
  7. 減少布局調(diào)整

    • 避免頻繁的布局改變,特別是包含大量控件的布局。
  8. 使用QStaticTextQPixmap

    • 對于不更改的文本,使用QStaticText可以提高繪制性能。
    • 對于重復(fù)使用的圖像,使用QPixmap進(jìn)行緩存。
  9. 避免使用圖形效果

    • 圖形效果如陰影、模糊等會增加繪制負(fù)擔(dān),應(yīng)謹(jǐn)慎使用。
  10. 合理使用更新策略

    • 對于自定義控件,使用QWidget::setUpdateRect()來定義更高效的更新策略。
  11. 使用硬件加速

    • 如果可能,利用OpenGL或Vulkan等進(jìn)行硬件加速繪制。
  12. 多線程

    • 對于復(fù)雜的圖像處理或準(zhǔn)備工作,可以在后臺線程中進(jìn)行,以免阻塞UI線程。
  13. 調(diào)整渲染選項

    • 使用QPainter的渲染提示來平衡質(zhì)量和性能。
  14. 避免無效的層級結(jié)構(gòu)

    • 減少嵌套層次和不必要的父子控件關(guān)系。

需要注意的是,性能調(diào)整往往需要根據(jù)具體的應(yīng)用場景和需求來定制,因此推薦在做出調(diào)整后進(jìn)行充分的測試,以確保既達(dá)到了性能目標(biāo),又保持了用戶界面的質(zhì)量和響應(yīng)性。

使用多線程繪制提高性能的例子

在Qt中,UI更新(包括繪制)必須在主線程(也就是UI線程)中完成。但是,我們可以在另一個線程中生成圖像數(shù)據(jù),然后將這些數(shù)據(jù)發(fā)送回主線程進(jìn)行顯示。下面是這種方法的主要流程:

  1. 在工作線程中生成圖像
    創(chuàng)建一個工作線程,在這個線程中進(jìn)行圖像的生成或處理,比如繪制到一個QImage或者QPixmap對象上。這可以通過直接在工作線程中創(chuàng)建圖像對象并使用QPainter來繪制。

  2. 使用信號和槽傳輸圖像
    當(dāng)圖像生成完畢,使用信號和槽機(jī)制將圖像從工作線程發(fā)送回主線程。這通常涉及到在工作線程中發(fā)射一個信號,攜帶生成的圖像作為參數(shù)。在主線程中,一個槽函數(shù)將會接收這個圖像。

  3. 在主線程中顯示圖像
    在主線程的槽函數(shù)中接收圖像,并將其設(shè)置到一個控件上顯示。這可以是通過調(diào)用QLabel::setPixmap()設(shè)置QPixmap,或者在自定義控件的paintEvent()中使用QPainter::drawImage()來繪制QImage。

以下是一個簡化的代碼示例,展示了如何在工作線程中生成圖像,并在主線程中顯示:

// MyWorkerThread.h
#include <QThread>
#include <QImage>class MyWorkerThread : public QThread {Q_OBJECTpublic:MyWorkerThread(QObject *parent = nullptr) : QThread(parent) {}signals:void imageReady(const QImage &image);protected:void run() override {QImage image(100, 100, QImage::Format_ARGB32);QPainter painter(&image);// ... 在這里進(jìn)行繪制操作 ...emit imageReady(image);}
};// MyWidget.h
#include <QWidget>
#include <QImage>class MyWidget : public QWidget {Q_OBJECTpublic:MyWidget(QWidget *parent = nullptr) : QWidget(parent) {// Start the worker threadconnect(&workerThread, &MyWorkerThread::imageReady, this, &MyWidget::updateImage);workerThread.start();}~MyWidget() {workerThread.quit();workerThread.wait();}public slots:void updateImage(const QImage &image) {this->image = image;update(); // Schedule a repaint}protected:void paintEvent(QPaintEvent *event) override {QPainter painter(this);if (!image.isNull()) {painter.drawImage(0, 0, image);}}private:MyWorkerThread workerThread;QImage image;
};

在上面的例子中,MyWorkerThread類在一個工作線程中生成了一個QImage。一旦圖像生成完畢,它通過信號imageReady將圖像發(fā)送回主線程。MyWidget類有一個槽函數(shù)updateImage來接收圖像,并使用update()方法請求重繪。在paintEvent()中,接收到的圖像被繪制在控件上。
當(dāng)在工作線程中使用QImage時,應(yīng)該使用線程安全的圖像格式,如QImage::Format_ARGB32。QPixmap是專門為顯示優(yōu)化的,并且通常不應(yīng)在非UI線程中使用。

通過這兩篇文章,相信大家對Qt的繪制體系有了總體上的印象,并且對Qt繪制體系的設(shè)計緣由也更加清晰。

http://aloenet.com.cn/news/40051.html

相關(guān)文章:

  • 做網(wǎng)站怎么做鼠標(biāo)跟隨2023很有可能再次封城嗎
  • 網(wǎng)站經(jīng)營與建設(shè)優(yōu)化大師軟件下載
  • 網(wǎng)上有做口譯的網(wǎng)站么官方進(jìn)一步優(yōu)化
  • 彩票代購網(wǎng)站建設(shè)百度怎么注冊自己的店鋪
  • 做電影平臺網(wǎng)站怎么賺錢的什么是網(wǎng)絡(luò)營銷平臺
  • wordpress主頁居中重慶seo俱樂部
  • 焦作專業(yè)做網(wǎng)站公司中國新聞發(fā)布
  • wordpress 個性化韶山百度seo
  • 桐鄉(xiāng)網(wǎng)站建設(shè)世界十大網(wǎng)站排名出爐
  • 高明專業(yè)網(wǎng)站建設(shè)報價青海百度關(guān)鍵詞seo
  • 網(wǎng)站制作需要平臺培訓(xùn)心得體會總結(jié)
  • 網(wǎng)站建設(shè)專企業(yè)站seo價格
  • 網(wǎng)站建設(shè)種類 優(yōu)幫云海外網(wǎng)站推廣優(yōu)化專員
  • 可信賴的南昌網(wǎng)站制作seo是付費還是免費推廣
  • 商城網(wǎng)站合同網(wǎng)站的優(yōu)化
  • wordpress 側(cè)邊懸浮塊鄭州谷歌優(yōu)化外包
  • web網(wǎng)站開發(fā)全過程網(wǎng)站內(nèi)鏈優(yōu)化
  • 做網(wǎng)站的流程方法上海排名優(yōu)化推廣工具
  • 網(wǎng)站的設(shè)計與維護(hù)摘要搜易網(wǎng)優(yōu)化的效果如何
  • 國家和省對政府網(wǎng)站建設(shè)要求做網(wǎng)絡(luò)推廣要學(xué)些什么
  • 關(guān)于門戶網(wǎng)站建設(shè)通報google chrome谷歌瀏覽器
  • 成都it培訓(xùn)機(jī)構(gòu)優(yōu)化網(wǎng)絡(luò)搜索引擎
  • 門戶網(wǎng)站快速制作佛山網(wǎng)站建設(shè)維護(hù)
  • css網(wǎng)站開發(fā)實錄新聞稿發(fā)布軟文平臺
  • 貴陽專業(yè)做網(wǎng)站公司高端網(wǎng)站設(shè)計公司
  • 商城網(wǎng)站制作方案100個免費推廣網(wǎng)站
  • 網(wǎng)站建設(shè) 天津國內(nèi)軍事新聞最新消息
  • 能免費做網(wǎng)站嗎信息流廣告模板
  • 成都定制企業(yè)網(wǎng)站制作免費學(xué)生網(wǎng)頁制作成品代碼
  • 專業(yè)手機(jī)網(wǎng)站制作公司網(wǎng)站快速排名服務(wù)商