doc/src/examples/concentriccircles.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \example painting/concentriccircles
       
    44     \title Concentric Circles Example
       
    45 
       
    46     The Concentric Circles example shows the improved rendering
       
    47     quality that can be obtained using floating point precision and
       
    48     anti-aliasing when drawing custom widgets. The example also shows
       
    49     how to do simple animations.
       
    50 
       
    51     The application's main window displays several widgets which are
       
    52     drawn using the various combinations of precision and
       
    53     anti-aliasing.
       
    54 
       
    55     \image concentriccircles-example.png
       
    56 
       
    57     Anti-aliasing is one of QPainter's render hints. The
       
    58     QPainter::RenderHints are used to specify flags to QPainter that
       
    59     may, or may not, be respected by any given
       
    60     engine. QPainter::Antialiasing indicates that the engine should
       
    61     anti-alias the edges of primitives if possible, i.e. put
       
    62     additional pixels around the original ones to smooth the edges.
       
    63 
       
    64     The difference between floating point precision and integer
       
    65     precision is a matter of accuracy, and is visible in the
       
    66     application's main window: Even though the logic that is
       
    67     calculating the circles' geometry is the same, floating points
       
    68     ensure that the white spaces between each circle are of the same
       
    69     size, while integers make two and two circles appear as if they
       
    70     belong together. The reason is that the integer based precision
       
    71     rely on rounding off non-integer calculations.
       
    72 
       
    73     The example consists of two classes:
       
    74 
       
    75     \list
       
    76     \o \c CircleWidget is a custom widget which renders several animated
       
    77        concentric circles.
       
    78     \o \c Window is the application's main window displaying four \c
       
    79        {CircleWidget}s drawn using different combinations of precision
       
    80        and aliasing.
       
    81     \endlist
       
    82 
       
    83     First we will review the CircleWidget class, then we will take a
       
    84     look at the Window class.
       
    85 
       
    86     \section1 CircleWidget Class Definition
       
    87 
       
    88     The CircleWidget class inherits QWidget, and is a custom widget
       
    89     which renders several animated concentric circles.
       
    90 
       
    91     \snippet examples/painting/concentriccircles/circlewidget.h 0
       
    92 
       
    93     We declare the \c floatBased and \c antialiased variables to hold
       
    94     whether an instance of the class should be rendered with integer
       
    95     or float based precision, and whether the rendering should be
       
    96     anti-aliased or not. We also declare functions setting each of
       
    97     these variables.
       
    98 
       
    99     In addition we reimplement the QWidget::paintEvent() function to
       
   100     apply the various combinations of precision and anti-aliasing when
       
   101     rendering, and to support the animation. We reimplement the
       
   102     QWidget::minimumSizeHint() and QWidget::sizeHint() functions to
       
   103     give the widget a reasonable size within our application.
       
   104 
       
   105     We declare the private \c nextAnimationFrame() slot, and the
       
   106     associated \c frameNo variable holding the number of "animation
       
   107     frames" for the widget, to facilitate the animation.
       
   108 
       
   109     \section1 CircleWidget Class Implementation
       
   110 
       
   111     In the constructor we make the widget's rendering integer based
       
   112     and aliased by default:
       
   113 
       
   114     \snippet examples/painting/concentriccircles/circlewidget.cpp 0
       
   115 
       
   116     We initialize the widget's \c frameNo variable, and set the
       
   117     widget's background color using the QWidget::setBackgroundColor()
       
   118     function which takes a \l {QPalette::ColorRole}{color role} as
       
   119     argument; the QPalette::Base color role is typically white.
       
   120 
       
   121     Then we set the widgets size policy using the
       
   122     QWidget::setSizePolicy() function. QSizePolicy::Expanding means
       
   123     that the widget's \l {QWidget::sizeHint()}{sizeHint()} is a
       
   124     sensible size, but that the widget can be shrunk and still be
       
   125     useful. The widget can also make use of extra space, so it should
       
   126     get as much space as possible.
       
   127 
       
   128     \snippet examples/painting/concentriccircles/circlewidget.cpp 1
       
   129     \codeline
       
   130     \snippet examples/painting/concentriccircles/circlewidget.cpp 2
       
   131 
       
   132     The public \c setFloatBased() and \c setAntialiased() functions
       
   133     update the widget's rendering preferences, i.e. whether the widget
       
   134     should be rendered with integer or float based precision, and
       
   135     whether the rendering should be anti-aliased or not.
       
   136 
       
   137     The functions also generate a paint event by calling the
       
   138     QWidget::update() function, forcing a repaint of the widget with
       
   139     the new rendering preferences.
       
   140 
       
   141     \snippet examples/painting/concentriccircles/circlewidget.cpp 3
       
   142     \codeline
       
   143     \snippet examples/painting/concentriccircles/circlewidget.cpp 4
       
   144 
       
   145     The default implementations of the QWidget::minimumSizeHint() and
       
   146     QWidget::sizeHint() functions return invalid sizes if there is no
       
   147     layout for the widget, otherwise they return the layout's minimum and
       
   148     preferred size, respectively.
       
   149 
       
   150     We reimplement the functions to give the widget minimum and
       
   151     preferred sizes which are reasonable within our application.
       
   152 
       
   153     \snippet examples/painting/concentriccircles/circlewidget.cpp 5
       
   154 
       
   155     The nextAnimationFrame() slot simply increments the \c frameNo
       
   156     variable's value, and calls the QWidget::update() function which
       
   157     schedules a paint event for processing when Qt returns to the main
       
   158     event loop.
       
   159 
       
   160     \snippet examples/painting/concentriccircles/circlewidget.cpp 6
       
   161 
       
   162     A paint event is a request to repaint all or part of the
       
   163     widget. The \c paintEvent() function is an event handler that can
       
   164     be reimplemented to receive the widget's paint events. We
       
   165     reimplement the event handler to apply the various combinations of
       
   166     precision and anti-aliasing when rendering the widget, and to
       
   167     support the animation.
       
   168 
       
   169     First, we create a QPainter for the widget, and set its
       
   170     antialiased flag to the widget's preferred aliasing. We also
       
   171     translate the painters coordinate system, preparing to draw the
       
   172     widget's cocentric circles. The translation ensures that the
       
   173     center of the circles will be equivalent to the widget's center.
       
   174 
       
   175     \snippet examples/painting/concentriccircles/circlewidget.cpp 7
       
   176 
       
   177     When painting a circle, we use the number of "animation frames" to
       
   178     determine the alpha channel of the circle's color. The alpha
       
   179     channel specifies the color's transparency effect, 0 represents a
       
   180     fully transparent color, while 255 represents a fully opaque
       
   181     color.
       
   182 
       
   183     \snippet examples/painting/concentriccircles/circlewidget.cpp 8
       
   184 
       
   185     If the calculated alpha channel is fully transparent, we don't
       
   186     draw anything since that would be equivalent to drawing a white
       
   187     circle on a white background. Instead we skip to the next circle
       
   188     still creating a white space. If the calculated alpha channel is
       
   189     fully opaque, we set the pen (the QColor passed to the QPen
       
   190     constructor is converted into the required QBrush by default) and
       
   191     draw the circle. If the widget's preferred precision is float
       
   192     based, we specify the circle's bounding rectangle using QRectF and
       
   193     double values, otherwise we use QRect and integers.
       
   194 
       
   195     The animation is controlled by the public \c nextAnimationFrame()
       
   196     slot: Whenever the \c nextAnimationFrame() slot is called the
       
   197     number of frames is incremented and a paint event is
       
   198     scheduled. Then, when the widget is repainted, the alpha-blending
       
   199     of the circles' colors change and the circles appear as animated.
       
   200 
       
   201     \section1 Window Class Definition
       
   202 
       
   203     The Window class inherits QWidget, and is the application's main
       
   204     window rendering four \c {CircleWidget}s using different
       
   205     combinations of precision and aliasing.
       
   206 
       
   207     \snippet examples/painting/concentriccircles/window.h 0
       
   208 
       
   209     We declare the various components of the main window, i.e the text
       
   210     labels and a double array that will hold reference to the four \c
       
   211     {CircleWidget}s. In addition we declare the private \c
       
   212     createLabel() function to simplify the constructor.
       
   213 
       
   214     \section1 Window Class Implementation
       
   215 
       
   216     \snippet examples/painting/concentriccircles/window.cpp 0
       
   217 
       
   218     In the constructor, we first create the various labels and put
       
   219     them in a QGridLayout.
       
   220 
       
   221     \snippet examples/painting/concentriccircles/window.cpp 1
       
   222 
       
   223     Then we create a QTimer. The QTimer class is a high-level
       
   224     programming interface for timers, and provides repetitive and
       
   225     single-shot timers.
       
   226 
       
   227     We create a timer to facilitate the animation of our concentric
       
   228     circles; when we create the four CircleWidget instances (and add
       
   229     them to the layout), we connect the QTimer::timeout() signal to
       
   230     each of the widgets' \c nextAnimationFrame() slots.
       
   231 
       
   232     \snippet examples/painting/concentriccircles/window.cpp 2
       
   233 
       
   234     Before we set the layout and window title for our main window, we
       
   235     make the timer start with a timeout interval of 100 milliseconds,
       
   236     using the QTimer::start() function. That means that the
       
   237     QTimer::timeout() signal will be emitted, forcing a repaint of the
       
   238     four \c {CircleWidget}s, every 100 millisecond which is the reason
       
   239     the circles appear as animated.
       
   240 
       
   241     \snippet examples/painting/concentriccircles/window.cpp 3
       
   242 
       
   243     The private \c createLabel() function is implemented to simlify
       
   244     the constructor.
       
   245 */