Search code examples
qtgraphicsdrawingqt-creator

Qt Drawing Lines


I am learning Qt, and I want to draw lines randomly on a widget and keep appending the new lines. The code below draws a random line in the paintEvent whenever an update is called on the widget, but how do I stop the widget from clearing the previously drawn line when paintEvent is called? Is there any way to just append drawn objects?

Obviously I could store all the lines and repaint them every time, but that seems unnecessary for what I will be doing with this application.

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(Qt::black, 2));

        painter.drawLine(QPointF(qrand() % 300, qrand() % 300), QPointF(qrand() % 300,qrand() % 300));
}



void MainWindow::on_b_toggleDrawing_triggered()
{
    this->update();
}

Solution

  • You could draw the lines on an off-screen surface and blit them to the widget in the paint event. A QImage would be ideal as it is a QPaintDevice and could be drawn using QPainter::drawImage. The snippet below assumes that this->image is a pointer to a QImage with the same size as the MainWindow.

    void MainWindow::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
    
        painter.drawImage(this->rect, *this->image);
    }
    
    void MainWindow::on_b_toggleDrawing_triggered()
    {
        QPainter painter(this->image);
    
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(Qt::black, 2));
        painter.drawLine(QPointF(qrand() % 300, qrand() % 300),
                         QPointF(qrand() % 300,qrand() % 300));
    
        this->update();
    }
    

    An alternative would be to build a path using QPainterPath. In that case, you would simply maintain a QPainterPath instance, add lines as needed and then draw the path in the paint event handler. I'm not as familiar with painter paths. So, I'm not sure how the performance compares with the previous approach.