当前位置:网站首页>QT - double buffer plot

QT - double buffer plot

2022-07-04 21:48:00 Half-up

So-called Double buffering (double-buffers) mapping , It's when you're drawing , First draw everything to a drawing device ( Such as QPixmap) On , And then the whole image is drawn on the part and displayed .

Use double buffer drawing It can avoid flickering when displaying .

from Qt 4.0 Start ,QWidget All drawing of the part automatically uses double buffering , So generally there is no need to paintEvent() Function to avoid flicker .

Although there is no need to use double buffer drawing manually in general drawing , But to achieve some graphic effects , Or with the help of the concept of double buffering .

The following program is implemented Use the mouse to draw a rectangle of any size on the interface .

Two canvases are needed here , They are all QPixmap example , One of them tempPix Used as a Temporary buffer , When the mouse is dragging the rectangle to draw , Draw the content first to tempPix On , And then tempPix Draw on the interface ; And another one. pix As a buffer , Used to save the finished drawing .

When you release the mouse to finish drawing the rectangle , Will tempPix Copy the contents of to pix On .

In order not to show the drag when drawing , In the process of moving the mouse , Every time you draw, you should draw on the image that you just drew the rectangle , So you need to draw every time tempPix Before , First the pix Copy the contents of to tempPix On .

newly build Qt Widgets application , Project name: mydoublebuffers, Base class selection QWidget, Class called Widget.
When it's done , stay widget.h Add the following to the file :

private:
    Ui::Widget *ui;
    //  buffer 
    QPixmap pix;
    //  Temporary buffer 
    QPixmap tempPix;
    QPoint startPoint;
    QPoint endPoint;
    //  Whether the sign is being drawn 
    bool isDrawing;

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);

Here, the method and painting equipment are defined
And then to widget.cpp In file , First add the header file

#include <QMouseEvent>
#include <QPainter>

Then add some variables to the constructor and initialize

  pix = QPixmap(400, 300);
    pix.fill(Qt::white);
    tempPix = pix;
    isDrawing = false;

pix yes 400,300 Size QPixmap equipment , white , Copy to tempPix Prevent ghosting ,isDrawing close

The following is the mouse event handler :

void Widget::mousePressEvent(QMouseEvent *event)
{
    
    if(event->button() == Qt::LeftButton) {
    
        //  When the left mouse button is pressed, the current position is obtained as the starting point of the rectangle 
        startPoint = event->pos();
        //  The tag is drawing 
        isDrawing = true;
    }
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    
    if(event->buttons() & Qt::LeftButton) {
    
        //  When you press the left mouse button to move , Get the current position as the end point , Draw a rectangle 
        endPoint = event->pos();
        //  Copy the contents of the buffer to the temporary buffer , When doing dynamic rendering like this ,
        //  Each time, it is drawn on the base of the buffer image , There will be no drag phenomenon 
        tempPix = pix;
        //  Update display 
        update();
    }
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    
    if(event->button() == Qt::LeftButton) {
    
        //  When the left mouse button is released , Get the current position as the end point , Complete rectangle drawing 
        endPoint = event->pos();
        //  Marking has ended drawing 
        isDrawing = false;
        update();
    }
}

Here we get Position of the upper left corner of the rectangle to be drawn , Then mark that the rectangle is being drawn .

In the mouse movement event handler Get the position of the lower right corner of the rectangle to be drawn , Then draw the rectangle dynamically , Here, in order not to draw a bunch of small rectangles, the so-called Drag phenomenon , Just before drawing the temporary buffer , Copy the contents of the buffer into the temporary buffer . such Each time, it is drawn on the basis of the buffer image , Therefore, there will be no drag phenomenon .

Finally, in the mouse button release event handler , Get the coordinates of the lower right corner of the rectangle , Marking has ended drawing .

Next, add the definition of redrawing event handler :

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 you have finished drawing , Then update the buffer 
    if(!isDrawing)
        pix = tempPix;
}

Here in the first Temporary buffer tempPix Drawing in , Then draw it on the interface .

Finally, judge whether the drawing has been completed , If it is , Then copy the contents of the temporary buffer to the buffer , This completes the drawing of the whole rectangle .
 Insert picture description here

 Insert picture description here

The key in this example is pix and tempPix Mutual replication , If you want to extend this program , You can check the graffiti board program on the website .

An application very similar to this example is rubber band , Is that we are Windows Drag the mouse on the desktop to show the rubber band selection box .Qt Provided in QRubberBand Class to implement the rubber band line , To use it, you only need to set it in a few mouse event handling functions , For specific applications, you can view the help documents of this class .

原网站

版权声明
本文为[Half-up]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/185/202207042048590111.html