Development/Architecture/KDE3/Low-level Graphics: Difference between revisions

    From KDE TechBase
    (first part of http://developer.kde.org/documentation/library/kdeqt/kde3arch/graphics/qpainter.html)
     
    (next part)
    Line 22: Line 22:
    widget for printing, with the same features supported. Of course, in
    widget for printing, with the same features supported. Of course, in
    practice, the code is used in a slightly different context. Drawing
    practice, the code is used in a slightly different context. Drawing
    on a widget is almost exlusively done in the paintEvent() method
    on a widget is almost exclusively done in the paintEvent() method
    of a widget class.
    of a widget class.


    Line 69: Line 69:
    Here are some pictures that show the effect of the elementary
    Here are some pictures that show the effect of the elementary
    transformation to our masquot:
    transformation to our masquot:
    {| align="center"
    ||[[Image:konqi-normal.png|frame|none|a) Normal]]
    ||[[Image:konqi-rotated.png|frame|none|b) Rotated by 30°]]
    |-
    ||[[Image:konqi-sheared.png|frame|none|c) Sheared by 0.4]]
    ||[[Image:konqi-mirrored.png|frame|none|d) Mirrored]]
    |}
    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.
    == Setting stroking attributes ==
    The rendering of lines, curves and outlines of polygons can be modified by
    setting a special pen with <tt>QPainter::setPen()</tt>. The argument of this
    function is a [http://doc.trolltech.com/3.3/qpen.html 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
    [http://doc.trolltech.com/qt.html#PenStyle-enum Qt::PenStyle].
    and can take one of the following values:
    <div align="center">[[Image:q3pen-styles.png|frame|none|Pen styles]]</div>
    The join style is a member of the enum
    [http://doc.trolltech.com/3.3/qt.html#PenJoinStyle-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:

    Revision as of 11:57, 6 January 2007

    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.

    Rendering with QPainter

    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.

    Transformations

    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

    File:Transformation-basic.png
    Formula for affine transformation

    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
    File:Transformation-translate.png
    Formula for translating transformation
    • 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
    File:Transformation-scale.png
    Formula for scaling transformation
    • 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
    File:Transformation-shear.png
    Formula for shearing transformation
    • 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
    File:Transformation-rotate.png
    Formula for rotating transformation

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

    a) Normal
    File:Konqi-rotated.png
    b) Rotated by 30°
    c) Sheared by 0.4
    d) Mirrored

    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.

    Setting stroking attributes

    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:

    Pen styles

    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: