Qt4 Как рисовать внутри виджета?

Qt4, QtCreator

Я пытаюсь рисовать внутри виджета:

void Widget::on_pushButton_clicked()
{
    QPainter painter;

    painter.begin(ui->label);

    QRectF rectangle(10.0, 20.0, 80.0, 60.0);
     int startAngle = 30 * 16;
     int spanAngle = 120 * 16;
     painter.drawArc(rectangle, startAngle, spanAngle);

    painter.end();
}

Но когда я нажимаю кнопку, ничего не происходит.

Как это сделать правильно?

Ответы

Ответ 1

Вам нужно переопределить paintEvent() и сделать свою картину там. Вам не нужны begin() и end(). Объявите художника с помощью

QPainter painter(this);

Конструктор будет обрабатывать begin(), а end() вызывается, когда объект painter выходит за пределы области видимости и уничтожается.

Для запуска рисунка вам также не понадобится событие click. paintEvent() будет вызываться всякий раз, когда виджет должен сам рисовать. Вы можете использовать кнопку click, чтобы переключить логическое значение, которое проверит paintEvent(), чтобы определить, должен ли он отображать прямоугольник и дугу. Просто убедитесь, что вы вызываете update() после переключения этой переменной.

void Widget::on_pushButton_clicked()
{
    drawShapes = !drawShapes;
    update();
}

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

    if(drawShapes)
    {
        QRectF rectangle(10.0, 20.0, 80.0, 60.0);
        int startAngle = 30 * 16;
        int spanAngle = 120 * 16;
        painter.drawArc(rectangle, startAngle, spanAngle);
    }
}

UPDATE:

Чтобы избежать переопределения paintEvent() виджета, вы можете использовать QLabel и назначить ему pixmap и нарисовать это. Примечание. Насколько я могу судить, вам нужно будет установить pixmap каждый раз, когда вы его измените.

void MainForm::slot_buttonClick()
{
    QPixmap pixmap(100,100);
    pixmap.fill(QColor("transparent"));

    QPainter painter(&pixmap);
    painter.setBrush(QBrush(Qt::black));
    painter.drawRect(10, 10, 100, 100);

    label.setPixmap(pixmap);
}

Ответ 2

Если вы перезаписываете метод paint, как описано Арнольдом Спенсом, вы должны вызвать родительский paintEvent или вы получите виджет, который отображает только ваш прямоугольник на белом фоне.