Qt双缓冲绘图
1. 双缓冲的概念
- 双缓冲绘图就是在绘制时,先将所有内容都绘制到一个绘图设备上,然后再将整个图像绘制到部件上显示出来。
- 使用双缓冲绘图可以避免显示时的闪烁现象。
- 从Qt 4.0开始,QWidget部件的所有绘制都自动使用了双缓冲,所以一般没有必要在paintEvent()函数中使用双缓冲代码来避免闪烁。
- 不过要想实现一些绘图效果,还是要借助双缓冲的概念。
2. 应用示例和代码
- 下面的程序实现使用鼠标在界面绘制一个任意大小的矩形的功能。

- .h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
QPixmap pix;
QPixmap tempPix;
QPoint startPoint;
QPoint endPoint;
bool isDrawing;
protected:
void mousePressEvent(QMouseEvent * event);
void mouseMoveEvent(QMouseEvent * event);
void mouseReleaseEvent(QMouseEvent * event);
void paintEvent(QPaintEvent * event);
};
#endif
#include "widget.h"
#include "ui_widget.h"
#include <QMouseEvent>
#include <QPainter>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
pix = QPixmap(400,300);
pix.fill(Qt::white);
tempPix = pix;
isDrawing = false;
}
Widget::~Widget()
{
delete ui;
}
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
startPoint = event->pos();
isDrawing = true;
}
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons()==Qt::LeftButton)
{
endPoint = event->pos();
tempPix=pix;
update();
}
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
endPoint=event->pos();
isDrawing=false;
update();
}
}
void Widget::paintEvent(QPaintEvent *event)
{
int x=startPoint.x();
int y=startPoint.y();
int width=endPoint.x()-x;
int height=endPoint.y()-y;
QPainter painter;
painter.begin(&tempPix);
painter.drawRect(x,y,width,height);
painter.end();
painter.begin(this);
painter.drawPixmap(0,0,tempPix);
if(!isDrawing)
pix=tempPix;
}
3. 橡皮筋
- Qt中提供了QRubberBand类来实现橡皮筋。