qt 雙緩沖案例對比

雙緩沖

1.雙緩沖原理

單緩沖:在paintEvent中直接繪制到屏幕,繪制過程被用戶看到
雙緩沖:先在redrawBuffer繪制到緩沖區,然后一次性顯示完整結果
代碼結構
單緩沖:所有繪制邏輯在paintEvent中
雙緩沖:繪制邏輯分離到redrawBuffer,paintEvent僅負責顯示緩沖區
性能影響
單緩沖:每次更新需要重復計算和繪制
雙緩沖:可以優化為只在必要時重繪緩沖區(如數據變化時)

減少的時間是重繪的那部分時間,單緩沖是逐個繪制,雙緩沖是整體繪制。

測試案例

1.Qt 實現繪制 5000 個小球移動,單緩沖和雙緩沖效果對比

雙緩沖和單緩沖效果對比

2.代碼

關鍵代碼對比:
單緩沖繪制: paintEvent 中通過 painter 繪制每一個 circle,一次 paintEvent 繪制 5000 次
雙緩沖繪制: paintEvent 中直接繪制提前賦好像素值的成員變量 buffer 中的像素

doublebufferwidget.h

#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QPixmap>
#include <QPointF>
#include <QVector>
#include <cmath>
#include <QTime>
#include <QDebug>class DoubleBufferWidget : public QWidget {Q_OBJECT
public:DoubleBufferWidget(QWidget *parent = nullptr) : QWidget(parent) {// 初始化緩沖區setWindowTitle("DoubleBuffer");buffer = QPixmap(size());buffer.fill(Qt::white);// 初始化動畫數據for (int i = 0; i < 5000; ++i) {circles.append({QPointF(rand() % width(), rand() % height()),5.f + rand() % 10,QColor(rand() % 256, rand() % 256, rand() % 256),QPointF((rand() % 100 - 50) / 100.0, (rand() % 100 - 50) / 100.0)});}// 設置定時器更新動畫QTimer *timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &DoubleBufferWidget::updateAnimation);timer->start(16);}void resizeEvent(QResizeEvent *event) override {buffer = QPixmap(size());buffer.fill(Qt::white);QWidget::resizeEvent(event);}void paintEvent(QPaintEvent *event) override {QTime doublePaint;doublePaint.start();Q_UNUSED(event);QPainter painter(this);painter.drawPixmap(0, 0, buffer);qInfo() << "void paintEvent(QPaintEvent *event) doublePaint cost times:" << doublePaint.elapsed() << "ms";}private slots:void updateAnimation() {// 更新所有圓形位置for (auto &circle : circles) {circle.pos += circle.velocity;if (circle.pos.x() - circle.radius < 0 || circle.pos.x() + circle.radius > width())circle.velocity.setX(-circle.velocity.x());if (circle.pos.y() - circle.radius < 0 || circle.pos.y() + circle.radius > height())circle.velocity.setY(-circle.velocity.y());}// 重新繪制到緩沖區redrawBuffer();update();}private:struct Circle {QPointF pos;qreal radius;QColor color;QPointF velocity;};QPixmap buffer;QVector<Circle> circles;void redrawBuffer() {buffer.fill(Qt::white);QPainter bufferPainter(&buffer);bufferPainter.setRenderHint(QPainter::Antialiasing);// 模擬長時間繪制過程for (int i = 0; i < 1000; ++i) {double temp = std::sin(i);Q_UNUSED(temp);}// 繪制所有圓形for (const auto &circle : circles) {bufferPainter.setPen(Qt::NoPen);bufferPainter.setBrush(circle.color);bufferPainter.drawEllipse(circle.pos, circle.radius, circle.radius);}}
};

singlebufferwidget.h

