首頁 > 軟體

詳解Qt中的雙緩衝機制與範例應用

2023-03-13 06:00:52

1、雙緩衝機制

所謂雙緩衝機制,是指在繪製控制元件時,首先將要繪製的內容繪製在一個圖片中,再將圖片一次性地繪製到控制元件上。

在早期的Qt版本中,若直接在控制元件上進行繪製工作,則在控制元件重繪時會產生閃爍的現象,控制元件重繪頻繁時,閃爍尤為明顯。雙緩衝機制可以有效地消除這種閃爍現象。自 Qt 5 版本之後,QWidget 控制元件已經能夠自動處理閃爍的問題。

因此,在控制元件上直接繪圖時,不用再操心顯示的閃爍問題,但雙緩衝機制在很多場合仍然有其用武之地。當所需繪製的內容較複雜並需要頻繁重新整理,或者每次只需要重新整理整個控制元件的一小部分時,仍應儘量採用雙緩衝機制。

2、範例效果圖

實現一個簡單的繪圖工具,可以選擇線形,線寬,顏色等基本要素。效果圖如下所示:

3、範例核心程式碼

PaintArea.h:

#ifndef PAINTAREA_H
#define PAINTAREA_H
 
#include <QWidget>
#include <QPen>
#include <QBrush>
#include <QMouseEvent>
#include <QPainter>
 
// 繪圖區域
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); // 設定形狀
    void setPen(QPen pen); // 設定畫筆
    void setBrush(QBrush brush); // 設定畫刷
    void clear(); // 清除繪圖區域
 
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; // 滑鼠移動繪圖的結束座標
};
 
#endif // PAINTAREA_H

PaintArea.cpp:

#include "PaintArea.h"
 
PaintArea::PaintArea(QWidget *parent) :
    QWidget(parent)
{
    // 設定尺寸
    this->setMinimumSize(600, 300);
 
    // 用調色盤設定背景色
    this->setPalette(QPalette(Qt::white));
    this->setAutoFillBackground(true);
 
    // 初始化畫布
    m_pix = new QPixmap(size()); // 此QPixmap物件用來準備隨時接收繪製的內容
    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);
}
 
// 設定形狀
void PaintArea::setShape(Shape shape)
{
    m_shape = shape;
}
 
// 設定畫筆
void PaintArea::setPen(QPen pen)
{
    m_pen = pen;
}
 
// 設定畫刷
void PaintArea::setBrush(QBrush brush)
{
    m_brush = brush;
}
 
// 清除繪圖區域
void PaintArea::clear()
{
    QPixmap *clearPix  =new QPixmap(size());
    clearPix->fill(Qt::white);
    m_pix = clearPix;
    this->update();
}

4、雙緩衝具體實現程式碼

下面是實現雙緩衝區域的地方:

PaintArea::PaintArea(QWidget *parent) :
    QWidget(parent)
{
    // 設定尺寸
    this->setMinimumSize(600, 300);
 
    // 用調色盤設定背景色
    this->setPalette(QPalette(Qt::white));
    this->setAutoFillBackground(true);
 
    // 初始化畫布
    m_pix = new QPixmap(size()); // 此QPixmap物件用來準備隨時接收繪製的內容
    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 裡面畫畫,在這裡,我們呼叫drawPixmap()函數,將用於接收圖形繪製的 QPixmap 物件繪製在繪製區表單控制元件上,這樣就實現了雙緩衝機制。

到此這篇關於詳解Qt中的雙緩衝機制與範例應用的文章就介紹到這了,更多相關Qt雙緩衝機制內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com