source: trunk/doc/src/examples/2dpainting.qdoc

Last change on this file 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: 8.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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: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 qt-info@nokia.com.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27
28/*!
29 \example opengl/2dpainting
30 \title 2D Painting Example
31
32 The 2D Painting example shows how QPainter and QGLWidget can be used
33 together to display accelerated 2D graphics on supported hardware.
34
35 \image 2dpainting-example.png
36
37 The QPainter class is used to draw 2D graphics primitives onto
38 paint devices provided by QPaintDevice subclasses, such as QWidget
39 and QImage.
40
41 Since QGLWidget is a subclass of QWidget, it is possible
42 to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use
43 QPainter to draw on the device, just as you would with a QWidget.
44 The only difference is that the painting operations will be accelerated
45 in hardware if it is supported by your system's OpenGL drivers.
46
47 In this example, we perform the same painting operations on a
48 QWidget and a QGLWidget. The QWidget is shown with anti-aliasing
49 enabled, and the QGLWidget will also use anti-aliasing if the
50 required extensions are supported by your system's OpenGL driver.
51
52 \section1 Overview
53
54 To be able to compare the results of painting onto a QGLWidget subclass
55 with native drawing in a QWidget subclass, we want to show both kinds
56 of widget side by side. To do this, we derive subclasses of QWidget and
57 QGLWidget, using a separate \c Helper class to perform the same painting
58 operations for each, and lay them out in a top-level widget, itself
59 provided a the \c Window class.
60
61 \section1 Helper Class Definition
62
63 In this example, the painting operations are performed by a helper class.
64 We do this because we want the same painting operations to be performed
65 for both our QWidget subclass and the QGLWidget subclass.
66
67 The \c Helper class is minimal:
68
69 \snippet examples/opengl/2dpainting/helper.h 0
70
71 Apart from the constructor, it only provides a \c paint() function to paint
72 using a painter supplied by one of our widget subclasses.
73
74 \section1 Helper Class Implementation
75
76 The constructor of the class sets up the resources it needs to paint
77 content onto a widget:
78
79 \snippet examples/opengl/2dpainting/helper.cpp 0
80
81 The actual painting is performed in the \c paint() function. This takes
82 a QPainter that has already been set up to paint onto a paint device
83 (either a QWidget or a QGLWidget), a QPaintEvent that provides information
84 about the region to be painted, and a measure of the elapsed time (in
85 milliseconds) since the paint device was last updated.
86
87 \snippet examples/opengl/2dpainting/helper.cpp 1
88
89 We begin painting by filling in the region contained in the paint event
90 before translating the origin of the coordinate system so that the rest
91 of the painting operations will be displaced towards the center of the
92 paint device.
93
94 We draw a spiral pattern of circles, using the elapsed time specified to
95 animate them so that they appear to move outward and around the coordinate
96 system's origin:
97
98 \snippet examples/opengl/2dpainting/helper.cpp 2
99
100 Since the coordinate system is rotated many times during
101 this process, we \l{QPainter::save()}{save()} the QPainter's state
102 beforehand and \l{QPainter::restore()}{restore()} it afterwards.
103
104 \snippet examples/opengl/2dpainting/helper.cpp 3
105
106 We draw some text at the origin to complete the effect.
107
108 \section1 Widget Class Definition
109
110 The \c Widget class provides a basic custom widget that we use to
111 display the simple animation painted by the \c Helper class.
112
113 \snippet examples/opengl/2dpainting/widget.h 0
114
115 Apart from the constructor, it only contains a
116 \l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw
117 customized content, and a slot that is used to animate its contents.
118 One member variable keeps track of the \c Helper that the widget uses
119 to paint its contents, and the other records the elapsed time since
120 it was last updated.
121
122 \section1 Widget Class Implementation
123
124 The constructor only initializes the member variables, storing the
125 \c Helper object supplied and calling the base class's constructor,
126 and enforces a fixed size for the widget:
127
128 \snippet examples/opengl/2dpainting/widget.cpp 0
129
130 The \c animate() slot is called whenever a timer, which we define later, times
131 out:
132
133 \snippet examples/opengl/2dpainting/widget.cpp 1
134
135 Here, we determine the interval that has elapsed since the timer last
136 timed out, and we add it to any existing value before repainting the
137 widget. Since the animation used in the \c Helper class loops every second,
138 we can use the modulo operator to ensure that the \c elapsed variable is
139 always less than 1000.
140
141 Since the \c Helper class does all of the actual painting, we only have
142 to implement a paint event that sets up a QPainter for the widget and calls
143 the helper's \c paint() function:
144
145 \snippet examples/opengl/2dpainting/widget.cpp 2
146
147 \section1 GLWidget Class Definition
148
149 The \c GLWidget class definition is basically the same as the \c Widget
150 class except that it is derived from QGLWidget.
151
152 \snippet examples/opengl/2dpainting/glwidget.h 0
153
154 Again, the member variables record the \c Helper used to paint the
155 widget and the elapsed time since the previous update.
156
157 \section1 GLWidget Class Implementation
158
159 The constructor differs a little from the \c Widget class's constructor:
160
161 \snippet examples/opengl/2dpainting/glwidget.cpp 0
162
163 As well as initializing the \c elapsed member variable and storing the
164 \c Helper object used to paint the widget, the base class's constructor
165 is called with the format that specifies the \l QGL::SampleBuffers flag.
166 This enables anti-aliasing if it is supported by your system's OpenGL
167 driver.
168
169 The \c animate() slot is exactly the same as that provided by the \c Widget
170 class:
171
172 \snippet examples/opengl/2dpainting/glwidget.cpp 1
173
174 The \c paintEvent() is almost the same as that found in the \c Widget class:
175
176 \snippet examples/opengl/2dpainting/glwidget.cpp 2
177
178 Since anti-aliasing will be enabled if available, we only need to set up
179 a QPainter on the widget and call the helper's \c paint() function to display
180 the widget's contents.
181
182 \section1 Window Class Definition
183
184 The \c Window class has a basic, minimal definition:
185
186 \snippet examples/opengl/2dpainting/window.h 0
187
188 It contains a single \c Helper object that will be shared between all
189 widgets.
190
191 \section1 Window Class Implementation
192
193 The constructor does all the work, creating a widget of each type and
194 inserting them with labels into a layout:
195
196 \snippet examples/opengl/2dpainting/window.cpp 0
197
198 A timer with a 50 millisecond time out is constructed for animation purposes,
199 and connected to the \c animate() slots of the \c Widget and \c GLWidget objects.
200 Once started, the widgets should be updated at around 20 frames per second.
201
202 \section1 Running the Example
203
204 The example shows the same painting operations performed at the same time
205 in a \c Widget and a \c GLWidget. The quality and speed of rendering in the
206 \c GLWidget depends on the level of support for multisampling and hardware
207 acceleration that your system's OpenGL driver provides. If support for either
208 of these is lacking, the driver may fall back on a software renderer that
209 may trade quality for speed.
210*/
Note: See TracBrowser for help on using the repository browser.