Qt4如何在小部件内绘制?

16

我想在Widget内部绘制:

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();
}

但是当我点击按钮时没有任何反应。

如何以正确的方式实现这个功能?

2个回答

26

你需要重写paintEvent()函数,并在其中绘制内容。你并不需要使用begin()end()函数。使用以下方式声明一个绘图器:

QPainter painter(this);
构造函数将处理begin(),当painter对象超出作用域并被销毁时,end()将被调用。
您也不需要单击事件来触发绘图。每当小部件需要绘制自身时,都会调用paintEvent()。您可以使用按钮单击来切换一个布尔值,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);
    }
}

更新:

为了避免必须重写一个小部件的paintEvent(),你可以使用一个QLabel并将一个像素图分配给它并绘制到那里。注意:据我所知,每次修改像素图时都需要设置它。

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);
}

有没有不覆盖的绘画方式?或者有没有任何组件可以在VCL(Delphi)中不需要任何事件进行绘制,例如TImage、TForm或包含TCanvas的其他组件?(在Delphi中,只需在需要时编写Form1.Canvas.Circle(...),而不仅仅是在onpaint事件内部) - Astronavigator
我从未尝试过使用小部件外部的代码在小部件上绘图,但是QWidget确实继承了PaintDevice,因此应该是可能的。 - Arnold Spence
1
放弃之前的处理,从QPainter的文档中可以看到:“警告:当绘制设备为小部件时,只能在paintEvent()函数内部或由paintEvent()调用的函数中使用QPainter;除非设置了Qt::WA_PaintOutsidePaintEvent小部件属性。在Mac OS X和Windows下,无论此属性的设置如何,都只能在paintEvent()函数中进行绘制。” - Arnold Spence
你可以使用QLabel和QPixmap,绘制pixmap并将其分配给标签。我在上面添加了一个带有代码的更新。 - Arnold Spence

1
如果您按照Arnold Spence的描述覆盖了paint方法,那么您应该调用父类的paintEvent,否则您最终会得到一个只在白色背景上显示矩形的小部件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接