9.10.  Paint Events, Drawing Images

[ fromfile: paintevents.xml id: paintevents ]

As you may have observed, a QPaintEvent can be sent to a QWidget due to a number of reasons:

  1. Widget is hidden and then exposed.

  2. Widget is resized, or re-laid out.

  3. update() or repaint() is called.

Example 9.19. src/widgets/life/lifewidget.h

[ . . . . ]
class LifeWidget : public QWidget
{
    Q_OBJECT
public:
    explicit LifeWidget(QWidget* parent = 0);
    ~LifeWidget();
    QSize sizeHint() const;
    void paintEvent(QPaintEvent* evt);      1
public slots:
    void setImage(const QImage& image);
private:
    QImage m_image;
    QSize m_size;
};
[ . . . . ]

1

Custom paint event


Steps to get a QPainter for a QWidget:

  1. Create a QPainter(this).

  2. Use QPainter API to draw on QWidget.

Example 9.20 shows a paintEvent() that takes an off-screen QImage and paints it directly onto the QWidget.

Example 9.20. src/widgets/life/lifewidget.cpp

[ . . . . ]

void LifeWidget::paintEvent(QPaintEvent* evt) {
    QPainter painter(this);         1
    if (!m_image.isNull())
        painter.drawImage(QPoint(0,0), m_image);
}

1

First line of most paintEvents.


This program paints successive generations of population maps based on the rules described in Conway's Game of Life. Figure 9.26 shows a snapshot of one generation. In Section 17.2.3 we revisit and parallelize this game.

Figure 9.26.  Conway's Game of Life

Conway's Game of Life

Example 9.21. src/widgets/life/lifewidget.cpp

[ . . . . ]

void LifeWidget::setImage(const QImage& image) {
    m_size = image.size();
    m_image = image.scaled(size());
    update();                       1
}

1

Asynchronous - return immediately.