qt 双缓冲绘图

refer to
http://www.yafeilinux.com/?p=73
private slots:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
private:
    QPixmap pix;
    QPoint lastPoint;
    QPoint endPoint;
    QPixmap tempPix; //临时画布
    bool isDrawing;   //标志是否正在绘图

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    resize(600,500);    //窗口大小设置为600*500
    pix = QPixmap(200,200);
    pix.fill(Qt::white);
    isDrawing = false;
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton) //鼠标左键按下
    {
        lastPoint = event->pos();
        isDrawing = true;   //正在绘图
    }
}


void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons()&Qt::LeftButton) //鼠标左键按下的同时移动鼠标
    {
        endPoint = event->pos();
        update();
    }
}


void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton) //鼠标左键释放
    {
        endPoint = event->pos();
        isDrawing = false;    //结束绘图
        update();
    }
}





1.在paintEvent函数中如果直接在窗体上绘图,前1次画的矩形是不能保存住的
void MainWindow::paintEvent(QPaintEvent *)
{  
    QPainter painter(this);
    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() - x;
    h = endPoint.y() - y;
    painter.drawRect(x,y,w,h);
}
2.在paintEvent函数中如果直接在pix上绘图,前1次前2次前3次...画的都保存住了(鼠标每移动一点就会触发paintEvent函数而画一次),所以在pix上会呈现好多矩形
void MainWindow::paintEvent(QPaintEvent *)
{  
    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() - x;
    h = endPoint.y() - y;
    QPainter pp(&pix);
    pp.drawRect(x,y,w,h);

    QPainter painter(this);
    painter.drawPixmap(0,0,pix);
}
3.双缓冲绘图,原理是在拖动过程中先把原来的图形复制到tempPix里面并在tempPix里面画,我们此时看到的就是在tempPix里的图形。只在鼠标释放的时候才在pix绘一次。
在paintEvent函数中,如果左键正在按着拖动,那就每次paintEvent事件时都在tempPix上绘图,并且在tempPix上绘图之前把pix复制给tempPix。而在左键释放的时候在pix上画图,仅一次。所以
当第1次按下左键拖动时,pix为空,在拖动过程中产生的每次paintEvent事件里面先把pix复制给tempPix,然后再在tempPix上绘图。这样在拖动过程中,我们看到的就是tempPix里面绘制的矩形+pix复制给tempPix的矩形,(而之前的拖动过程中在tempPix里绘的矩形都被pix的内容覆盖掉了,此时pix为空,所以什么也没有)。然后在左键释放时,触发paintEvent来在pix里绘制一次矩形。这样鼠标释放后我们看到的矩形就是在pix里面的一个矩形(此时tempPix也还在,因为不是临时的嘛,但必pix少一个矩形)
当第2次按下左键拖动时,pix里面有一个矩形。。。

void MainWindow::paintEvent(QPaintEvent *)
{

    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() - x;
    h = endPoint.y() - y;

    QPainter painter(this);
    if(isDrawing)     //如果正在绘图
    {
        tempPix = pix;    //将以前pix中的内容复制到tempPix中,这样实现了交互绘图
        QPainter pp(&tempPix);
        pp.drawRect(x,y,w,h);
        painter.drawPixmap(0,0,tempPix);
    }
    else
    {
        QPainter pp(&pix);
        pp.drawRect(x,y,w,h);
        painter.drawPixmap(0,0,pix);
    }
}


你可能感兴趣的:(UI,qt,图形)