詳解Qt中的雙緩沖機制與實例應(yīng)用
1、雙緩沖機制
所謂雙緩沖機制,是指在繪制控件時,首先將要繪制的內(nèi)容繪制在一個圖片中,再將圖片一次性地繪制到控件上。
在早期的Qt版本中,若直接在控件上進行繪制工作,則在控件重繪時會產(chǎn)生閃爍的現(xiàn)象,控件重繪頻繁時,閃爍尤為明顯。雙緩沖機制可以有效地消除這種閃爍現(xiàn)象。自 Qt 5 版本之后,QWidget 控件已經(jīng)能夠自動處理閃爍的問題。
因此,在控件上直接繪圖時,不用再操心顯示的閃爍問題,但雙緩沖機制在很多場合仍然有其用武之地。當所需繪制的內(nèi)容較復(fù)雜并需要頻繁刷新,或者每次只需要刷新整個控件的一小部分時,仍應(yīng)盡量采用雙緩沖機制。
2、實例效果圖
實現(xiàn)一個簡單的繪圖工具,可以選擇線形,線寬,顏色等基本要素。效果圖如下所示:
3、實例核心代碼
PaintArea.h:
#ifndef PAINTAREA_H #define PAINTAREA_H #include <QWidget> #include <QPen> #include <QBrush> #include <QMouseEvent> #include <QPainter> // 繪圖區(qū)域 class PaintArea : public QWidget { Q_OBJECT public: enum Shape{Dot, Line, Rectangle, RoundRect, Ellipse, Polygon, Polyline, Points, Arc, Path, Text, Pixmap}; explicit PaintArea(QWidget *parent = nullptr); void setShape(Shape shape); // 設(shè)置形狀 void setPen(QPen pen); // 設(shè)置畫筆 void setBrush(QBrush brush); // 設(shè)置畫刷 void clear(); // 清除繪圖區(qū)域 protected: void mousePressEvent(QMouseEvent *event); // 鼠標點擊事件 void mouseMoveEvent(QMouseEvent *event); // 鼠標移動事件 void paintEvent(QPaintEvent *event); // 繪圖事件 private: Shape m_shape; // 形狀 QPen m_pen; // 畫筆 QBrush m_brush; // 畫刷 QPixmap *m_pix; // 畫布 QPoint m_posStart; // 鼠標移動繪圖的開始坐標 QPoint m_posEnd; // 鼠標移動繪圖的結(jié)束坐標 }; #endif // PAINTAREA_H
PaintArea.cpp:
#include "PaintArea.h" PaintArea::PaintArea(QWidget *parent) : QWidget(parent) { // 設(shè)置尺寸 this->setMinimumSize(600, 300); // 用調(diào)色板設(shè)置背景色 this->setPalette(QPalette(Qt::white)); this->setAutoFillBackground(true); // 初始化畫布 m_pix = new QPixmap(size()); // 此QPixmap對象用來準備隨時接收繪制的內(nèi)容 m_pix->fill(Qt::white); // 填充背景色為白色 } // 鼠標點擊事件 void PaintArea::mousePressEvent(QMouseEvent *event) { m_posStart = event->pos(); } // 鼠標移動事件 void PaintArea::mouseMoveEvent(QMouseEvent *event) { QPainter *painter = new QPainter; // 鼠標移動繪圖在畫布pix上 painter->begin(m_pix); painter->setPen(m_pen); if(m_shape == Dot) painter->drawLine(m_posStart, event->pos()); else if(m_shape == Line) painter->drawLine(m_posStart, event->pos()); painter->end(); // 形狀為Dot時,也就是自由繪圖模式時,才時刻更新開始點擊坐標 if(m_shape == Dot) m_posStart = event->pos(); this->update(); } // 繪圖事件 void PaintArea::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawPixmap(QPoint(0,0),*m_pix); } // 設(shè)置形狀 void PaintArea::setShape(Shape shape) { m_shape = shape; } // 設(shè)置畫筆 void PaintArea::setPen(QPen pen) { m_pen = pen; } // 設(shè)置畫刷 void PaintArea::setBrush(QBrush brush) { m_brush = brush; } // 清除繪圖區(qū)域 void PaintArea::clear() { QPixmap *clearPix =new QPixmap(size()); clearPix->fill(Qt::white); m_pix = clearPix; this->update(); }
4、雙緩沖具體實現(xiàn)代碼
下面是實現(xiàn)雙緩沖區(qū)域的地方:
PaintArea::PaintArea(QWidget *parent) : QWidget(parent) { // 設(shè)置尺寸 this->setMinimumSize(600, 300); // 用調(diào)色板設(shè)置背景色 this->setPalette(QPalette(Qt::white)); this->setAutoFillBackground(true); // 初始化畫布 m_pix = new QPixmap(size()); // 此QPixmap對象用來準備隨時接收繪制的內(nèi)容 m_pix->fill(Qt::white); // 填充背景色為白色 } // 鼠標移動事件 void PaintArea::mouseMoveEvent(QMouseEvent *event) { QPainter *painter = new QPainter; // 鼠標移動繪圖在畫布pix上 painter->begin(m_pix); painter->setPen(m_pen); if(m_shape == Dot) painter->drawLine(m_posStart, event->pos()); else if(m_shape == Line) painter->drawLine(m_posStart, event->pos()); painter->end(); // 形狀為Dot時,也就是自由繪圖模式時,才時刻更新開始點擊坐標 if(m_shape == Dot) m_posStart = event->pos(); this->update(); } // 繪圖事件 void PaintArea::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawPixmap(QPoint(0,0), *m_pix); }
我們不是直接在面板上畫畫,而且在 Pixmap 里面畫畫,在這里,我們調(diào)用drawPixmap()函數(shù),將用于接收圖形繪制的 QPixmap 對象繪制在繪制區(qū)窗體控件上,這樣就實現(xiàn)了雙緩沖機制。
到此這篇關(guān)于詳解Qt中的雙緩沖機制與實例應(yīng)用的文章就介紹到這了,更多相關(guān)Qt雙緩沖機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)LeetCode(8.字符串轉(zhuǎn)為整數(shù))
這篇文章主要介紹了C++實現(xiàn)LeetCode(8.字符串轉(zhuǎn)為整數(shù)),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07C++中的static和const的關(guān)鍵字用法詳解
這篇文章主要介紹了C++中的static和const的關(guān)鍵字用法詳解,這是一道經(jīng)常在面試中被問到的知識,本文給大家詳細介紹下,需要的朋友可以參考下2023-06-06C++實現(xiàn)LeetCode(121.買賣股票的最佳時間)
這篇文章主要介紹了C++實現(xiàn)LeetCode(121.買賣股票的最佳時間),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07