2016-03-08 6 views
0

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

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) не меняет ничего, кроме цвета фона.

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

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

+0

Вы видите только самую большую площадь, потому что она полностью покрывает все меньшие квадраты, нарисованные ранее. Что вы ожидаете увидеть? – Flopp

+0

@Flopp Это интересно, спасибо.Прямоугольники не заполнены, поэтому я не ожидал, что они смогут что-то покрыть. Я посмотрю, смогу ли я это проверить. – Jersey

+0

Хм, ты прав; Ваш код должен рисовать незаполненный прямоугольник. – Flopp

ответ

1

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

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

(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(..) содержит инструкцию, чтобы всегда рисовать всю область виджета.

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

Greets.

0

QWidget::paintEvent docs утверждает, что

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

Итак, возможно, это так в вашем примере.

+0

Ну, «нормально» относится к хорошим стандартам программирования или есть механизм Qt на работе? Наверное, я неправильно понял, как картина делается в qt. Я думал, что все, что связано с рисованием виджета, происходит внутри paintEvent(). – Jersey

0

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