fc924ae47e
Widget examples were moved into a widgets subfolder, but qdoc references were not updated. Change-Id: Id2a4573e723745b9827c664c852807d6116f8f6d Reviewed-by: Casper van Donderen <casper.vandonderen@nokia.com>
584 lines
27 KiB
Plaintext
584 lines
27 KiB
Plaintext
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
|
** Contact: http://www.qt-project.org/
|
|
**
|
|
** This file is part of the documentation of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:FDL$
|
|
** GNU Free Documentation License
|
|
** Alternatively, this file may be used under the terms of the GNU Free
|
|
** Documentation License version 1.3 as published by the Free Software
|
|
** Foundation and appearing in the file included in the packaging of
|
|
** this file.
|
|
**
|
|
** Other Usage
|
|
** Alternatively, this file may be used in accordance with the terms
|
|
** and conditions contained in a signed written agreement between you
|
|
** and Nokia.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
/*!
|
|
\example widgets/graphicsview/padnavigator
|
|
\title Pad Navigator Example
|
|
|
|
The Pad Navigator Example shows how you can use Graphics View together with
|
|
embedded widgets and Qt's \l{State Machine Framework} to create a simple
|
|
but useful, dynamic, animated user interface.
|
|
|
|
\image padnavigator-example.png
|
|
|
|
The interface consists of a flippable, rotating pad with icons that can be
|
|
selected using the arrow keys on your keyboard or keypad. Pressing enter
|
|
will flip the pad around and reveal its back side, which has a form
|
|
embedded into a QGraphicsProxyWidget. You can interact with the form, and
|
|
press the enter key to flip back to the front side of the pad at any time.
|
|
|
|
Graphics View provides the QGraphicsScene class for managing and
|
|
interacting with a large number of custom-made 2D graphical items derived
|
|
from the QGraphicsItem class, and a QGraphicsView widget for visualizing
|
|
the items, with support for zooming and rotation.
|
|
|
|
This example consists of a \c RoundRectItem class, a \c FlippablePad class,
|
|
a \c PadNavigator class, a \c SplashItem class, and a \c main() function.
|
|
|
|
\section1 RoundRectItem Class Definition
|
|
|
|
The \c RoundRectItem class is used by itself to display the icons on the
|
|
pad, and as a base class for \c FlippablePad, the class for the pad itself.
|
|
The role of the class is to paint a round rectangle of a specified size and
|
|
gradient color, and optionally to paint a pixmap icon on top. To support \c
|
|
FlippablePad it also allows filling its contents with a plain window
|
|
background color.
|
|
|
|
Let's start by reviewing the \c RoundRectItem class declaration.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.h 0
|
|
|
|
\c RoundRectItem inherits QGraphicsObject, which makes it easy to control
|
|
its properties using QPropertyAnimation. Its constructor takes a rectangle
|
|
to determine its bounds, and a color.
|
|
|
|
Besides implementing the mandatory \l{QGraphicsItem::paint()}{paint()} and
|
|
\l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions,
|
|
it also provides the \c pixmap and \c fill properties.
|
|
|
|
The \c pixmap property sets an optional pixmap that is drawn on top of the
|
|
round rectangle. The \c fill property will, when true, fill the round
|
|
rectangle contents with a fixed QPalette::Window background color.
|
|
Otherwise the contents are filled using a gradient based on the color
|
|
passed to \c RoundRectItem's constructor.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.h 1
|
|
|
|
The private data members are:
|
|
|
|
\list
|
|
\li \c pix: The optional pixmap that is drawn on top of the rectangle.
|
|
\li \c fillRect: Corresponds to the \c fill property.
|
|
\li \c color: The configurable gradient color fill of the rectangle.
|
|
\li \c bounds: The bounds of the rectangle.
|
|
\li \c gradient: A precalculated gradient used to fill the rectangle.
|
|
\endlist
|
|
|
|
We will now review the \c RoundRectItem implementation. Let's start by
|
|
looking at its constructor:
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 0
|
|
|
|
The constructor initializes its member variables and forwards the \c parent
|
|
argument to QGraphicsObject's constructor. It then constructs the linear
|
|
gradient that is used in \l{QGraphicsItem::paint()}{paint()} to draw the
|
|
round rectangle's gradient background. The linear gradient's starting point
|
|
is at the top-left corner of the bounds, and the end is at the bottom-left
|
|
corner. The start color is identical to the color passed as an argument,
|
|
and a slightly darker color is chosen for the final stop.
|
|
|
|
We store this gradient as a member variable to avoid having to recreate the
|
|
gradient every time the item is repainted.
|
|
|
|
Finally we set the cache mode
|
|
\l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}. This mode
|
|
causes the item's rendering to be cached into an off-screen pixmap that
|
|
remains persistent as we move and transform the item. This mode is ideal
|
|
for this example, and works particularly well with OpenGL and OpenGL ES.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 1
|
|
|
|
The \c pixmap property implementation simple returns the member pixmap, or
|
|
sets it and then calls \l{QGraphicsItem::update()}{update()}.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 2
|
|
|
|
As the \l{QGraphicsItem::paint()}{paint()} implementation below draws a
|
|
simple drop shadow down and to the right of the item, we return a slightly
|
|
adjusted rectangle from \l{QGraphicsItem::boundingRect()}{boundingRect()}.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 3
|
|
|
|
The \l{QGraphicsItem::paint()}{paint()} implementation starts by rendering
|
|
a semi transparent black round rectangle drop shadow, two units down and to
|
|
the right of the main item.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 4
|
|
|
|
We then draw the "foreground" round rectangle itself. The fill depends on
|
|
the \c fill property; if true, we will with a plain QPalette::Window color.
|
|
We get the current brush from QApplication::palette(). We assign a single
|
|
unit wide pen for the stroke, assign the brush, and then draw the
|
|
rectangle.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 5
|
|
|
|
If a pixmap has been assigned to the \e pixmap property, we draw this
|
|
pixmap in the center of the rectangle item. The pixmaps are scaled to match
|
|
the size of the icons; in arguably a better approach would have been to
|
|
store the icons with the right size in the first places.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/roundrectitem.cpp 6
|
|
|
|
Finally, for completeness we include the \c fill property implementation.
|
|
It returns the \c fill member variable's value, and when assigned to, it
|
|
calls \l{QGraphicsItem::update()}{update()}.
|
|
|
|
As mentioned already, \c RoundRectItem is the base class for \c
|
|
FlippablePad, which is the class representing the tilting pad itself. We
|
|
will proceed to reviewing \c FlippablePad.
|
|
|
|
\section1 FlippablePad Class Definition
|
|
|
|
\c FlippablePad is, in addition to its inherited \c RoundRectItem
|
|
responsibilities, responsible for creating and managing a grid of icons.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.h 0
|
|
|
|
Its declaration is very simple: It inherits \c RoundRectItem and does not
|
|
need any special polymorphic behavior. It's suitable to declare its own
|
|
constructor, and a getter-function that allows \c PadNavigator to access
|
|
the icons in the grid by (row, column).
|
|
|
|
The example has no "real" behavior or logic of any kind, and because of
|
|
that, the icons do not need to provide any \e behavior or special
|
|
interactions management. In a real application, however, it would be
|
|
natural for the \c FlippablePad and its icons to handle more of the
|
|
navigation logic. In this example, we have chosen to leave this to
|
|
the \c PadNavigator class, which we will get back to below.
|
|
|
|
We will now review the \c FlippablePad implementation. This implementation
|
|
starts with two helper functions: \c boundsFromSize() and \c
|
|
posForLocation():
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.cpp 0
|
|
|
|
\c boundsForSize() takes a QSize argument, and returns the bounding
|
|
rectangle of the flippable pad item. The QSize determines how many rows and
|
|
columns the icon grid should have. Each icon is given 150x150 units of
|
|
space, and this determines the bounds.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.cpp 1
|
|
|
|
\c posForLocation() returns the position of an icon given its row and
|
|
column position. Like \c boundsForSize(), the function assumes each icon is
|
|
given 150x150 units of space, and that all icons are centered around the
|
|
flippable pad item's origin (0, 0).
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.cpp 2
|
|
|
|
The \c FlippablePad constructor passes suitable bounds (using \c
|
|
boundsForSize()) and specific color to \c RoundRectItem's constructor.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.cpp 3
|
|
|
|
It then loads pixmaps from compiled-in resources to use for its icons.
|
|
QDirIterator is very useful in this context, as it allows us to fetch all
|
|
resource "*.png" files inside the \c :/images directory without explicitly
|
|
naming the files.
|
|
|
|
We also make sure not to load more pixmaps than we need.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.cpp 4
|
|
|
|
Now that we have the pixmaps, we can create icons, position then and assign
|
|
pixmaps. We start by finding a suitable size and color for the icons, and
|
|
initializing a convenient grid structure for storing the icons. This \c
|
|
iconGrid is also used later to find the icon for a specific (column, row)
|
|
location.
|
|
|
|
For each row and column in our grid, we proceed to constructing each icon
|
|
as an instance of \c RoundRectItem. The item is placed by using the \c
|
|
posForLocation() helper function. To make room for the slip-behind
|
|
selection item, we give each icon a \l{QGraphicsItem::zValue()}{Z-value} of
|
|
1. The pixmaps are distributed to the icons in round-robin fasion.
|
|
|
|
Again, this approach is only suitable for example purposes. In a real-life
|
|
application where each icon represents a specific action, it would be more
|
|
natural to assign the pixmaps directly, or that the icons themselves
|
|
provide suitable pixmaps.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/flippablepad.cpp 5
|
|
|
|
Finally, the \c iconAt() function returns a pointer to the icon at a
|
|
specific row and column. It makes a somewhat bold assumption that the input
|
|
is valid, which is fair because the \c PadNavigator class only calls this
|
|
function with correct input.
|
|
|
|
We will now review the \c SplashItem class.
|
|
|
|
\section1 SplashItem Class Definition
|
|
|
|
The \c SplashItem class represents the "splash window", a semitransparent
|
|
white overlay with text that appears immediately after the application has
|
|
started, and disappears after pressing any key. The animation is controlled
|
|
by \c PadNavigator; this class is very simple by itself.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/splashitem.h 0
|
|
|
|
The class declaration shows that \c SplashItem inherits QGraphicsObject to
|
|
allow it to be controlled by QPropertyAnimation. It reimplements the
|
|
mandatory \l{QGraphicsItem::paint()}{paint()} and
|
|
\l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions,
|
|
and keeps a \c text member variable which will contain the information text
|
|
displayed on this splash item.
|
|
|
|
Let's look at its implementation.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/splashitem.cpp 0
|
|
|
|
The constructor forwards to QGraphicsObject as expected, assigns a text
|
|
message to the \c text member variable, and enables
|
|
\l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache}. This cache
|
|
mode is suitable because the splash item only moves and is never
|
|
transformed, and because it contains text, it's important that it has a
|
|
pixel perfect visual appearance (in constrast to
|
|
\l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}, where the
|
|
visual appearance is not as good).
|
|
|
|
We use caching to avoid having to relayout and rerender the text for each
|
|
frame. An alterative approach would be to use the new QStaticText class.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/splashitem.cpp 1
|
|
|
|
\c SplashItem's bounding rectangle is fixed at (400x175).
|
|
|
|
\snippet widgets/graphicsview/padnavigator/splashitem.cpp 2
|
|
|
|
The \l{QGraphicsItem::paint()}{paint()} implementation draws a clipped
|
|
round rectangle with a thick 2-unit border and a semi-transparent white
|
|
background. It proceeds to finding a suitable text area by adjusting the
|
|
splash item's bounding rectangle with 10 units in each side. The text is
|
|
rendered inside this rectangle, with top-left alignment, and with word
|
|
wrapping enabled.
|
|
|
|
The main class now remains. We will proceed to reviewing \c PadNavigator.
|
|
|
|
\section1 PadNavigator Class Definition
|
|
|
|
\c PadNavigator represents the main window of our Pad Navigator Example
|
|
application. It creates and controls a somewhat complex state machine, and
|
|
several animations. Its class declaration is very simple:
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.h 0
|
|
|
|
It inherits QGraphicsView and reimplements only one function:
|
|
\l{QGraphicsView::resizeEvent()}{resizeEvent()}, to ensure the scene is
|
|
scaled to fit inside the view when resizing the main window.
|
|
|
|
The \c PadNavigator constructor takes a QSize argument that determines the
|
|
number or rows and columns in the grid.
|
|
|
|
It also keeps a private member instance, \c form, which is the generated
|
|
code for the pad's back side item's QGraphicsProxyWidget-embedded form.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 0
|
|
|
|
\c PadNavigator's constructor is a bit long. In short, its job is to create
|
|
all items, including the \c FlippablePad, the \c SplashItem and the
|
|
QGraphicsProxyWidget \c backItem, and then to set up all animations, states
|
|
and transitions that control the behavior of the application.
|
|
|
|
It starts out simple, by forwarding to QGraphicsView's constructor.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 1
|
|
|
|
The first item to be created is \c SplashItem. This is going to be a top-level
|
|
item in the scene, next to \c FlippablePad, and stacked on top of it, so we
|
|
assign it a \l{QGraphicsItem::zValue()}{Z-value} of 1.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 2
|
|
|
|
Now we construct the \c FlippablePad item, passing its column-row count to
|
|
its constructor.
|
|
|
|
The pad is controlled by three transformations, and we create one
|
|
QGraphicsRotation object for each of these.
|
|
|
|
\list
|
|
\li \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
|
|
animated from 0 to 180, and eventually back, when enter is pressed on the
|
|
keyboard, flipping the pad around.
|
|
\li \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
|
|
tilt the pad vertically corresponding to which item is currently selected.
|
|
This way, the selected item is always kept in front.
|
|
\li \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
|
|
tilt the pad horizontally corresponding to which item is selected. This
|
|
way, the selected item is always kept in front.
|
|
\endlist
|
|
|
|
The combination of all three rotations is assigned via
|
|
QGraphicsItem::setTransformations().
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 3
|
|
|
|
Now we construct the QGraphicsProxyWidget-embedded \c backItem. The proxy
|
|
widget is created as a child of the pad. We create a new QWidget and
|
|
populate it with the \c form member. To ensure the \c hostName line edit is
|
|
the first to receive input focus when this item is shown, we call
|
|
\l{QWidget::setFocus()}{setFocus()} immediately. This will not give the
|
|
widget focus right away; it will only prepare the item to automatically
|
|
receive focus once it is shown.
|
|
|
|
The QWidget based form is embedded into the proxy widget. The proxy is
|
|
hidden initially; we only want to show it when the pad is rotated at least
|
|
90 degrees, and we also rotate the proxy itself by 180 degrees. This way we
|
|
give the impression that the proxy widget is "behind" the flipped pad, when
|
|
in fact, it's actually \e{on top of it}.
|
|
|
|
We enable \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache} to
|
|
ensure the flip animation can run smoothly.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 4
|
|
|
|
We now create the selection item. This is simply another instance of \c
|
|
RoundRectItem that is slightly larger than the icons on the pad. We create
|
|
it as an immediate child of the \c FlippablePad, so the selection item is a
|
|
sibling to all the icons. By giving it a
|
|
\l{QGraphicsItem::zValue()}{Z-value} of 0.5 we ensure it will slide between
|
|
the pad and its icons.
|
|
|
|
What follows now is a series of animation initializations.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 5
|
|
|
|
We begin with the animations that apply to the splash item. The first
|
|
animation, \c smoothSplashMove, ensures that the "y" property of \c splash
|
|
will be animated with a 250-millisecond duration
|
|
\l{QEasingCurve::InQuad}{InQuad} easing function. \c smoothSplashOpacity
|
|
ensures the opacity of \c splash eases in and out in 250 milliseconds.
|
|
|
|
The values are assigned by \c PadNavigator's state machine, which is
|
|
created later.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 6
|
|
|
|
These are the animations that control the selection item's movement and the
|
|
\c xRotation and \c yRotation QGraphicsRotation objects that tilt the pad.
|
|
All animations have a duration of 125 milliseconds, and they all use the
|
|
\l{QEasingCurve::InOutQuad}{InOutQuad} easing function.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 7
|
|
|
|
We now create the animations that control the flip-effect when you press
|
|
the enter key. The main goal is to rotate the pad by 180 degrees or back,
|
|
but we also need to make sure the selection item's tilt rotations are reset
|
|
back to 0 when the pad is flipped, and restored back to their original
|
|
values when flipped back:
|
|
|
|
\list
|
|
\li \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
|
|
\li \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
|
|
\li \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
|
|
\li \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
|
|
\li \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
|
|
\endlist
|
|
|
|
All animations are given a 500 millisecond duration and an
|
|
\l{QEasingCurve::InOutQuad}{InOutQuad} easing function.
|
|
|
|
It's worth taking a close look at \c smoothFlipScale. This animation's
|
|
start and end values are both 1.0, but at animation step 0.5 the
|
|
animation's value is 0.7. This means that after 50% of the animation's
|
|
duration, or 250 milliseconds, the pad will be scaled down to 0.7x of its
|
|
original size, which gives a great visual effect while flipping.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 8
|
|
|
|
This section uses a trick to ensure that certain properties are assigned
|
|
precisely when the flip animation passes 50%, or 90 degrees, rotation. In
|
|
short, the pad's icons and selection item are all hidden, the pad's \c fill
|
|
property is enabled, and \c backItem is shown when flipping over. When
|
|
flipping back, the reverse properties are applied.
|
|
|
|
The way this is achieved is by running a sequential animation in parallel
|
|
to the other animations. This sequence, dubbed \c setVariablesSequence,
|
|
starts with a 250 millisecond pause, and then executes several animations
|
|
with a duration of 0. Each animation will ensure that properties are set
|
|
immediate at this point.
|
|
|
|
This approach can also be used to call functions or set any other
|
|
properties at a specific time while an animation is running.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 9
|
|
|
|
We will now create the state machine. The whole \c PadNavigator state
|
|
machinery is controlled by one single state machine that has a
|
|
straight-forward state structure. The state engine itself is created
|
|
as a child of the \c PadNavigator itself. We then create three top level
|
|
states:
|
|
|
|
\list
|
|
\li \c splashState: The initial state where the splash item is visible.
|
|
\li \c frontState: The base state where the splash is gone and we can see
|
|
the front side of the pad, and navigate the selection item.
|
|
\li \c backState: The flipped state where the \c backItem is visible, and we
|
|
can interact with the QGraphicsProxyWidget-embedded form.
|
|
\endlist
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 10
|
|
|
|
Each state assigns specific properties to objects on entry. Most
|
|
interesting perhaps is the assignment of the value 0.0 to the pad's \c
|
|
flipRotation angle property when in \c frontState, and 180.0 when in \c
|
|
backState. At the end of this section we register default animations with
|
|
the state engine; these animations will apply to their respective objects
|
|
and properties for any state transition. Otherwise it's common to assign
|
|
animations to specific transitions.
|
|
|
|
The \c splashState state is set as the initial state. This is required
|
|
before we start the state engine. We proceed with creating some
|
|
transitions.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 11
|
|
|
|
QEventTransition defines a very flexible transition type. You can use this
|
|
class to trigger a transition based on an object receiving an event of a
|
|
specific type. In this case, we would like to transition from \c
|
|
splashState into \c frontState if \c PadNavigator receives any key press
|
|
event (QEvent::KeyPress).
|
|
|
|
We register the \c splashItem's animations to this transition to ensure they
|
|
are used to animate the item's movement and opacity.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 12
|
|
|
|
We use QKeyEventTransition to capture specific key events. In this case, we
|
|
detect that the user presses Qt::Key_Return or Qt::Key_Enter, and use this
|
|
to trigger transitions between \c frontState and backState. We register \c
|
|
flipAnimation, our complex parallel animation group, with these
|
|
transitions.
|
|
|
|
We continue by defining the states for each of the icons in the grid.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 13
|
|
|
|
We will use state groups to control transitions between icons. Each icon
|
|
represents a \e substate of \c frontState. We will then define transitions
|
|
between the states by detecting key presses, using QKeyEventTransition.
|
|
|
|
We start by creating all the substates, and at the same time we create a
|
|
temporary grid structure for the states to make it easier to find which
|
|
states represents icons that are up, down, left and to the right each
|
|
other.
|
|
|
|
Once the first substate is known, we set this up as the initial substate of
|
|
\c frontState. We will use the (0, 0), or top-left, icon for the initial
|
|
substate. We initialze the selection item's position to be exactly where
|
|
the top-left icon is.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 14
|
|
|
|
We can now create four transitions for each icon. Each transition ensures
|
|
that we move to the state corresponding to which arrow key has been
|
|
pressed. It's clear from this techinique that we could design any other
|
|
specific transitions to and from each of the sub states depending on these
|
|
and other keys.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 15
|
|
|
|
Also, for each of the icons, we assign suitable values to the \c xRotation
|
|
and \c yRotation objects' "angle"-properties. If you recall, these
|
|
properties "tilt" the pad corresponding to which item is currently
|
|
selected. We ensure each icon is invisible when the pad is flipped, and
|
|
visible when the pad is not flipped. To ensure the visible property is
|
|
assigned at the right time, we add property-controlling animations to the
|
|
\c setVariableSequence animation defined earlier.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 16
|
|
|
|
We are now finished with all states, transitions, and animations. We now
|
|
create the scene that will contain all our items. The scene gets a defined
|
|
background pixmap, and we disable item indexing (as most items in this
|
|
scene are animated). We add our \c pad item to the scene, and use its
|
|
bounding rectangle to fixate the scene rectangle. This rectangle is used by
|
|
the view to find a suitable size for the application window.
|
|
|
|
Then the scene is assigned to the view, or in our case, \c PadNavigator
|
|
itself.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 17
|
|
|
|
Now that the scene has received its final size, we can position the splash
|
|
item at the very top, find its fade-out position, and add it to the scene.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 18
|
|
|
|
The view toggles a few necessary properties:
|
|
|
|
\list
|
|
\li It disables its scroll bars - this application has no use for scroll bars.
|
|
\li It assigns a minimum size. This is necessary to avoid numerical errors
|
|
in our fit-in-view \c resizeEvent() implementation.
|
|
\li It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
|
|
ensure QGraphicsView doesn't spend time figuring out precisely what needs
|
|
to be redrawn. This application is very simple - if anything changes,
|
|
everything is updated.
|
|
\li It enables background caching - this makes no performance difference
|
|
with OpenGL, but without OpenGL it avoids unnecessary re-scaling of the
|
|
background pixmap.
|
|
\li It sets render hints that increase rendering quality.
|
|
\li If OpenGL is supported, a QGLWidget viewport is assigned to the view.
|
|
\endlist
|
|
|
|
Finally, we start the state engine.
|
|
|
|
\snippet widgets/graphicsview/padnavigator/padnavigator.cpp 19
|
|
|
|
The \l{QGraphicsView::resizeEvent()}{resizeEvent()} implementation calls
|
|
the base implementation, and then calls QGraphicsView::fitInView() to scale
|
|
the scene so that it fits perfectly inside the view.
|
|
|
|
By resizing the main application window, you can see this effect yourself.
|
|
The scene contents grow when you make the window larger, and shrink when
|
|
you make it smaller, while keeping the aspect ratio intact.
|
|
|
|
\section1 The main() Function
|
|
|
|
\snippet widgets/graphicsview/padnavigator/main.cpp 0
|
|
|
|
The \c main function creates the QApplication instance, uses
|
|
Q_INIT_RESOURCE to ensure our compiled-in resources aren't removed by the
|
|
linker, and then creates a 3x3 \c PadNavigator instance and shows it.
|
|
|
|
Our flippable pad shows up with a suitable splash item once control returns
|
|
to the event loop.
|
|
|
|
\section1 Performance Notes
|
|
|
|
The example uses OpenGL if this is available, to achieve optimal
|
|
performance; otherwise perspective tranformations can be quite costly.
|
|
|
|
Although this example does use QGraphicsProxyWidget to demonstrate
|
|
integration of Qt widget components integrated into Graphics View, using
|
|
QGraphicsProxyWidget comes with a performance penalty, and is therefore not
|
|
recommended for embedded development.
|
|
|
|
This example uses extensive item caching to avoid rerendering of static
|
|
elements, at the expense of graphics memory.
|
|
*/
|