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

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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