19

I have a QScrollArea fathering my awesome scrolling widget. I like to do updates on the contents on various occasions.

For this I did an override of paintEvent(QPaintEvent *). Then everytime I want it to be done I call update() on the widget.

Problem: paintEvent() is never called by this!

What I tried in troubleshooting so far:

  • Use repaint() instead of update(). Should call it instantanously. Unfortunately does not.
  • Test for isVisible() and updatesEnabled
  • Test wether my override is correct. Resizing the window calls my function. Only my manual update(), repaint() calls fail.
  • Implement a QTimer to trigger update() or repaint() every 500ms. The trigger gives text output, the function is not called.

Anybody got an idea what to check next? What could make repaint() not call paintEvent()?

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
ypnos
  • 50,202
  • 14
  • 95
  • 141
  • Not drawing on the QScrollArea, but instead its assigned QLabel solved the problem for me. I get the update()s for the QLabel. – ypnos Feb 19 '10 at 09:44
  • could you paste in your header / class definition? Do you have all of your Q_OBJECT macros in there? also give a quick snippet on how you are overriding your paintEvent()... – bgs Mar 02 '10 at 17:12

1 Answers1

32

The solution is to call this->viewport()->repaint() or this->viewport()->update() from your QAbstractScrollArea derived class instead of just repaint() or update().

More info is given in Qt documentation:

QWidget * QAbstractScrollArea::viewport () const

Returns the viewport widget. Use the QScrollArea::widget() function to retrieve the contents of the viewport widget.

Since the contents that we have in our QAbstractScrollArea derived class will be displayed in the viewport widget, makes sense to call viewport widget's update or repaint to draw our data again (have our paintEvent called).

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Abhiram
  • 336
  • 4
  • 3
  • Basically this is the correct answer. My fault was that I created my custom widget from QScrollArea and thought I could do my individual drawing there. Instead, I would have to override the viewport's drawing function, probably not possible. – ypnos Jul 24 '10 at 10:52
  • It is possible to override viewport's drawing function. Only thing you need to take care of inside viewport's reimplemented paintEvent() is- Instead of passing "this" pointer as one would normally do while creating a QPainter object, pass this->viewport(). QPainter(this->viewport()) instead of QPainter(this). Otherwise "QPainter is not active" error is thrown. – Abhiram Jul 24 '10 at 22:12
  • This applies to any 'fancy' widget that uses a QAbstractScrollArea, like the QTableWidget. Thanks a ton for pointing this out! – eresonance Jun 07 '15 at 04:49
  • Spent three hours on this same issue. Thanks for posting. – darda Jun 20 '15 at 23:41
  • I don't know how often I tapped into this trap although I already should know better. It seems that roughly once per year I write a custom widget derived from `QAbstractScrollArea`. This is rare enough to forget about this specific fact so that it hits me again every time. :-( I hope this answer will never age and come to the rescue and as a reminder not to mention that I would appreciate if this would've been fixed in Qt. Or is there a case where `QAbstractScrollArea::update()` would be called intentionally? – Scheff's Cat Apr 07 '22 at 08:41