source: trunk/doc/src/examples/padnavigator.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: 27.5 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 graphicsview/padnavigator
30 \title Pad Navigator Example
31
32 The Pad Navigator Example shows how you can use Graphics View together with
33 embedded widgets and Qt's \l{State Machine Framework} to create a simple
34 but useful, dynamic, animated user interface.
35
36 \image padnavigator-example.png
37
38 The interface consists of a flippable, rotating pad with icons that can be
39 selected using the arrow keys on your keyboard or keypad. Pressing enter
40 will flip the pad around and reveal its back side, which has a form
41 embedded into a QGraphicsProxyWidget. You can interact with the form, and
42 press the enter key to flip back to the front side of the pad at any time.
43
44 Graphics View provides the QGraphicsScene class for managing and
45 interacting with a large number of custom-made 2D graphical items derived
46 from the QGraphicsItem class, and a QGraphicsView widget for visualizing
47 the items, with support for zooming and rotation.
48
49 This example consists of a \c RoundRectItem class, a \c FlippablePad class,
50 a \c PadNavigator class, a \c SplashItem class, and a \c main() function.
51
52 \section1 RoundRectItem Class Definition
53
54 The \c RoundRectItem class is used by itself to diplay the icons on the
55 pad, and as a base class for \c FlippablePad, the class for the pad itself.
56 The role of the class is to paint a round rectangle of a specified size and
57 gradient color, and optionally to paint a pixmap icon on top. To support \c
58 FlippablePad it also allows filling its contents with a plain window
59 background color.
60
61 Let's start by reviewing the \c RoundRectItem class declaration.
62
63 \snippet examples/graphicsview/padnavigator/roundrectitem.h 0
64
65 \c RoundRectItem inherits QGraphicsObject, which makes it easy to control
66 its properties using QPropertyAnimation. Its constructor takes a rectangle
67 to determine its bounds, and a color.
68
69 Besides implementing the mandatory \l{QGraphicsItem::paint()}{paint()} and
70 \l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions,
71 it also provides the \c pixmap and \c fill properties.
72
73 The \c pixmap property sets an optional pixmap that is drawn on top of the
74 round rectangle. The \c fill property will, when true, fill the round
75 rectangle contents with a fixed QPalette::Window background color.
76 Otherwise the contents are filled using a gradient based on the color
77 passed to \c RoundRectItem's constructor.
78
79 \snippet examples/graphicsview/padnavigator/roundrectitem.h 1
80
81 The private data members are:
82
83 \list
84 \o \c pix: The optional pixmap that is drawn on top of the rectangle.
85 \o \c fillRect: Corresponds to the \c fill property.
86 \o \c color: The configurable gradient color fill of the rectangle.
87 \o \c bounds: The bounds of the rectangle.
88 \o \c gradient: A precalculated gradient used to fill the rectangle.
89 \endlist
90
91 We will now review the \c RoundRectItem implementation. Let's start by
92 looking at its constructor:
93
94 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 0
95
96 The constructor initializes its member variables and forwards the \c parent
97 argument to QGraphicsObject's constructor. It then constructs the linear
98 gradient that is used in \l{QGraphicsItem::paint()}{paint()} to draw the
99 round rectangle's gradient background. The linear gradient's starting point
100 is at the top-left corner of the bounds, and the end is at the bottom-left
101 corner. The start color is identical to the color passed as an argument,
102 and a slightly darker color is chosen for the final stop.
103
104 We store this gradient as a member variable to avoid having to recreate the
105 gradient every time the item is repainted.
106
107 Finally we set the cache mode
108 \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}. This mode
109 causes the item's rendering to be cached into an off-screen pixmap that
110 remains persistent as we move and transform the item. This mode is ideal
111 for this example, and works particularily well with OpenGL and OpenGL ES.
112
113 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 1
114
115 The \c pixmap property implementation simple returns the member pixmap, or
116 sets it and then calls \l{QGraphicsItem::update()}{update()}.
117
118 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 2
119
120 As the \l{QGraphicsItem::paint()}{paint()} implementation below draws a
121 simple drop shadow down and to the right of the item, we return a slightly
122 adjusted rectangle from \l{QGraphicsItem::boundingRect()}{boundingRect()}.
123
124 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 3
125
126 The \l{QGraphicsItem::paint()}{paint()} implementation starts by rendering
127 a semi transparent black round rectangle drop shadow, two units down and to
128 the right of the main item.
129
130 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 4
131
132 We then draw the "foreground" round rectangle itself. The fill depends on
133 the \c fill property; if true, we will with a plain QPalette::Window color.
134 We get the corrent brush from QApplication::palette(). We assign a single
135 unit wide pen for the stroke, assign the brush, and then draw the
136 rectangle.
137
138 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 5
139
140 If a pixmap has been assigned to the \e pixmap property, we draw this
141 pixmap in the center of the rectangle item. The pixmaps are scaled to match
142 the size of the icons; in arguably a better approach would have been to
143 store the icons with the right size in the first places.
144
145 \snippet examples/graphicsview/padnavigator/roundrectitem.cpp 6
146
147 Finally, for completeness we include the \c fill property implementation.
148 It returns the \c fill member variable's value, and when assigned to, it
149 calls \l{QGraphicsItem::update()}{update()}.
150
151 As mentioned already, \c RoundRectItem is the base class for \c
152 FlippablePad, which is the class representing the tilting pad itself. We
153 will proceed to reviewing \c FlippablePad.
154
155 \section1 FlippablePad Class Definition
156
157 \c FlippablePad is, in addition to its inherited \c RoundRectItem
158 responsibilities, responsible for creating and managing a grid of icons.
159
160 \snippet examples/graphicsview/padnavigator/flippablepad.h 0
161
162 Its declaration is very simple: It inherits \c RoundRectItem and does not
163 need any special polymorphic behavior. It's suitable to declare its own
164 constructor, and a getter-function that allows \c PadNavigator to access
165 the icons in the grid by (row, column).
166
167 The example has no "real" behavior or logic of any kind, and because of
168 that, the icons do not need to provide any \e behavior or special
169 interactions management. In a real application, however, it would be
170 natural for the \c FlippablePad and its icons to handle more of the
171 navigation logic. In this example, we have chosen to leave this to
172 the \c PadNavigator class, which we will get back to below.
173
174 We will now review the \c FlippablePad implementation. This implementation
175 starts with two helper functions: \c boundsFromSize() and \c
176 posForLocation():
177
178 \snippet examples/graphicsview/padnavigator/flippablepad.cpp 0
179
180 \c boundsForSize() takes a QSize argument, and returns the bounding
181 rectangle of the flippable pad item. The QSize determines how many rows and
182 columns the icon grid should have. Each icon is given 150x150 units of
183 space, and this determines the bounds.
184
185 \snippet examples/graphicsview/padnavigator/flippablepad.cpp 1
186
187 \c posForLocation() returns the position of an icon given its row and
188 column position. Like \c boundsForSize(), the function assumes each icon is
189 given 150x150 units of space, and that all icons are centered around the
190 flippable pad item's origin (0, 0).
191
192 \snippet examples/graphicsview/padnavigator/flippablepad.cpp 2
193
194 The \c FlippablePad constructor passes suitable bounds (using \c
195 boundsForSize()) and specific color to \c RoundRectItem's constructor.
196
197 \snippet examples/graphicsview/padnavigator/flippablepad.cpp 3
198
199 It then loads pixmaps from compiled-in resources to use for its icons.
200 QDirIterator is very useful in this context, as it allows us to fetch all
201 resource "*.png" files inside the \c :/images directory without explicitly
202 naming the files.
203
204 We also make sure not to load more pixmaps than we need.
205
206 \snippet examples/graphicsview/padnavigator/flippablepad.cpp 4
207
208 Now that we have the pixmaps, we can create icons, position then and assign
209 pixmaps. We start by finding a suitable size and color for the icons, and
210 initializing a convenient grid structure for storing the icons. This \c
211 iconGrid is also used later to find the icon for a specific (column, row)
212 location.
213
214 For each row and column in our grid, we proceed to constructing each icon
215 as an instance of \c RoundRectItem. The item is placed by using the \c
216 posForLocation() helper function. To make room for the slip-behind
217 selection item, we give each icon a \l{QGraphicsItem::zValue()}{Z-value} of
218 1. The pixmaps are distributed to the icons in round-robin fasion.
219
220 Again, this approach is only suitable for example purposes. In a real-life
221 application where each icon represents a specific action, it would be more
222 natural to assign the pixmaps directly, or that the icons themselves
223 provide suitable pixmaps.
224
225 \snippet examples/graphicsview/padnavigator/flippablepad.cpp 5
226
227 Finally, the \c iconAt() function returns a pointer to the icon at a
228 specific row and column. It makes a somewhat bold assumption that the input
229 is valid, which is fair because the \c PadNavigator class only calls this
230 function with correct input.
231
232 We will now review the \c SplashItem class.
233
234 \section1 SplashItem Class Definition
235
236 The \c SplashItem class represents the "splash window", a semitransparent
237 white overlay with text that appears immediately after the application has
238 started, and disappears after pressing any key. The animation is controlled
239 by \c PadNavigator; this class is very simple by itself.
240
241 \snippet examples/graphicsview/padnavigator/splashitem.h 0
242
243 The class declaration shows that \c SplashItem inherits QGraphicsObject to
244 allow it to be controlled by QPropertyAnimation. It reimplements the
245 mandatory \l{QGraphicsItem::paint()}{paint()} and
246 \l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions,
247 and keeps a \c text member variable which will contain the information text
248 displayed on this splash item.
249
250 Let's look at its implementation.
251
252 \snippet examples/graphicsview/padnavigator/splashitem.cpp 0
253
254 The constructor forwards to QGraphicsObject as expected, assigns a text
255 message to the \c text member variable, and enables
256 \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache}. This cache
257 mode is suitable because the splash item only moves and is never
258 transformed, and because it contains text, it's important that it has a
259 pixel perfect visual appearance (in constrast to
260 \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}, where the
261 visual appearance is not as good).
262
263 We use caching to avoid having to relayout and rerender the text for each
264 frame. An alterative approach would be to use the new QStaticText class.
265
266 \snippet examples/graphicsview/padnavigator/splashitem.cpp 1
267
268 \c SplashItem's bounding rectangle is fixed at (400x175).
269
270 \snippet examples/graphicsview/padnavigator/splashitem.cpp 2
271
272 The \l{QGraphicsItem::paint()}{paint()} implementation draws a clipped
273 round rectangle with a thick 2-unit border and a semi-transparent white
274 background. It proceeds to finding a suitable text area by adjusting the
275 splash item's bounding rectangle with 10 units in each side. The text is
276 rendered inside this rectangle, with top-left alignment, and with word
277 wrapping enabled.
278
279 The main class now remains. We will proceed to reviewing \c PadNavigator.
280
281 \section1 PadNavigator Class Definition
282
283 \c PadNavigator represents the main window of our Pad Navigator Example
284 application. It creates and controls a somewhat complex state machine, and
285 several animations. Its class declaration is very simple:
286
287 \snippet examples/graphicsview/padnavigator/padnavigator.h 0
288
289 It inherits QGraphicsView and reimplements only one function:
290 \l{QGraphicsView::resizeEvent()}{resizeEvent()}, to ensure the scene is
291 scaled to fit inside the view when resizing the main window.
292
293 The \c PadNavigator constructor takes a QSize argument that determines the
294 number or rows and columns in the grid.
295
296 It also keeps a private member instance, \c form, which is the generated
297 code for the pad's back side item's QGraphicsProxyWidget-embedded form.
298
299 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 0
300
301 \c PadNavigator's constructor is a bit long. In short, its job is to create
302 all items, including the \c FlippablePad, the \c SplashItem and the
303 QGraphicsProxyWidget \c backItem, and then to set up all animations, states
304 and transitions that control the behavior of the application.
305
306 It starts out simple, by forwarding to QGraphicsView's constructor.
307
308 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 1
309
310 The first item to be created is \c SplashItem. This is going to be a top-level
311 item in the scene, next to \c FlippablePad, and stacked on top of it, so we
312 assign it a \l{QGraphicsItem::zValue()}{Z-value} of 1.
313
314 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 2
315
316 Now we construct the \c FlippablePad item, passing its column-row count to
317 its constructor.
318
319 The pad is constrolled by three transformations, and we create one
320 QGraphicsRotation object for each of these.
321
322 \list
323 \o \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
324 animated from 0 to 180, and eventually back, when enter is pressed on the
325 keyboard, flipping the pad around.
326 \o \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
327 tilt the pad vertically corresponding to which item is currently selected.
328 This way, the selected item is always kept in front.
329 \o \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
330 tilt the pad horizontally corresponding to which item is selected. This
331 way, the selected item is always kept in front.
332 \endlist
333
334 The combination of all three rotations is assigned via
335 QGraphicsItem::setTransformations().
336
337 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 3
338
339 Now we construct the QGraphicsProxyWidget-embedded \c backItem. The proxy
340 widget is created as a child of the pad. We create a new QWidget and
341 populate it with the \c form member. To ensure the \c hostName line edit is
342 the first to receive input focus when this item is shown, we call
343 \l{QWidget::setFocus()}{setFocus()} immediately. This will not give the
344 widget focus right away; it will only prepare the item to automatically
345 receive focus once it is shown.
346
347 The QWidget based form is embedded into the proxy widget. The proxy is
348 hidden initially; we only want to show it when the pad is rotated at least
349 90 degrees, and we also rotate the proxy itself by 180 degrees. This way we
350 give the impression that the proxy widget is "behind" the flipped pad, when
351 in fact, it's actually \e{on top of it}.
352
353 We enable \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache} to
354 ensure the flip animation can run smoothly.
355
356 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 4
357
358 We now create the selection item. This is simply another instance of \c
359 RoundRectItem that is slightly larger than the icons on the pad. We create
360 it as an immediate child of the \c FlippablePad, so the selection item is a
361 sibling to all the icons. By giving it a
362 \l{QGraphicsItem::zValue()}{Z-value} of 0.5 we ensure it will slide beteen
363 the pad and its icons.
364
365 What follows now is a series of animation initializations.
366
367 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 5
368
369 We begin with the animations that apply to the splash item. The first
370 animation, \c smoothSplashMove, ensures that the "y" property of \c splash
371 will be animated with a 250-millisecond duration
372 \l{QEasingCurve::InQuad}{InQuad} easing function. \c smoothSplashOpacity
373 ensures the opacity of \c splash eases in and out in 250 milliseconds.
374
375 The values are assigned by \c PadNavigator's state machine, which is
376 created later.
377
378 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 6
379
380 These are the animations that control the selection item's movement and the
381 \c xRotation and \c yRotation QGraphicsRotation objects that tilt the pad.
382 All animations have a duration of 125 milliseconds, and they all use the
383 \l{QEasingCurve::InOutQuad}{InOutQuad} easing function.
384
385 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 7
386
387 We now create the animations that control the flip-effect when you press
388 the enter key. The main goal is to rotate the pad by 180 degrees or back,
389 but we also need to make sure the selection item's tilt rotations are reset
390 back to 0 when the pad is flipped, and restored back to their original
391 values when flipped back:
392
393 \list
394 \o \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
395 \o \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
396 \o \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
397 \o \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
398 \o \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
399 \endlist
400
401 All animations are given a 500 millisecond duration and an
402 \l{QEasingCurve::InOutQuad}{InOutQuad} easing function.
403
404 It's worth taking a close look at \c smoothFlipScale. This animation's
405 start and end values are both 1.0, but at animation step 0.5 the
406 animation's value is 0.7. This means that after 50% of the animation's
407 duration, or 250 milliseconds, the pad will be scaled down to 0.7x of its
408 original size, which gives a great visual effect while flipping.
409
410 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 8
411
412 This section uses a trick to ensure that certain properties are assigned
413 precisely when the flip animation passes 50%, or 90 degrees, rotation. In
414 short, the pad's icons and selection item are all hidden, the pad's \c fill
415 property is enabled, and \c backItem is shown when flipping over. When
416 flipping back, the reverse properties are applied.
417
418 The way this is achieved is by running a sequential animation in parallel
419 to the other animations. This sequence, dubbed \c setVariablesSequence,
420 starts with a 250 millisecond pause, and then executes several animations
421 with a duration of 0. Each animation will ensure that properties are set
422 immediate at this point.
423
424 This approach can also be used to call functions or set any other
425 properties at a specific time while an animation is running.
426
427 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 9
428
429 We will now create the state machine. The whole \c PadNavigator state
430 machinery is controlled by one single state machine that has a
431 straight-forward state structure. The state engine itself is created
432 as a child of the \c PadNavigator itself. We then create three top level
433 states:
434
435 \list
436 \o \c splashState: The initial state where the splash item is visible.
437 \o \c frontState: The base state where the splash is gone and we can see
438 the front side of the pad, and navigate the selection item.
439 \o \c backState: The flipped state where the \c backItem is visible, and we
440 can interact with the QGraphicsProxyWidget-embedded form.
441 \endlist
442
443 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 10
444
445 Each state assigns specific properties to objects on entry. Most
446 interesting perhaps is the assignment of the value 0.0 to the pad's \c
447 flipRotation angle property when in \c frontState, and 180.0 when in \c
448 backState. At the end of this section we register default animations with
449 the state engine; these animations will apply to their respective objects
450 and properties for any state transition. Otherwise it's common to assign
451 animations to specific transitions.
452
453 The \c splashState state is set as the initial state. This is required
454 before we start the state engine. We proceed with creating some
455 transitions.
456
457 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 11
458
459 QEventTransition defines a very flexible transition type. You can use this
460 class to trigger a transition based on an object receiving an event of a
461 specific type. In this case, we would like to transition from \c
462 splashState into \c frontState if \c PadNavigator receives any key press
463 event (QEvent::KeyPress).
464
465 We register the \c splashItem's animations to this transition to ensure they
466 are used to animate the item's movement and opacity.
467
468 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 12
469
470 We use QKeyEventTransition to capture specific key events. In this case, we
471 detect that the user presses Qt::Key_Return or Qt::Key_Enter, and use this
472 to trigger transitions between \c frontState and backState. We register \c
473 flipAnimation, our complex parallel animation group, with these
474 transitions.
475
476 We continue by defining the states for each of the icons in the grid.
477
478 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 13
479
480 We will use state groups to control transitions between icons. Each icon
481 represents a \e substate of \c frontState. We will then define transitions
482 between the states by detecting key presses, using QKeyEventTransition.
483
484 We start by creating all the substates, and at the same time we create a
485 temporary grid structure for the states to make it easier to find which
486 states represents icons that are up, down, left and to the right each
487 other.
488
489 Once the first substate is known, we set this up as the initial substate of
490 \c frontState. We will use the (0, 0), or top-left, icon for the initial
491 substate. We initialze the selection item's position to be exactly where
492 the top-left icon is.
493
494 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 14
495
496 We can now create four transitions for each icon. Each transition ensures
497 that we move to the state corresponding to which arrow key has been
498 pressed. It's clear from this techinique that we could design any other
499 specific transitions to and from each of the sub states depending on these
500 and other keys.
501
502 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 15
503
504 Also, for each of the icons, we assign suitable values to the \c xRotation
505 and \c yRotation objects' "angle"-properties. If you recall, these
506 properties "tilt" the pad corresponding to which item is currently
507 selected. We ensure each icon is invisible when the pad is flipped, and
508 visible when the pad is not flipped. To ensure the visible property is
509 assigned at the right time, we add property-controlling animations to the
510 \c setVariableSequence animation defined earlier.
511
512 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 16
513
514 We are now finished with all states, transitions, and animations. We now
515 create the scene that will contain all our items. The scene gets a defined
516 background pixmap, and we disable item indexing (as most items in this
517 scene are animated). We add our \c pad item to the scene, and use its
518 bounding rectangle to fixate the scene rectangle. This rectangle is used by
519 the view to find a suitable size for the application window.
520
521 Then the scene is assigned to the view, or in our case, \c PadNavigator
522 itself.
523
524 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 17
525
526 Now that the scene has received its final size, we can position the splash
527 item at the very top, find its fade-out position, and add it to the scene.
528
529 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 18
530
531 The view toggles a few necessary properties:
532
533 \list
534 \o It disables its scroll bars - this application has no use for scroll bars.
535 \o It assigns a minimum size. This is necessary to avoid numerical errors
536 in our fit-in-view \c resizeEvent() implementation.
537 \o It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
538 ensure QGraphicsView doesn't spend time figuring out precisely what needs
539 to be redrawn. This application is very simple - if anything changes,
540 everything is updated.
541 \o It enables background caching - this makes no performance difference
542 with OpenGL, but without OpenGL it avoids unnecessary re-scaling of the
543 background pixmap.
544 \o It sets render hints that increase rendering quality.
545 \o If OpenGL is supported, a QGLWidget viewport is assigned to the view.
546 \endlist
547
548 Finally, we start the state engine.
549
550 \snippet examples/graphicsview/padnavigator/padnavigator.cpp 19
551
552 The \l{QGraphicsView::resizeEvent()}{resizeEvent()} implementation calls
553 the base implementation, and then calls QGraphicsView::fitInView() to scale
554 the scene so that it fits perfectly inside the view.
555
556 By resizing the main application window, you can see this effect yourself.
557 The scene contents grow when you make the window larger, and shrink when
558 you make it smaller, while keeping the aspect ratio intact.
559
560 \section1 The main() Function
561
562 \snippet examples/graphicsview/padnavigator/main.cpp 0
563
564 The \c main function creates the QApplication instance, uses
565 Q_INIT_RESOURCE to ensure our compiled-in resources aren't removed by the
566 linker, and then creates a 3x3 \c PadNavigator instance and shows it.
567
568 Our flippable pad shows up with a suitable splash item once control returns
569 to the event loop.
570
571 \section1 Performance Notes
572
573 The example uses OpenGL if this is available, to achieve optimal
574 performance; otherwise perspective tranformations can be quite costly.
575
576 Although this example does use QGraphicsProxyWidget to demonstrate
577 integration of Qt widget components integrated into Graphics View, using
578 QGraphicsProxyWidget comes with a performance penalty, and is therefore not
579 recommended for embedded development.
580
581 This example uses extensive item caching to avoid rerendering of static
582 elements, at the expense of graphics memory.
583*/
Note: See TracBrowser for help on using the repository browser.