Hello,
Here is the problem. A Widget takes time to render (this is the short explanation) and upon a paintEvent we want to render it in two stages:
1/ If not already done, render the Widget into a cache (Pixmap)
2/ Do the actual painting of the Widget using the cache.

I tried the naive solution below:
Qt Code:
  1. template <class WIDGET>
  2. class CachedWidget : public WIDGET
  3. {
  4. public:
  5. CachedWidget(QWidget *parent = 0) : WIDGET(parent), m_paintState(Idle) { }
  6.  
  7. virtual void paintEvent ( QPaintEvent * event ) {
  8. switch(m_paintState) {
  9. case Idle: // paint event occurred when widget was 'idle'
  10. m_paintState = Painting;
  11. if(m_cache.size() != QWidget::size()) {
  12. m_cache = QPixmap(QWidget::size());
  13. }
  14.  
  15. // this will somehow trigger a secondary paint event
  16. // this is out of our control
  17. QWidget::render(&m_cache);
  18.  
  19. { QPainter painter(this);
  20. painter.drawPixmap(event->rect(), m_cache, event->rect()); }
  21. m_paintState = Idle;
  22. break;
  23.  
  24. case Painting: // paint event occurred when widget was already painting
  25. WIDGET::paintEvent(event);
  26. break;
  27. }
  28. }
  29.  
  30. private:
  31. enum PaintState { Idle, Painting };
  32. PaintState m_paintState;
  33. QPixmap m_cache;
  34. };
  35.  
  36. int main(int argc, char *argv[])
  37. {
  38. QApplication a(argc, argv);
  39. CachedWidget<QWidget> w;
  40. w.show();
  41. return a.exec();
  42. }
To copy to clipboard, switch view to plain text mode 

This 'solution' does not work because to render the Widget into a cache we have to resort to the QWidget::render() function, and this function happens to somehow trigger another paintEvent, and Qt forbids reentrancy in the paintEvent() method.

The question is the following. When inside the paintEvent() function, is there a way to perform the painting into a QPaintDevice that is different than the Widget that received the QPaintEvent?
Or is it possible to otherwise implement a caching system similar to the the intention above?

Another question: since the render() method manages to render a QWidget in a different QPaintDevice, why does it have to send a QPaintEvent to the QWidget?

Thanks!