Qt双缓冲机制与应用方法

1、双缓冲机制

所谓双缓冲机制,是指在绘制控件时,首先将要绘制的内容绘制在一个图片中,再将图片一次性地绘制到控件上。

在早期的Qt版本中,若直接在控件上进行绘制工作,则在控件重绘时会产生闪烁的现象,控件重绘频繁时,闪烁尤为明显。双缓冲机制可以有效地消除这种闪烁现象。自 Qt 5 版本之后,QWidget 控件已经能够自动处理闪烁的问题。

因此,在控件上直接绘图时,不用再操心显示的闪烁问题,但双缓冲机制在很多场合仍然有其用武之地。当所需绘制的内容较复杂并需要频繁刷新,或者每次只需要刷新整个控件的一小部分时,仍应尽量采用双缓冲机制。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

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开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Qt C++ 中使用双缓冲技术进行绘图,可以按照以下步骤进行操作: 1. 创建一个自定义的 QWidget 子类,例如 MyPaintWidget,用于绘制图形。 ```cpp class MyPaintWidget : public QWidget { Q_OBJECT public: explicit MyPaintWidget(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; private: QImage buffer; // 双缓冲区 }; MyPaintWidget::MyPaintWidget(QWidget *parent) : QWidget(parent) { // 设置窗口属性,启用双缓冲绘制 setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); } void MyPaintWidget::paintEvent(QPaintEvent *event) { // 创建绘图对象,并将其绑定到双缓冲区 QPainter painter(&buffer); // 在双缓冲区上进行绘制 painter.fillRect(rect(), Qt::white); // 绘制白色背景 painter.setPen(Qt::black); // 设置画笔颜色为黑色 painter.drawLine(0, 0, width(), height()); // 绘制一条线段 // 将双缓冲区的内容绘制到窗口上 painter.begin(this); painter.drawImage(0, 0, buffer); painter.end(); } ``` 2. 在主窗口的构造函数中创建 MyPaintWidget 对象,并将其添加到布局中。 ```cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { MyPaintWidget *paintWidget = new MyPaintWidget(this); setCentralWidget(paintWidget); } ``` 通过以上步骤,我们创建了一个自定义的 QWidget 子类,并在其中实现了双缓冲绘图的功能。在 paintEvent 函数中,首先将绘图操作绘制在双缓冲区(buffer)上,然后再将双缓冲区的内容绘制到窗口上。这样可以避免图形闪烁的问题,并提高绘图的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值