Question

I am currently trying to encapsulate my QPainter objects into reusable classes, possibly deriving each other. This enables them to transform the painter around any way they like, have their own children to draw etc:

I have DrawArc derived from QPainterPath

DrawArc::DrawArc() : QPainterPath()
{}

void DrawArc::paint(QPainter* painter)
{
    painter->save();
    //...
    arcTo(/*...*/);
    lineTo(/*...*/);
    painter->translate(QPoint(100,100));
    painter->drawPath(*dynamic_cast<QPainterPath*>(this));
    painter->restore();
}

and DrawBeam derived from DrawArc

DrawBeam::DrawBeam() : DrawArc()
{}

void DrawBeam::paint(QPainter* painter)
{
    painter->save();
    //...
    painter->setPen(QPen(color, 4));
    painter->setBrush(brush);
    DrawArc::paint(painter);
    painter->restore();
}

In the actual Widget I am doing the following

BeamWidget::BeamWidget(QWidget* parent) : QWidget(parent)
{
    DrawBeam* mybeam = new DrawBeam();
}

void BeamWidget::paintEvent(QPaintEvent * /* event */)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    mybeam->paint(&painter);
}

However I am seeing dramatic performance losses in painter->drawPath(*dynamic_cast<QPainterPath*>(this)); after a few seconds (or few hundred redraws). Everything else in the remaining procedure seems to run fine but when I enable that line the performance degrades quickly.

Also all elements deriving from DrawArc painting seem to sometimes lose their QBrush styles and remain visible even though setAutoFillBackground(true); is set...

Was it helpful?

Solution

I found out this has to do with me only creating the object once, then adding an arcTo and a few other lines to it during each run of paint(). Since I can't flush the QPainterPath the Path simply becomes longer and longer and longer and longer.

This explains why old lines are not being flushed and why the brush is alternating (each time I re-draw the same thing I am forming a new intersection with the path itself, wich by design is not being filled).

I fixed it like this:

void DrawArc::paint(QPainter* painter)
{
    painter->save();
    //...

    QPainterPath path = QPainterPath(*this);
    path.arcTo(/*...*/);
    path.lineTo(/*...*/);

    painter->translate(QPoint(100,100));
    painter->drawPath(path);
    painter->restore();
}

So in each drawing operation I create a copy of the current path, add all lines I need to it and paint that one. After exiting paint, that drawn path is being discarded.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top