Qt double buffer drawing

Reprinted from: https://wizardforcel.gitbooks.io/qt-beginning/content/22.html

Introduction

In the previous section, I described how to implement a simple graffiti board. This time we will implement drawing graphics on the graffiti board. Here we will use the rectangle as an example. The concept of double-buffered drawing will be presented later.

Environment: Windows Xp + Qt 4.8.4 + QtCreator 2.6.2

table of Contents

  • First, draw a rectangle
  • Two, double buffered drawing

text

First, draw a rectangle

1. We still modify on the basis of the previous program, first change the painEvent()function:

 
  1. void Dialog::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. }

Here is to determine the starting point, width and height of the rectangle to be drawn through the lastPoint and endPoint points. Run the program and drag out a rectangle with the mouse, the effect is shown in the figure below.

18-1.jpguploading.4e448015.gifUnsuccessful transfer and re-upload cancel

2. A rectangle can be dragged out from above, but this way you can draw directly on the window. The previously drawn rectangle cannot be saved. So we add the canvas below and draw on the canvas. paintEvent()Change the function as follows:

 
  1. void Dialog::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. QPainter painter(this);

  11. painter.drawPixmap(0, 0, pix);

  12. }

Here is to draw the graphics on the canvas first, and then draw the canvas to the window. We run the program, and then use the mouse to drag out a rectangle, and found that there are many ghosts, the effect is shown below.

18-2.jpguploading.4e448015.gifUnsuccessful transfer and re-upload cancel

Why would such phenomenon happen? You can try to draw the rectangle quickly by dragging the mouse and slowly by dragging the mouse. As a result, you will find that the faster the drag speed, the less ghosting. In fact, in the process of dragging the mouse, the screen has been refreshed many times, and it can also be understood that the paintEvent()function is executed many times, and a rectangle is drawn every time it is executed. Knowing the reason, there are ways to avoid this problem.

Two, double buffered drawing

1. We add another auxiliary canvas. If we are drawing, that is, when the mouse button has not been released, we draw on this auxiliary canvas. Only when the mouse button is released, we will draw on the real canvas.

First dialog.hadd two private variables to the file:

 
  1. QPixmap tempPix; //辅助画布

  2. bool isDrawing; //标志是否正在绘图

Then dialog.cppinitialize the variable in the constructor:

isDrawing = false;

Then change the paintEvent()function:

 
  1. void Dialog::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 painter(this);

  9. if(isDrawing) //如果正在绘图,就在辅助画布上绘制

  10. {

  11. //将以前pix中的内容复制到tempPix中,保证以前的内容不消失

  12. tempPix = pix;

  13. QPainter pp(&tempPix);

  14. pp.drawRect(x,y,w,h);

  15. painter.drawPixmap(0, 0, tempPix);

  16. } else {

  17. QPainter pp(&pix);

  18. pp.drawRect(x,y,w,h);

  19. painter.drawPixmap(0,0,pix);

  20. }

  21. }

The following also needs to change the content of the mouse down event handler and mouse release event handler:

 
  1. void Dialog::mousePressEvent(QMouseEvent *event)

  2. {

  3. if(event->button()==Qt::LeftButton) //鼠标左键按下

  4. {

  5. lastPoint = event->pos();

  6. isDrawing = true; //正在绘图

  7. }

  8. }

  9. void Dialog::mouseReleaseEvent(QMouseEvent *event)

  10. {

  11. if(event->button() == Qt::LeftButton) //鼠标左键释放

  12. {

  13. endPoint = event->pos();

  14. isDrawing = false; //结束绘图

  15. update();

  16. }

  17. }

When the left mouse button is pressed, we start marking the drawing, when the button is released, we cancel the marking of the drawing. Now run the program and you can achieve normal drawing. Results as shown below.

18-3.jpguploading.4e448015.gifUnsuccessful transfer and re-upload cancel

2. Double buffered drawing

Based on the technique used in this example, we introduce the concept of so-called double-buffered drawing. Double-buffers (double-buffers) drawing, that is, when drawing, all content is drawn to a drawing device (such as QPixmap), and then the entire image is drawn on the part and displayed. Using double-buffered drawing can avoid flickering during display. Starting from Qt 4.0, QWidgetall drawing of parts automatically uses double buffering, so there is generally no need paintEvent()to use double buffering code in functions to avoid flicker.

Although there is no need to manually use double-buffered drawing in general drawing, but to achieve some drawing effects, you still have to rely on the concept of double-buffering. For example, in this program, we want to use the mouse to draw a rectangle of any size on the interface. It should be two canvases, which are QPixmapinstances in which a tempPixused as a temporary buffer when the mouse is dragged to draw a rectangle, the first content to draw tempPixon, and then tempPixdrawn to the interface; and the other pixas a buffer , Used to save the completed drawing. When you release the mouse to complete the drawing of the rectangle, tempPixthe content is copied to pix. In order not to show the smear when drawing, and to ensure that the previously drawn content does not disappear, then every time you draw during the mouse movement, you must draw on the original image of the rectangle, so you need to draw tempPixbefore each time , First copy the content of pix onto tempPixit. Because there are two QPixmapobjects here , it can be said that there are two buffers, so it is called double-buffered drawing.

Conclusion

For the content of Qt basic drawing, we will talk about it here. If you want to learn these basic knowledge more systematically and in-depth, you can refer to Chapter 10 of "Quick Start of Qt Creator". From the next section, we will briefly introduce the graphical view framework in Qt.

Published 85 original articles · praised 18 · 120,000 views

Guess you like

Origin blog.csdn.net/a1317338022/article/details/105534088