目录
实现过程:
在缓冲区里创建一个画布,将缓冲区(pix)的内容复制给临时缓冲区(tempPix);
在临时缓冲区上绘画一个矩形,然后在主部件绘画临时缓冲区的内容;
判断是否完成绘制,如果已经完成绘制,那么更新缓冲区。将临时缓冲区的内容复制给缓冲区(为了第二次绘制时保存上一次绘制的图);
当鼠标按下并移动时(这时进行第二次绘制),将缓冲区的内容复制到临时缓冲区去;
效果图
.h文件
#ifndef MAINWIN_H
#define MAINWIN_H
#include <QWidget>
#include <QPixmap>
class MainWin : public QWidget
{
Q_OBJECT
public:
explicit MainWin(QWidget *parent = 0);
protected:
void mousePressEvent(QMouseEvent* ev) override;
void mouseMoveEvent(QMouseEvent* ev) override;
void mouseReleaseEvent(QMouseEvent* ev) override;
void paintEvent(QPaintEvent* ev) override;
private:
QPixmap m_pix; //画布
QPixmap m_tempPix; //临时画布
QPoint m_startPoint;
QPoint m_endPoint;
bool m_isDrawing;//是否正在绘制
};
#endif // MAINWIN_H
.cpp文件
#include "main_win.h"
#include <QMouseEvent>
#include <QPainter>
MainWin::MainWin(QWidget *parent) : QWidget(parent)
{
m_pix = QPixmap(this->width(), this->height());
m_pix.fill(Qt::white);
m_tempPix = m_pix; //将pix内容复制给tempPix,在tempPix里绘制。
m_isDrawing = false;
}
void MainWin::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
//当鼠标左键按下时获取当前位置作为矩形的开始点
m_startPoint = ev->pos();
//标记正在绘图
m_isDrawing = true;
}
}
void MainWin::mouseMoveEvent(QMouseEvent *ev)
{
if(ev->buttons() & Qt::LeftButton)
{
//当按着鼠标左键移动时,获取当前位置作为结束点,绘制矩形
m_endPoint = ev->pos();
//将缓冲区的内容复制到临时缓冲区,这样进行动态绘制时
//每次都是在缓冲区图像的基上进行绘制,就不会产生拖影现象了
m_tempPix = m_pix;
//更新显示
update();
}
}
void MainWin::mouseReleaseEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
//当鼠标左键松开时,获取当前位置为结束点,完成矩形绘制
m_endPoint = ev->pos();
//标记已经结束绘图
m_isDrawing = false;
update();
}
}
void MainWin::paintEvent(QPaintEvent *ev)
{
int x = m_startPoint.x();
int y = m_startPoint.y();
int width = m_endPoint.x() - x; //获取宽
int height = m_endPoint.y() - y; //获取高
QPainter tempPainter(&m_tempPix); //在tempPix上绘画
tempPainter.drawRect(x,y,width,height); //在tempPix中绘制矩形
QPainter painter(this); //在主部件上绘画
painter.drawPixmap(0,0,m_tempPix); //在主部件中绘制矩形
//如果已经完成了绘制,那么更新缓冲区
if(!m_isDrawing)
m_pix = m_tempPix;
}