Search code examples
qtpaintevent

Qt: Why does my paintEvent() erase everything before doing its job?


I'm trying to make my widget paint a rectangle with every paintEvent it receives. The rectangles are supposed to increase in size by 1px at a time, filling a square. What I get, however, is only the latest (and largest) rectangle.

void TestClass::paintEvent(QPaintEvent* e){
    static int size = 1;
    QStylePainter painter(this);
    painter.setPen(Qt::blue);
    painter.drawRect(QRect(50, 50, size, size));
    size++;
}

I don't understand why it would be that way. I expected the painter to just paint on top of what is already there. Instead it seems to delete the previously drawn rectangle, leaving me with a single rectangle at any time. Any ideas?

setAutoFillBackground(true/false) does not change anything but the color of the background.

To evoke a paintEvent I update() inside mousePressEvent(). So my rectangles grow with every click.

Thanks a lot.


Solution

  • So, to answer my own question, I found out that:

    (1) update(QRect area) erases the area specified by its argument before doing anything else. Calling update without argument erases the whole widget area.

    (2) The area that has been cleared is the only area that any painting is done on, even if your paintEvent() looks to paint somewhere else. The untouched part of the widget is not affected.

    For example, consider this paintEvent().

    void myWidget::paintEvent(QPaintEvent* e){
        QPainter painter(this);
        static int counter = 1;
    
        if (counter % 2){
            painter.fillRect(0, 0, 199, 199, Qt::blue); //Fill with blue color
        } else {
            painter.fillRect(0, 0, 199, 199, Qt::green); //Fill with green color
        }
        counter++;
    }
    

    Calling update() repeatedly will toggle between green and blue color for every pixel. However, upon calling update(QRect(0, 0, 50, 50)) only the top left quarter of the widget's area will change its color, the other pixels will remain untouched, even if paintEvent(..) contains the instruction to always paint over the whole widget's area.

    I do not know whether my answer is fully correct under any circumstances, but I expect more noobs to be confused about the relationship between update() and paintEvent() and so I'll offer this as a first aid.

    Greets.