summaryrefslogtreecommitdiffstats
path: root/examples/widgets/doc/src/padnavigator.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/doc/src/padnavigator.qdoc')
-rw-r--r--examples/widgets/doc/src/padnavigator.qdoc586
1 files changed, 0 insertions, 586 deletions
diff --git a/examples/widgets/doc/src/padnavigator.qdoc b/examples/widgets/doc/src/padnavigator.qdoc
deleted file mode 100644
index 31440b650f..0000000000
--- a/examples/widgets/doc/src/padnavigator.qdoc
+++ /dev/null
@@ -1,586 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** 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. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \example graphicsview/padnavigator
- \title Pad Navigator Example
- \ingroup examples-graphicsview
- \brief Demonstrates how to create animated user interface.
-
- The Pad Navigator Example shows how you can use Graphics View together with
- embedded widgets and Qt's \l{The State Machine Framework}{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 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 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 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 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 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 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 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 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 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 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 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 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 graphicsview/padnavigator/flippablepad.cpp 2
-
- The \c FlippablePad constructor passes suitable bounds (using \c
- boundsForSize()) and specific color to \c RoundRectItem's constructor.
-
- \snippet 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 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 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 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 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 graphicsview/padnavigator/splashitem.cpp 1
-
- \c SplashItem's bounding rectangle is fixed at (400x175).
-
- \snippet 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 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 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 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 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 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 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 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 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 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.
-
- \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 flipAnimation: A parallel animation group that ensures 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 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 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 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.
-
- Specifically, we use default animations to control the selection item's
- movement and tilt rotations. The tilt rotations are set to 0 when the pad
- is flipped, and restored back to their original values when flipped back.
-
- 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 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 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 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 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 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 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 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 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 QOpenGLWidget viewport is assigned to the view.
- \endlist
-
- Finally, we start the state engine.
-
- \snippet 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 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.
-*/