qt 双缓冲绘图


[cpp]  view plain  copy
  1. private slots:  
  2.     void mousePressEvent(QMouseEvent *event);  
  3.     void mouseMoveEvent(QMouseEvent *);  
  4.     void mouseReleaseEvent(QMouseEvent *);  
  5. private:  
  6.     QPixmap pix;  
  7.     QPoint lastPoint;  
  8.     QPoint endPoint;  
  9.     QPixmap tempPix; //临时画布  
  10.     bool isDrawing;   //标志是否正在绘图  

[cpp]  view plain  copy
  1. MainWindow::MainWindow(QWidget *parent) :  
  2.     QMainWindow(parent),  
  3.     ui(new Ui::MainWindow)  
  4. {  
  5.     ui->setupUi(this);  
  6.     resize(600,500);    //窗口大小设置为600*500  
  7.     pix = QPixmap(200,200);  
  8.     pix.fill(Qt::white);  
  9.     isDrawing = false;  
  10. }  
  11.   
  12. void MainWindow::mousePressEvent(QMouseEvent *event)  
  13. {  
  14.     if(event->button()==Qt::LeftButton) //鼠标左键按下  
  15.     {  
  16.         lastPoint = event->pos();  
  17.         isDrawing = true;   //正在绘图  
  18.     }  
  19. }  
  20.   
  21.   
  22. void MainWindow::mouseMoveEvent(QMouseEvent *event)  
  23. {  
  24.     if(event->buttons()&Qt::LeftButton) //鼠标左键按下的同时移动鼠标  
  25.     {  
  26.         endPoint = event->pos();  
  27.         update();  
  28.     }  
  29. }  
  30.   
  31.   
  32. void MainWindow::mouseReleaseEvent(QMouseEvent *event)  
  33. {  
  34.     if(event->button() == Qt::LeftButton) //鼠标左键释放  
  35.     {  
  36.         endPoint = event->pos();  
  37.         isDrawing = false;    //结束绘图  
  38.         update();  
  39.     }  
  40. }  




1.在paintEvent函数中如果直接在窗体上绘图,前1次画的矩形是不能保存住的
[cpp]  view plain  copy
  1. void MainWindow::paintEvent(QPaintEvent *)  
  2. {    
  3.     QPainter painter(this);  
  4.     int x,y,w,h;  
  5.     x = lastPoint.x();  
  6.     y = lastPoint.y();  
  7.     w = endPoint.x() - x;  
  8.     h = endPoint.y() - y;  
  9.     painter.drawRect(x,y,w,h);  
  10. }  
2.在paintEvent函数中如果直接在pix上绘图,前1次前2次前3次...画的都保存住了(鼠标每移动一点就会触发paintEvent函数而画一次),所以在pix上会呈现好多矩形
[cpp]  view plain  copy
  1. void MainWindow::paintEvent(QPaintEvent *)  
  2. {    
  3.     int x,y,w,h;  
  4.     x = lastPoint.x();  
  5.     y = lastPoint.y();  
  6.     w = endPoint.x() - x;  
  7.     h = endPoint.y() - y;  
  8.     QPainter pp(&pix);  
  9.     pp.drawRect(x,y,w,h);  
  10.   
  11.     QPainter painter(this);  
  12.     painter.drawPixmap(0,0,pix);  
  13. }  
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里面有一个矩形。。。

[cpp]  view plain  copy
  1. void MainWindow::paintEvent(QPaintEvent *)  
  2. {  
  3.   
  4.     int x,y,w,h;  
  5.     x = lastPoint.x();  
  6.     y = lastPoint.y();  
  7.     w = endPoint.x() - x;  
  8.     h = endPoint.y() - y;  
  9.   
  10.     QPainter painter(this);  
  11.     if(isDrawing)     //如果正在绘图  
  12.     {  
  13.         tempPix = pix;    //将以前pix中的内容复制到tempPix中,这样实现了交互绘图  
  14.         QPainter pp(&tempPix);  
  15.         pp.drawRect(x,y,w,h);  
  16.         painter.drawPixmap(0,0,tempPix);  
  17.     }  
  18.     else  
  19.     {  
  20.         QPainter pp(&pix);  
  21.         pp.drawRect(x,y,w,h);  
  22.         painter.drawPixmap(0,0,pix);  
  23.     }  
  24. }  

猜你喜欢

转载自blog.csdn.net/kaida1234/article/details/80208266