fc924ae47e
Widget examples were moved into a widgets subfolder, but qdoc references were not updated. Change-Id: Id2a4573e723745b9827c664c852807d6116f8f6d Reviewed-by: Casper van Donderen <casper.vandonderen@nokia.com>
372 lines
16 KiB
Plaintext
372 lines
16 KiB
Plaintext
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
** Contact: http://www.qt-project.org/
|
|
**
|
|
** This file is part of the documentation of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:FDL$
|
|
** GNU Free Documentation License
|
|
** Alternatively, this file may be used under the terms of the GNU Free
|
|
** Documentation License version 1.3 as published by the Free Software
|
|
** Foundation and appearing in the file included in the packaging of
|
|
** this file.
|
|
**
|
|
** Other Usage
|
|
** Alternatively, this file may be used in accordance with the terms
|
|
** and conditions contained in a signed written agreement between you
|
|
** and Nokia.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
/*!
|
|
\example widgets/painting/transformations
|
|
\title Transformations Example
|
|
|
|
The Transformations example shows how transformations influence
|
|
the way that QPainter renders graphics primitives. In particular
|
|
it shows how the order of transformations affect the result.
|
|
|
|
\image transformations-example.png
|
|
|
|
The application allows the user to manipulate the rendering of a
|
|
shape by changing the translation, rotation and scale of
|
|
QPainter's coordinate system.
|
|
|
|
The example consists of two classes and a global enum:
|
|
|
|
\list
|
|
\li The \c RenderArea class controls the rendering of a given shape.
|
|
\li The \c Window class is the application's main window.
|
|
\li The \c Operation enum describes the various transformation
|
|
operations available in the application.
|
|
\endlist
|
|
|
|
First we will take a quick look at the \c Operation enum, then we
|
|
will review the \c RenderArea class to see how a shape is
|
|
rendered. Finally, we will take a look at the Transformations
|
|
application's features implemented in the \c Window class.
|
|
|
|
\section1 Transformation Operations
|
|
|
|
Normally, the QPainter operates on the associated device's own
|
|
coordinate system, but it also has good support for coordinate
|
|
transformations.
|
|
|
|
The default coordinate system of a paint device has its origin at
|
|
the top-left corner. The x values increase to the right and the y
|
|
values increase downwards. You can scale the coordinate system by
|
|
a given offset using the QPainter::scale() function, you can
|
|
rotate it clockwise using the QPainter::rotate() function and you
|
|
can translate it (i.e. adding a given offset to the points) using
|
|
the QPainter::translate() function. You can also twist the
|
|
coordinate system around the origin (called shearing) using the
|
|
QPainter::shear() function.
|
|
|
|
All the tranformation operations operate on QPainter's
|
|
tranformation matrix that you can retrieve using the
|
|
QPainter::worldTransform() function. A matrix transforms a point in the
|
|
plane to another point. For more information about the
|
|
transformation matrix, see the \l {Coordinate System} and
|
|
QTransform documentation.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.h 0
|
|
|
|
The global \c Operation enum is declared in the \c renderarea.h
|
|
file and describes the various transformation operations available
|
|
in the Transformations application.
|
|
|
|
\section1 RenderArea Class Definition
|
|
|
|
The \c RenderArea class inherits QWidget, and controls the
|
|
rendering of a given shape.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.h 1
|
|
|
|
We declare two public functions, \c setOperations() and
|
|
\c setShape(), to be able to specify the \c RenderArea widget's shape
|
|
and to transform the coordinate system the shape is rendered
|
|
within.
|
|
|
|
We reimplement the QWidget's \l
|
|
{QWidget::minimumSizeHint()}{minimumSizeHint()} and \l
|
|
{QWidget::sizeHint()}{sizeHint()} functions to give the \c
|
|
RenderArea widget a reasonable size within our application, and we
|
|
reimplement the QWidget::paintEvent() event handler to draw the
|
|
render area's shape applying the user's transformation choices.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.h 2
|
|
|
|
We also declare several convenience functions to draw the shape,
|
|
the coordinate system's outline and the coordinates, and to
|
|
transform the painter according to the chosen transformations.
|
|
|
|
In addition, the \c RenderArea widget keeps a list of the
|
|
currently applied transformation operations, a reference to its
|
|
shape, and a couple of convenience variables that we will use when
|
|
rendering the coordinates.
|
|
|
|
\section1 RenderArea Class Implementation
|
|
|
|
The \c RenderArea widget controls the rendering of a given shape,
|
|
including the transformations of the coordinate system, by
|
|
reimplementing the QWidget::paintEvent() event handler. But first
|
|
we will take a quick look at the constructor and at the functions
|
|
that provides access to the \c RenderArea widget:
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 0
|
|
|
|
In the constructor we pass the parent parameter on to the base
|
|
class, and customize the font that we will use to render the
|
|
coordinates. The QWidget::font() function returns the font
|
|
currently set for the widget. As long as no special font has been
|
|
set, or after QWidget::setFont() is called, this is either a
|
|
special font for the widget class, the parent's font or (if this
|
|
widget is a top level widget) the default application font.
|
|
|
|
After ensuring that the font's size is 12 points, we extract the
|
|
rectangles enclosing the coordinate letters, 'x' and 'y', using the
|
|
QFontMetrics class.
|
|
|
|
QFontMetrics provides functions to access the individual metrics
|
|
of the font, its characters, and for strings rendered in the
|
|
font. The QFontMetrics::boundingRect() function returns the
|
|
bounding rectangle of the given character relative to the
|
|
left-most point on the base line.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 1
|
|
\codeline
|
|
\snippet widgets/painting/transformations/renderarea.cpp 2
|
|
|
|
In the \c setShape() and \c setOperations() functions we update
|
|
the \c RenderArea widget by storing the new value or values
|
|
followed by a call to the QWidget::update() slot which schedules a
|
|
paint event for processing when Qt returns to the main event loop.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 3
|
|
\codeline
|
|
\snippet widgets/painting/transformations/renderarea.cpp 4
|
|
|
|
We reimplement the QWidget's \l
|
|
{QWidget::minimumSizeHint()}{minimumSizeHint()} and \l
|
|
{QWidget::sizeHint()}{sizeHint()} functions to give the \c
|
|
RenderArea widget a reasonable size within our application. The
|
|
default implementations of these functions returns an invalid size
|
|
if there is no layout for this widget, and returns the layout's
|
|
minimum size or preferred size, respectively, otherwise.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 5
|
|
|
|
The \c paintEvent() event handler receives the \c RenderArea
|
|
widget's paint events. A paint event is a request to repaint all
|
|
or part of the widget. It can happen as a result of
|
|
QWidget::repaint() or QWidget::update(), or because the widget was
|
|
obscured and has now been uncovered, or for many other reasons.
|
|
|
|
First we create a QPainter for the \c RenderArea widget. The \l
|
|
{QPainter::RenderHint}{QPainter::Antialiasing} render hint
|
|
indicates that the engine should antialias edges of primitives if
|
|
possible. Then we erase the area that needs to be repainted using
|
|
the QPainter::fillRect() function.
|
|
|
|
We also translate the coordinate system with an constant offset to
|
|
ensure that the original shape is renderend with a suitable
|
|
margin.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 6
|
|
|
|
Before we start to render the shape, we call the QPainter::save()
|
|
function.
|
|
|
|
QPainter::save() saves the current painter state (i.e. pushes the
|
|
state onto a stack) including the current coordinate system. The
|
|
rationale for saving the painter state is that the following call
|
|
to the \c transformPainter() function will transform the
|
|
coordinate system depending on the currently chosen transformation
|
|
operations, and we need a way to get back to the original state to
|
|
draw the outline.
|
|
|
|
After transforming the coordinate system, we draw the \c
|
|
RenderArea's shape, and then we restore the painter state using
|
|
the QPainter::restore() function (i.e. popping the saved state off
|
|
the stack).
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 7
|
|
|
|
Then we draw the square outline.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 8
|
|
|
|
Since we want the coordinates to correspond with the coordinate
|
|
system the shape is rendered within, we must make another call to
|
|
the \c transformPainter() function.
|
|
|
|
The order of the painting operations is essential with respect to
|
|
the shared pixels. The reason why we don't render the coordinates
|
|
when the coordinate system already is transformed to render the
|
|
shape, but instead defer their rendering to the end, is that we
|
|
want the coordinates to appear on top of the shape and its
|
|
outline.
|
|
|
|
There is no need to save the QPainter state this time since
|
|
drawing the coordinates is the last painting operation.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 9
|
|
\codeline
|
|
\snippet widgets/painting/transformations/renderarea.cpp 10
|
|
\codeline
|
|
\snippet widgets/painting/transformations/renderarea.cpp 11
|
|
|
|
The \c drawCoordinates(), \c drawOutline() and \c drawShape() are
|
|
convenience functions called from the \c paintEvent() event
|
|
handler. For more information about QPainter's basic drawing
|
|
operations and how to display basic graphics primitives, see the
|
|
\l {painting/basicdrawing}{Basic Drawing} example.
|
|
|
|
\snippet widgets/painting/transformations/renderarea.cpp 12
|
|
|
|
The \c transformPainter() convenience function is also called from
|
|
the \c paintEvent() event handler, and transforms the given
|
|
QPainter's coordinate system according to the user's
|
|
transformation choices.
|
|
|
|
\section1 Window Class Definition
|
|
|
|
The \c Window class is the Transformations application's main
|
|
window.
|
|
|
|
The application displays four \c RenderArea widgets. The left-most
|
|
widget renders the shape in QPainter's default coordinate system,
|
|
the others render the shape with the chosen transformation in
|
|
addition to all the transformations applied to the \c RenderArea
|
|
widgets to their left.
|
|
|
|
\snippet widgets/painting/transformations/window.h 0
|
|
|
|
We declare two public slots to make the application able to
|
|
respond to user interaction, updating the displayed \c RenderArea
|
|
widgets according to the user's transformation choices.
|
|
|
|
The \c operationChanged() slot updates each of the \c RenderArea
|
|
widgets applying the currently chosen transformation operations, and
|
|
is called whenever the user changes the selected operations. The
|
|
\c shapeSelected() slot updates the \c RenderArea widgets' shapes
|
|
whenever the user changes the preferred shape.
|
|
|
|
\snippet widgets/painting/transformations/window.h 1
|
|
|
|
We also declare a private convenience function, \c setupShapes(),
|
|
that is used when constructing the \c Window widget, and we
|
|
declare pointers to the various components of the widget. We
|
|
choose to keep the available shapes in a QList of \l
|
|
{QPainterPath}s. In addition we declare a private enum counting
|
|
the number of displayed \c RenderArea widgets except the widget
|
|
that renders the shape in QPainter's default coordinate system.
|
|
|
|
\section1 Window Class Implementation
|
|
|
|
In the constructor we create and initialize the application's
|
|
components:
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 0
|
|
|
|
First we create the \c RenderArea widget that will render the
|
|
shape in the default coordinate system. We also create the
|
|
associated QComboBox that allows the user to choose among four
|
|
different shapes: A clock, a house, a text and a truck. The shapes
|
|
themselves are created at the end of the constructor, using the
|
|
\c setupShapes() convenience function.
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 1
|
|
|
|
Then we create the \c RenderArea widgets that will render their
|
|
shapes with coordinate tranformations. By default the applied
|
|
operation is \uicontrol {No Transformation}, i.e. the shapes are
|
|
rendered within the default coordinate system. We create and
|
|
initialize the associated \l {QComboBox}es with items
|
|
corresponding to the various transformation operations decribed by
|
|
the global \c Operation enum.
|
|
|
|
We also connect the \l {QComboBox}es' \l
|
|
{QComboBox::activated()}{activated()} signal to the \c
|
|
operationChanged() slot to update the application whenever the
|
|
user changes the selected transformation operations.
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 2
|
|
|
|
Finally, we set the layout for the application window using the
|
|
QWidget::setLayout() function, construct the available shapes
|
|
using the private \c setupShapes() convenience function, and make
|
|
the application show the clock shape on startup using the public
|
|
\c shapeSelected() slot before we set the window title.
|
|
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 3
|
|
\snippet widgets/painting/transformations/window.cpp 4
|
|
\snippet widgets/painting/transformations/window.cpp 5
|
|
\snippet widgets/painting/transformations/window.cpp 6
|
|
\dots
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 7
|
|
|
|
The \c setupShapes() function is called from the constructor and
|
|
create the QPainterPath objects representing the shapes that are
|
|
used in the application. For construction details, see the \l
|
|
{painting/transformations/window.cpp}{window.cpp} example
|
|
file. The shapes are stored in a QList. The QList::append()
|
|
function inserts the given shape at the end of the list.
|
|
|
|
We also connect the associated QComboBox's \l
|
|
{QComboBox::activated()}{activated()} signal to the \c
|
|
shapeSelected() slot to update the application when the user
|
|
changes the preferred shape.
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 8
|
|
|
|
The public \c operationChanged() slot is called whenever the user
|
|
changes the selected operations.
|
|
|
|
We retrieve the chosen transformation operation for each of the
|
|
transformed \c RenderArea widgets by querying the associated \l
|
|
{QComboBox}{QComboBoxes}. The transformed \c RenderArea widgets
|
|
are supposed to render the shape with the transformation specified
|
|
by its associated combobox \e {in addition to} all the
|
|
transformations applied to the \c RenderArea widgets to its
|
|
left. For that reason, for each widget we query, we append the
|
|
associated operation to a QList of transformations which we apply
|
|
to the widget before proceeding to the next.
|
|
|
|
\snippet widgets/painting/transformations/window.cpp 9
|
|
|
|
The \c shapeSelected() slot is called whenever the user changes
|
|
the preferred shape, updating the \c RenderArea widgets using
|
|
their public \c setShape() function.
|
|
|
|
\section1 Summary
|
|
|
|
The Transformations example shows how transformations influence
|
|
the way that QPainter renders graphics primitives. Normally, the
|
|
QPainter operates on the device's own coordinate system, but it
|
|
also has good support for coordinate transformations. With the
|
|
Transformations application you can scale, rotate and translate
|
|
QPainter's coordinate system. The order in which these
|
|
tranformations are applied is essential for the result.
|
|
|
|
All the tranformation operations operate on QPainter's
|
|
tranformation matrix. For more information about the
|
|
transformation matrix, see the \l {Coordinate System} and
|
|
QTransform documentation.
|
|
|
|
The Qt reference documentation provides several painting
|
|
examples. Among these is the \l {painting/affine}{Affine
|
|
Transformations} example that shows Qt's ability to perform
|
|
transformations on painting operations. The example also allows the
|
|
user to experiment with the various transformation operations.
|
|
*/
|