0

I have a QFrame that is used to paint some rectangles to represent some periods of the day, for example, the period when the user was sleeping.

To do so I overwrite the paintEvent(QPaintEvent *) function and I'm using a QPainter to paint the rectangles.

It is working fine, the problem is that the paintEvent(QPaintEvent *) function is automatically called multiple times by Qt to repaint the QFrame and it is consuming too much CPU. Actually, I just need to repaint a few times (by manually calling the repaint function).

There is some way that I can avoid the QFrame to automatically repaint itself?

Thanks in advance

I'm using Qt 5.3

KelvinS
  • 2,870
  • 8
  • 34
  • 67

2 Answers2

2

Widgets are repainted whenever Qt needs to repaint them. You have no control over any of that, generally speaking. You can only add repaint requests when needed, not reduce them.

You should never need to call the repaint method. Instead, whenever the data used for painting changes, you should update() the widget. The update events are fused to improve performance. The calls to update() should be in the widget's setter methods, or should be connected to the dataChanged() and equivalent signals of the data model used to feed the widget.

Most likely you're doing something else wrong. You'd need to provide a self-contained example to demonstrate the problem.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • The widgets are only repainted when some data has changed? Then I will need to take a look closely to find out if some data has being changed. I will try to provide a self-contained example. Thanks. – KelvinS Apr 12 '17 at 20:37
  • 1
    The widgets should be painted only when Qt has requested a repaint by invoking `paintEvent`. You should **request** a repaint from Qt by calling `update()` only when the data used to paint has changed. Look at your `paintEvent` and identify what non-constnat data you use in painting. Then make sure that at all points where this data is changed, `update()` is invoked. Qt will take care of the rest. Never call `repaint()`. – Kuba hasn't forgotten Monica Apr 12 '17 at 20:39
  • Thanks @Kuba Ober, I will look into my `paintEvent` function. – KelvinS Apr 12 '17 at 20:41
0

I finally found the problem. I was setting the style sheet inside the paintEvent function and I think it was being repainted because of that.

I was doing something like this:

MyFrameBar::MyFrameBar(QWidget *parent) : QFrame(parent)
{
    color = QColor(50, 50, 50, 200);
}

void MyFrameBar::paintEvent(QPaintEvent *)
{
    QString style = "border: 1px solid rgba(%1, %2, %3, %4);";
    style = style.arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
    setStyleSheet(style);
    ...
}

I just changed the place where I was setting the style sheet and everything is working fine.

The new code looks like this:

MyFrameBar::MyFrameBar(QWidget *parent) : QFrame(parent)
{
    setColor(QColor(50, 50, 50, 200));
}

void MyFrameBar::paintEvent(QPaintEvent *)
{
    ...
}

void MyFrameBar::setColor(const QColor &color)
{
    this->color = color;

    QString style = "border: 1px solid rgba(%1, %2, %3, %4);";
    style = style.arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
    setStyleSheet(style);
}
KelvinS
  • 2,870
  • 8
  • 34
  • 67