Qt: Почему мой paintEvent() стирает все перед выполнением своей работы?

Я пытаюсь заставить мой виджет рисовать прямоугольник с каждым полученным paintEvent. Предполагается, что прямоугольники увеличиваются в размере на 1 пиксель за раз, заполняя квадрат. Однако я получаю только самый последний (и самый большой) прямоугольник.

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

Я не понимаю, почему это так. Я ожидал, что художник просто нарисует поверх того, что уже есть. Вместо этого он, кажется, удаляет ранее нарисованный прямоугольник, оставляя меня с одним прямоугольником в любое время. Есть идеи?

setAutoFillBackground(true/false) не меняет ничего, кроме цвета фона.

Чтобы вызвать краску update() внутри mousePressEvent(), Так что мои прямоугольники растут с каждым кликом.

Большое спасибо.

3 ответа

Решение

Итак, чтобы ответить на мой собственный вопрос, я узнал, что:

(1) update(QRect area) стирает область, указанную его аргументом, прежде чем делать что-либо еще. Вызов update без аргументов стирает всю область виджета.

(2) Область, которая была очищена, является единственной областью, на которой выполняется любая живопись, даже если ваша paintEvent() выглядит рисовать где-то еще. На нетронутую часть виджета это не влияет.

Например, рассмотрим это 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++;
}

призвание update() несколько раз будет переключаться между зеленым и синим цветом для каждого пикселя. Однако по вызову update(QRect(0, 0, 50, 50)) только верхняя левая четверть области виджета изменит свой цвет, остальные пиксели останутся нетронутыми, даже если paintEvent(..) содержит инструкцию всегда закрашивать всю область виджета.

Я не знаю, является ли мой ответ полностью правильным ни при каких обстоятельствах, но я ожидаю, что больше новичков будут смущены отношениями между update() а также paintEvent() и поэтому я предложу это в качестве первой помощи.

Поздравил.

Документы QWidget::paintEvent утверждают, что

Когда происходит событие рисования, область обновления обычно стирается, поэтому вы рисуете на фоне виджета.

Так что, вероятно, это так в вашем примере.

Вам не гарантируется сохранение состояния между вызовами paintEvent, Это длинное и короткое из этого. Единственная правильная семантика вашей реализации paintEvent are: нарисовать (по крайней мере) всю область, которая была передана вам, как в случае: дотроньтесь до каждого пикселя, если ваш виджет не был предварительно очищен перед рисованием.

Другие вопросы по тегам