source: trunk/doc/src/examples/concentriccircles.qdoc@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 10.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
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*/
Note: See TracBrowser for help on using the repository browser.