详解Qt中的双缓冲机制与实例应用

2023-03-11 11:03:41 缓冲 实例 详解

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双缓冲机制内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章