#include <QWidget>
#include <QTime>
#include <QPainter>
#include <QTimer>
#include <math.h>
#include <qmath.h>
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class SingleBufferWidget; }
QT_END_NAMESPACEclass SingleBufferWidget : public QWidget {Q_OBJECT
public:SingleBufferWidget(QWidget *parent = nullptr) : QWidget(parent) {// 初始化動畫數據for (int i = 0; i < 5000; ++i) {circles.append({QPointF(rand() % width(), rand() % height()),5.f + rand() % 10,QColor(rand() % 256, rand() % 256, rand() % 256),QPointF((rand() % 100 - 50) / 100.0, (rand() % 100 - 50) / 100.0)});}// 設置定時器更新動畫QTimer *timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &SingleBufferWidget::updateAnimation);timer->start(16);}void paintEvent(QPaintEvent *event) override {QTime SingpaintTimer;SingpaintTimer.start();Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 模擬長時間繪制過程for (int i = 0; i < 1000; ++i) {// 這個循環會延長繪制時間,加劇閃爍現象double temp = std::sin(i);Q_UNUSED(temp);}// 繪制所有圓形for (const auto &circle : circles) {painter.setPen(Qt::NoPen);painter.setBrush(circle.color);painter.drawEllipse(circle.pos, circle.radius, circle.radius);}qInfo() << "void paintEvent(QPaintEvent *event) SingpaintTimer cost times:" << SingpaintTimer.elapsed() << "ms";}private slots:void updateAnimation() {// 更新所有圓形位置for (auto &circle : circles) {circle.pos += circle.velocity;if (circle.pos.x() - circle.radius < 0 || circle.pos.x() + circle.radius > width())circle.velocity.setX(-circle.velocity.x());if (circle.pos.y() - circle.radius < 0 || circle.pos.y() + circle.radius > height())circle.velocity.setY(-circle.velocity.y());}update();}private:struct Circle {QPointF pos;qreal radius;QColor color;QPointF velocity;};QVector<Circle> circles;
};

3.工程文件資源

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83629.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

華為云AI開發平臺ModelArts

華為云ModelArts&#xff1a;重塑AI開發流程的“智能引擎”與“創新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企業擁抱AI的意愿空前高漲&#xff0c;但技術門檻高、流程復雜、資源投入巨大的現實&#xff0c;卻讓許多創新構想止步于實驗室。數據科學家…

ParaGraphX [特殊字符]

https://github.com/stevechampion1/paragraphx 一個基于 JAX 的、為 CPU/GPU 加速而生的超高性能圖算法庫。 ParaGraphX 是一個實驗性的 Python 庫&#xff0c;旨在利用 JAX 的即時編譯 (JIT) 和大規模并行計算能力&#xff0c;為經典的圖算法提供驚人的性能提升。我們的目標…

如何用4 種可靠的方法更換 iPhone(2025 年指南)

Apple 每年都會發布新版本的 iPhone。升級到新 iPhone 是一種令人興奮的體驗&#xff0c;但轉移所有寶貴數據的想法有時會讓人感到畏懼。幸運的是&#xff0c;我們準備了 4 種有效的更換 iPhone 的方法&#xff0c;讓你可以毫不費力地更換到你的新 iPhone。 此外&#xff0c;您…

GitLab 拉取變慢的原因及排查方法

前言&#xff1a;在軟件開發的快節奏世界里&#xff0c;高效協作與快速交付是制勝關鍵。然而&#xff0c;當開發團隊興高采烈地投入工作&#xff0c;卻發現從GitLab拉取代碼的速度慢如蝸牛&#xff0c;那種沮喪感簡直能瞬間澆滅熱情。在分布式開發環境中&#xff0c;這種情況時…

落水人員目標檢測數據集(貓臉碼客第253期)

落水人員目標檢測&#xff1a;科技守護生命之舟 一、背景與意義 隨著人類海洋活動和水上活動的日益頻繁&#xff0c;海上與水域安全事故頻發。每年都會開展大量的海上救援行動&#xff0c;以搜救數以萬計的落難人員。在水上活動區域&#xff0c;如水庫、河道等&#xff0c;溺…

JAVA_強制類型轉換:

類型范圍大的變量&#xff0c;不可以直接賦值給類型變量小的變量 需要進行強制類型轉換&#xff1a; 想要完成類型范圍大的變量傳給類型范圍小的變量需要先創建一個新的變量&#xff08;類型與方法的形參類型要相同&#xff09;。將類型范圍大的變量前面加上&#xff08;轉換類…

打卡第44天:無人機數據集分類

重復以下內容 作業&#xff1a; kaggle找到一個圖像數據集&#xff0c;用cnn網絡進行訓練并且用grad-cam做可視化 進階&#xff1a; 并拆分成多個文件 import os import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader,…

個人網站大更新,還是有個總站比較好

個人網站大更新&#xff0c;還是有個總站比較好 放棄了所有框架&#xff0c;用純htmlcssjs擼了個網站&#xff0c;這回可以想改啥改啥了。 選擇了黑紫作為主色調&#xff0c;暫時看著還算可以。 為什么不用那些框架了 幾個原因&#xff1a; 嘗試用vuepress、vitepress、not…

高精度算法詳解:從原理到加減乘除的完整實現

文章目錄 一、為什么需要高精度算法二、高精度算法的數據結構設計2.1 基礎工具函數2.2 高精度加法實現2.3 高精度減法實現2.4 高精度乘法實現2.5 高精度除法實現 三、完整測試程序四、總結 一、為什么需要高精度算法 在編程中&#xff0c;處理極大數值是常見需求&#xff0c;例…

排序--計數排序

一,引言 計數排序是一種針對整數數據的高效排序算法。其主要流程可分為三個步驟&#xff1a;首先計算整數數據的數值范圍&#xff1b;接著按大小順序統計各數值的出現次數&#xff1b;最后根據統計結果輸出排序后的數據序列。 二,求最值 遍歷現有數據&#xff0c;獲取最大值…

Kubernetes安全機制深度解析(四):動態準入控制和Webhook

#作者&#xff1a;程宏斌 文章目錄 動態準入控制什么是準入 Webhook&#xff1f; 嘗試準入Webhook先決條件編寫一個準入 Webhook 服務器部署準入 Webhook 服務即時配置準入 Webhook對 API 服務器進行身份認證 Webhook 請求與響應Webhook 配置匹配請求-規則匹配請求&#xff1a…

WDK 10.0.19041.685,可在32位win7 sp1系統下搭配vs2019使用,可以編譯出xp驅動。

(14)[驅動開發]配置環境 VS2019 WDK10 寫 xp驅動 (14)[驅動開發]配置環境 VS2019 WDK10 寫 xp驅動_microsoft visual 2019 wdk-CSDN博客文章瀏覽閱讀3k次&#xff0c;點贊8次&#xff0c;收藏17次。本文介紹了如何在VS2019環境下安裝和配置Windows Driver Kit(WDK)&#xff0…

論壇系統自動化測試

1、項目背景與測試目標 系統定位 論壇系統作為典型的高并發Web應用&#xff0c;需支持用戶注冊、登錄、發帖、評論、私信及個人中心管理等核心功能&#xff0c;是用戶公開交流與信息共享的核心平臺。其穩定性與響應效率直接影響用戶體驗及平臺活躍度。 測試必要性 功能可靠性&…

ChipWhisperer教程(一)

一、ChipWhisperer介紹 ChipWhisperer 是一個完整的開源工具鏈&#xff0c;用于學習嵌入式設備上的側信道攻擊并驗證這些設備的側信道抗性。ChipWhisperer主要用于功耗分析&#xff0c;利用設備功耗泄露的信息進行攻擊&#xff0c;也可用于故障攻擊&#xff08;電壓和時鐘毛刺…

【持續更新】計算機網絡試題

問題1 請簡要說明TCP/IP協議棧的四層結構&#xff0c;并分別舉出每一層出現的典型協議或應用。 答案 應用層&#xff1a;ping,telnet,dns 傳輸層&#xff1a;tcp,udp 網絡層&#xff1a;ip,icmp 數據鏈路層&#xff1a;arp,rarp 問題2 下列協議或應用分別屬于TCP/IP協議…

短劇系統開發:打造高效、創新的短視頻娛樂平臺 - 從0到1的完整解決方案

一、短劇市場迎來爆發式增長 - 不容錯過的萬億級藍海 隨著5G技術的普及和移動互聯網的深度滲透&#xff0c;短劇市場正在經歷前所未有的爆發式增長。根據權威機構艾瑞咨詢最新發布的《2023年中國網絡短劇行業發展報告》顯示&#xff1a; 市場規模&#xff1a;2023年中國短劇市…

ChipWhisperer教程(三)

——CW305目標板的波形采集 一、目標板介紹 CW305 是一款獨立的 FPGA 目標板&#xff0c;搭載的FPGA芯片為Xilinx Artix-7系列。 它具有與 FPGA 通信的 USB 接口、為 FPGA 提供時鐘的外部 PLL、編程 VCC-INT 電源以及用于故障注入環境的二極管保護。 CW305 電路板有多種配置&…

django中如何解析content-type=application/json的請求

django中如何解析content-typeapplication/json的請求 本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; 往期文章回顧: …

Chainlink VRF 深度解析與實戰

背景 在區塊鏈的去中心化應用中&#xff0c;隨機性是一個常見但難以實現的需求。例如&#xff0c;區塊鏈游戲需要隨機決定戰斗結果&#xff0c;NFT 項目需要隨機分配稀有屬性&#xff0c;去中心化抽獎需要公平選擇獲獎者。然而&#xff0c;傳統的鏈上隨機數生成方法&#xff0…

7. TypeScript接口

TypeScript 中的接口&#xff08;Interfaces&#xff09;用于定義對象的結構。它們允許開發者指定一個對象應具有哪些屬性以及這些屬性的類型。接口有助于確保對象遵循特定的結構&#xff0c;從而在整個應用中提供一致性&#xff0c;并提升代碼的可維護性。 一、認識接口 Typ…