< Development | Architecture | KDE3

Qt's low level imaging model is based on the capabilities provided by X11 and other windowing systems for which Qt ports exist. But it also extends these by implementing additional features such as arbitrary affine transformations for text and pixmaps.

The central graphics class for 2D painting with Qt is QPainter. It can draw on a QPaintDevice. There are three possible paint devices implemented: One is QWidget which represents a widget on the screen. The second is QPrinter which represents a printer and produces Postscript output. The third it the class QPicture which records paint commands and can save them on disk and play them back later. A possible storage format for paint commands is the W3C standard SVG.

So, it is possible to reuse the rendering code you use for displaying a widget for printing, with the same features supported. Of course, in practice, the code is used in a slightly different context. Drawing on a widget is almost exclusively done in the paintEvent() method of a widget class.

```
void FooWidget::paintEvent()
{
```

```
``` QPainter p(this);
// Setup painter
// Use painter

```
}
```

When drawing on a printer, you have to make sure to use QPrinter::newPage() to finish with a page and begin a new one - something that naturally is not relevant for painting widgets. Also, when printing, you may want to use the device metrics in order to compute coordinates.

By default, when using the QPainter, it draws in the natural coordinate system of the device used. This means, if you draw a line along the horizontal axis with a length of 10 units, it will be painted as a horizontal line on the screen with a length of 10 pixels. However, QPainter can apply arbitrary affine transformations before actually rendering shapes and curves. An affine transformation maps the x and y coordinates linearly into x' and y' according to

The 3x3 matrix in this equation can be set with `QPainter::setWorldMatrix()`
and is of type QWMatrix.
Normally, this is the identity matrix, i.e. `m11` and `m22` are
one, and the other parameters are zero. There are basically three different
groups of transformations:

- Translations: These move all points of an object by a fixed amount in some direction. A translation matrix can be obtained by calling method
`m.translate(dx, dy)`for a QWMatrix. This corresponds to the matrix

- Scaling: These stretch or shrink the coordinates of an object, making it bigger or smaller without distorting it. A scaling transformation can be applied to a QWMatrix by calling
`m.scale(sx, sy)`. By setting one of the parameters to a negative value, one can achieve a mirroring of the coordinate system. The corresponding matrix looks like this

- Shearing: A distortion of the coordinate system with two parameters. A shearing transformation can be applied by calling
`m.shear(sh, sv)`, corresponding to the matrix

- Rotating: This rotates an object. A rotation transformation can be applied by calling
`m.rotate(alpha)`. Note that the angle has to be given in degrees, not as mathematical angle! Notate that a rotation is equivalent with a combination of scaling and shearing. The corresponding matrix is

Here are some pictures that show the effect of the elementary transformation to our masquot:

Transformations can be combined by multiplying elementary matrices. Note that matrix operations are not commutative in general, and therefore the combined effect of of a concatenation depends on the order in which the matrices are multiplied.

The rendering of lines, curves and outlines of polygons can be modified by
setting a special pen with `QPainter::setPen()`. The argument of this
function is a QPen object. The properties
stored in it are a style, a color, a join style and a cap style.

The pen style is member of the enum Qt::PenStyle. and can take one of the following values:

The join style is a member of the enum Qt::PenJoinStyle. It specifies how the junction between multiple lines which are attached to each other is drawn. It takes one of the following values:

Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.